
Jellyfin Server 12.2 - उच्च - रिमोट - IDOR - GET /Items/Suggestions omit-userId छिपी हुई लाइब्रेरी Path और IDs को डंप करता है
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · jellyfin-suggestions-idor
Jellyfin Server 12.2 - Jellyfin
वर्ग: IDOR. पहुँच: रिमोट (कोई भी प्रमाणित गैर-एडमिन)।
GET /Items/Suggestions केवल [Authorize] है। जब userId छोड़ा जाता है, तो SuggestionsController.GetSuggestions user = null सेट करता है और कभी RequestHelpers.GetUserId को कॉल नहीं करता। InternalItemsQuery(null) SetUser नहीं करता। LibraryManager.GetItemsResult AddUserToQuery को छोड़ देता है। new DtoOptions() में ItemFields.Path शामिल है। GetBaseItemDtos(..., user: null) IsVisible को छोड़ देता है।
GHSA-9x85 ने GetUserId सिखाया (छोड़ने पर claims पर जाता है; विदेशी GUID 403 है)। ItemsController.GetItems हमेशा इसका उपयोग करता है। Suggestions ने नहीं किया। लेगेसी GET /Users/{userId}/Suggestions में हमेशा एक रूट GUID होता है, इसलिए वह सहोदर GetUserId से होकर गुजरता है।
एक प्रतिबंधित खाता उन लाइब्रेरी के लिए शीर्षक, ID, अवलोकन, प्रदाता ID, और फ़ाइलसिस्टम Path डंप करता है जिन्हें उसे सौंपा नहीं गया है। वे GUIDs अनप्रमाणित GET /Videos/{id}/stream पर चलते हैं।
| ID | अभी तक कोई CVE नहीं |
| CWE | CWE-639 / CWE-862 |
| CVSS | उच्च: 6.5 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N |
| उत्पाद | Jellyfin Server |
| प्रभावित | v12.2 (ca0f16eb7c195f720a1493ed469a27c4657db0c6), इमेज jellyfin/jellyfin:12.2 |
| प्रमाणीकरण | प्रमाणित (कोई भी गैर-एडमिन, जिसमें चाइल्ड / छिपी-लाइब्रेरी खाता शामिल है) |
| लाइसेंस | GNU Affero GPL v3.0 |
| लैब | केवल 127.0.0.1:18790 |
Jellyfin 12.2 leftovers का शेष #1। वही पिन, अन्य पैक: jellyfin-svg-gzip (GHSA-cf3c शेष gzip data:image/png), jellyfin-playlist-itemids (GHSA-9x85 शेष ItemIds + अनप्रमाणित स्ट्रीम), jellyfin-ffmpeg-colonslash (GHSA-wwwm शेष .strm URL उद्धरण)। यह पैक वही है जो छिपी लाइब्रेरी को डंप करता है।
कोई भी प्रमाणित गैर-एडमिन, जिसमें चाइल्ड / छिपी-लाइब्रेरी / MaxParentalRating खाता शामिल है। एक सामान्य उपयोगकर्ता टोकन की आवश्यकता है। कोई एडमिन नहीं, कोई API कुंजी नहीं। वे पासवर्ड नहीं बदलते। वे एडमिन नहीं बनाते। वे उन लाइब्रेरी की सूची बनाते हैं जिन्हें उन्हें सौंपा नहीं गया था, जिसमें फ़ाइलसिस्टम Path शामिल है, फिर उन GUIDs को चलाते हैं।
विशेषाधिकार तालिका (विस्तृत)। Signal-Server Dropwizard admin के समान मानक: विधि + पथ, वह कॉल क्या प्रदान करती है, रेकॉन बनाम अखंडता बनाम उपलब्धता, लैब-प्रमाणित बनाम अनुमानित, आसन्न सतह जो बंद रहती है।
| अक्ष | विधि + पथ | अनुदान | उद्गम |
|---|---|---|---|
| रेकॉन | GET /Items/Suggestions बिना userId के (वैकल्पिक limit / mediaType / type) | अनस्कोप्ड पुनरावर्ती आइटम सूची: Name, Id, Overview, प्रदाता ID, फ़ाइलसिस्टम Path, उन लाइब्रेरी का इमेज मेटाडेटा जो कॉलर को सौंपी नहीं गई हैं, जिनमें केवल एक छिपे हुए उपयोगकर्ता को दिए गए फ़ोल्डर भी शामिल हैं। फ़ोल्डर ACL, पैरेंटल रेटिंग, और अनुमत-टैग लागू नहीं होते। | लैब-प्रमाणित। प्रतिबंधित labuser (EnableAllFolders=false, केवल EnabledFolders=PublicB): GET /Items witness=0; Suggestions witness=1 |
| रेकॉन | वही, limit छोड़कर | InternalItemsQuery.Limit अनसेट रहता है; रिपॉज़िटरी पूरा मिलान सेट लौटाती है (संपूर्ण आइटम तालिका, यादृच्छिक क्रम) | स्रोत (SuggestionsController.cs:70-95) |
| रेकॉन | अनॉथ GET /Videos/{itemId}/stream उस सूची से एक GUID के साथ | उस फ़ाइल के बाइट्स jellyfin UID के रूप में | स्रोत (VideosController में क्लास [Authorize] नहीं है; StreamingHelpers GetItemById बिना उपयोगकर्ता के)। स्ट्रीम सहोदर लेफ़्टओवर jellyfin-playlist-itemids में लैब किया गया, इस पैक में नहीं |
| अखंडता | Suggestions पर कोई नहीं | कोई पासवर्ड, नीति, पसंदीदा, या सत्र लेखन नहीं | बंद |
| उपलब्धता | Suggestions पर कोई नहीं | सामान्य क्वेरी लागत से अधिक कोई DoS नहीं | बंद |
इस पिन पर बंद रहता है
| अक्ष | विधि + पथ | यह क्यों बंद है |
|---|---|---|
| रेकॉन | GET /Items?userId= और GET /Items?parentId=<hiddenFolder> | हमेशा GetUserId + IsVisible (ItemsController.cs:265, 342-350) |
| रेकॉन | GET /Playlists/{id}/Items?userId= | GetUserId (PlaylistsController.cs:524)। GHSA-9x85 श्रेणी, पैच किया गया |
| रेकॉन | GET /Items/Suggestions?userId=<other> | विदेशी GUID फिर भी GetUserId पर जाता है और गैर-एडमिन के लिए 403 देता है। लैब-प्रमाणित (impersonate-403=yes) |
| रेकॉन | लीगेसी GET /Users/{userId}/Suggestions | रूट GUID आवश्यक है, इसलिए यह वास्तव में GetUserId कॉल करता है |
| अखंडता | POST /Users/Password?userId= | AssertCanUpdateUser |
| अखंडता | POST /Users/{id}/Policy | RequiresElevation |
| अखंडता | डिवाइस, सत्र, AddAdditionalUser | केवल एलिवेशन या स्वयं का सत्र |
| रेकॉन | GET /Users / GET /Users/{id} | UserDto + नीति (फ़ोल्डर GUID, एडमिन बिट), लाइब्रेरी सामग्री या हैश नहीं। घरेलू गणना, यह लेफ़्टओवर नहीं |
मैं प्लगइन-DLL RCE, रिवर्स शेल, या पासवर्ड चोरी का दावा नहीं कर रहा हूँ। डंप उन लाइब्रेरी का कैटलॉग (और Path) है जो कॉलर को सौंपी नहीं गई थीं। GUID-द्वारा-स्ट्रीम अनुवर्ती लंबे समय से चली आ रही Jellyfin HTML5/DLNA व्यवहार है; यह लेफ़्टओवर वह है जो ID की गणना करता है।
v12.2 ने 12.0 GHSA लहर को बंद कर दिया। मैं फिर भी उस टैग पर बैठा और RequestHelpers.GetUserId के बगल में हर userId क्वेरी पढ़ी। Items हमेशा इसका उपयोग करता है। Suggestions शाखाएँ: खाली userId -> user = null, कभी GetUserId नहीं। यही लेफ़्टओवर है।
run.sh दो मूवी लाइब्रेरी सीड करता है (PrivateA जिसका नाम witness के साथ है, PublicB), विज़ार्ड पूरा करता है, labuser बनाता है जिसमें EnableAllFolders=false और केवल EnabledFolders=PublicB है, फिर GET /Items की तुलना GET /Items/Suggestions से करता है।
पहले से दर्ज गलत मोड़: GET /Items को लीक मानना (यह स्कोप्ड है); Suggestions?userId=<admin> को लीक मानना (403); लीगेसी /Users/{userId}/Suggestions रूट को छेद मानना (इसमें GUID है इसलिए यह GetUserId कॉल करता है); अनॉथ स्ट्रीम को इस पैक का बग बताना (सहोदर लेफ़्टओवर); एक रिवर्स शेल। नाटक।
क्लाइंट बग उत्पाद बग जैसे दिखते हैं। एक हेल्पर जो http.client को छाया देता है, कभी पैकेट नहीं भेजता। HTTPResponse पर .recv() .read() नहीं है। मैं इसका उल्लेख एक बार करता हूँ क्योंकि इसने समय लिया और एक मिनट के लिए ऐसा लगा कि 12.2 ने काम पूरा कर लिया है।
python3 jellyfin-suggestions-idor-Abraxas-Labs.py
या
cd lab
./run.sh
केवल http://127.0.0.1:18790 को लक्षित करें। इमेज jellyfin/jellyfin:12.2। Docker आवश्यक है। लॉन्चर lab/ में chdir करता है और run.sh को exec करता है।
IOC user-items http=200 witness=0
IOC user-suggestions http=200 witness=1
IOC impersonate-suggestions http=403
SUCCESS jellyfin-suggestions-idor items-hidden=yes suggestions-has-witness=yes impersonate-403=yes JELLYFIN-SUGGESTIONS-IDOR-WITNESS