
प्लेन का V2 एसेट सबसिस्टम उपयुक्त सदस्यता जांच लागू किए बिना workspace slugs और asset UUIDs पर भरोसा करता था, जिससे एक प्रमाणित उपयोगकर्ता अन्य workspaces में एसेट्स को पढ़, कॉपी, हटा और ओवरराइट कर सकता था।
प्लेन के V2 एसेट सबसिस्टम ने सही सदस्यता जाँच लागू किए बिना विश्वसनीय वर्कस्पेस स्लग और एसेट UUID पर भरोसा किया, जिससे एक प्रमाणित उपयोगकर्ता दूसरे वर्कस्पेस में एसेट्स को पढ़, कॉपी, हटा और अधिलेखित कर सकता था।
मुझे यह समस्या प्लेन, ओपन-सोर्स प्रोजेक्ट मैनेजमेंट प्लेटफ़ॉर्म, की समीक्षा करते समय मिली, जिसमें एक बहुत ही विशिष्ट प्रश्न था:
क्या V2 एसेट एंडपॉइंट वास्तव में वर्कस्पेस सीमाएँ लागू करते हैं, या वे हमलावर द्वारा प्रदान किए गए वर्कस्पेस स्लग और एसेट आईडी पर बहुत अधिक भरोसा करते हैं?
इस मामले में, उत्तर नहीं था।
प्लेन के V2 एसेट सबसिस्टम ने दो संबंधित प्राधिकरण दोष उजागर किए जिन्होंने किसी भी प्रमाणित उपयोगकर्ता के लिए वर्कस्पेस अलगाव को तोड़ दिया:
इसने क्रॉस-वर्कस्पेस एसेट दुरुपयोग संभव बना दिया।
मेरे मान्य किए गए PoC में, वर्कस्पेस ब्रावो में एक सामान्य उपयोगकर्ता सक्षम था:
उस समस्या को बाद में CVE-2026-46558 निर्दिष्ट किया गया।
प्लेन: GitHub पर प्लेन
CVE: CVE-2026-46558
इसने प्लेन को प्रभावित किया, जो अपनी आधिकारिक साइट पर दुनिया भर में 50,000+ टीमों द्वारा उपयोग किए जाने के रूप में प्रस्तुत किया जाता है। प्लेन मजबूत ओपन-सोर्स अपनाने पर भी प्रकाश डालता है, जिसमें 46,000+ GitHub स्टार और 1,000,000+ Docker पुल शामिल हैं, और Tencent, , , और जैसे संगठनों को प्रदर्शित करता है।

वर्कस्पेस B में प्रमाणित हमलावर → वर्कस्पेस-स्तरीय V2 एसेट रूट उचित सदस्यता जाँच के बिना लक्ष्य वर्कस्पेस स्लग और एसेट UUID पर भरोसा करता है → वर्कस्पेस A एसेट्स के विरुद्ध प्रिसाइन्ड रीड/पैच/डिलीट + डुप्लिकेट-एसेट्स स्रोत लुकअप अपलोड किए गए स्रोत UUID पर भरोसा करता है → क्रॉस-वर्कस्पेस प्रकटीकरण, प्रतिलिपि, विलोपन, और ब्रांडिंग अधिलेखन
प्लेन एक ओपन-सोर्स प्रोजेक्ट मैनेजमेंट प्लेटफ़ॉर्म है जिसका उपयोग प्रबंधन के लिए किया जाता है:
इसका मतलब है कि इसका एसेट सबसिस्टम एक वास्तविक विश्वास सीमा पर बैठता है।
यहाँ महत्वपूर्ण प्रश्न यह नहीं था कि क्या प्लेन अपलोड का समर्थन करता है।
असली प्रश्न था:
क्या प्लेन वर्कस्पेस अलगाव लागू करता है जब एक प्रमाणित उपयोगकर्ता दूसरे वर्कस्पेस के स्वामित्व वाले एसेट्स को संदर्भित करता है?
इस मामले में, ऐसा नहीं हुआ।
बहु-किरायेदार अनुप्रयोग समीक्षाएँ अक्सर पहले स्पष्ट व्यवस्थापक एंडपॉइंट या प्रत्यक्ष सेटिंग्स अपडेट पर ध्यान केंद्रित करती हैं।
यह एक बहुत ही सामान्य और वास्तविक बग वर्ग को अनदेखा करता है:
साझा फ़ाइल या एसेट सबसिस्टम के माध्यम से द्वितीयक वस्तु पहुँच
एसेट सिस्टम गलत होना आसान है क्योंकि वे अक्सर संयोजित करते हैं:
यह ठीक वही जगह है जहाँ किरायेदार सीमाएँ चुपचाप कमजोर हो जाती हैं।
यह समस्या भंडारण भ्रष्टाचार के बारे में नहीं थी। यह S3 के बारे में ही नहीं थी। यह अपलोड MIME हैंडलिंग के बारे में नहीं थी।
यह एक प्राधिकरण सीमा विफलता थी:
यह एक वास्तविक कमजोरी पैदा करने के लिए पर्याप्त है।
मैंने प्लेन में बेतरतीब ढंग से यादृच्छिक एंडपॉइंट फ़ज़ करके या बिना किसी मॉडल के UUID का अनुमान लगाकर संपर्क नहीं किया।
सबसे मजबूत दृष्टिकोण पहले सबसे आशाजनक अलगाव सीमा की पहचान करना था।
प्लेन के लिए, वह था V2 एसेट सबसिस्टम।
क्यों?
क्योंकि एक साझा एसेट सिस्टम तब खतरनाक हो जाता है जब:
यह जाँच करने के लिए सही सीमा थी।
और यह ठीक वही जगह थी जहाँ बग रहता था।
यह वास्तव में एक ही सबसिस्टम में दो संबंधित प्राधिकरण विफलताएँ थीं।
वर्कस्पेस-स्तरीय एसेट रूट इसके माध्यम से उजागर हुए:
apps/api/plane/app/urls/asset.py:50-56कमजोर हैंडलर इसमें थे:
apps/api/plane/app/views/asset/v2.py:314apps/api/plane/app/views/asset/v2.py:379apps/api/plane/app/views/asset/v2.py:400apps/api/plane/app/views/asset/v2.py:409समस्या सरल थी।
WorkspaceFileAssetEndpoint ने एक वर्कस्पेस स्लग और एसेट UUID स्वीकार किया, फिर सीधे वस्तुओं को हल किया जैसे:
workspace = Workspace.objects.get(slug=slug)
और:
asset = FileAsset.objects.get(id=asset_id, workspace__slug=slug)
बिना पहले यह लागू किए कि कॉल करने वाला वास्तव में उस लक्ष्य वर्कस्पेस का एक अधिकृत सदस्य था।
इसका मतलब था कि एंडपॉइंट अभी भी कर सकता था:
दूसरे वर्कस्पेस की वस्तुओं के लिए।
डुप्लिकेट-एसेट्स रूट इसके माध्यम से मैप किया गया:
apps/api/plane/app/urls/asset.py:100-101कमजोर तर्क इसमें था:
apps/api/plane/app/views/asset/v2.py:736-780गंतव्य वर्कस्पेस में एक प्राधिकरण डेकोरेटर था। लेकिन स्रोत एसेट लुकअप में नहीं था।
स्रोत वस्तु को इसके साथ लोड किया गया:
original_asset = FileAsset.objects.filter(id=asset_id, is_uploaded=True).first()
इसका मतलब था कि कॉल करने वाले को केवल चाहिए था:
कोई जाँच नहीं थी कि कॉल करने वाला उस स्रोत वर्कस्पेस से संबंधित है जो वास्तव में उस एसेट का मालिक था।
यह पूरा दूसरा बग है।
महत्वपूर्ण अंतर क्रॉस-वर्कस्पेस प्रभाव है।
बहुत सारे प्राधिकरण बग को कम करके आंका जाता है:
"इसके लिए अभी भी लॉगिन आवश्यक है"
यह बिंदु से चूक जाता है।
असली सवाल यह नहीं है:
"क्या कॉल करने वाला प्रमाणित है?"
असली सवाल है:
"क्या कॉल करने वाला उस विशिष्ट वर्कस्पेस और विशिष्ट एसेट के लिए अधिकृत है जिस पर कार्रवाई की जा रही है?"
प्लेन में, वह उत्तर नहीं था।
यह वही है जो सामान्य वस्तु हैंडलिंग जैसा दिख सकता है, उसे एक वास्तविक बहु-किरायेदार सुरक्षा मुद्दे में बदल देता है।
इसके बीच एक स्पष्ट अंतर है:
यह मुद्दा दूसरे मामले में दृढ़ता से था।
मैंने स्थानीय रूप से प्लेन कम्युनिटी एडिशन 1.2.3 के विरुद्ध दो असंबंधित वर्कस्पेस में दो सामान्य उपयोगकर्ताओं का उपयोग करके समस्या को मान्य किया:
alpha-20260323072017 में Alphabravo-20260323072017 में Bravoमैंने Alpha का उपयोग एक प्रोजेक्ट इश्यू में एक वैध निजी अपलोड किया गया एसेट बनाने के लिए किया।
मेरे रन में मान्य निजी एसेट ID थी:
6ed6ed62-d1b2-4399-8220-336c01b7d72c
Bravo के रूप में, मैंने अनुरोध किया:
GET /api/assets/v2/workspaces/alpha-20260323072017/6ed6ed62-d1b2-4399-8220-336c01b7d72c/
प्लेन ने लौटाया:
HTTP/1.1 302 Found
Alpha के एसेट के लिए एक प्रिसाइन्ड डाउनलोड URL के साथ।
डाउनलोड की गई फ़ाइल हैश Alpha के मूल निजी एसेट से बिल्कुल मेल खाती है:
original: 0d4d070f550ba59ba6b30bee62343cf68ea221af7034f131f72f6409cf5a598e
unauthorized read: 0d4d070f550ba59ba6b30bee62343cf68ea221af7034f131f72f6409cf5a598e
इसने साबित किया कि रीड पथ वर्कस्पेस सीमाओं को सफलतापूर्वक पार कर गया।
Bravo के रूप में, मैंने फिर अनुरोध किया:
POST /api/assets/v2/workspaces/bravo-20260323072017/duplicate-assets/6ed6ed62-d1b2-4399-8220-336c01b7d72c/
प्लेन ने लौटाया:
HTTP/1.1 200 OK
और एक डुप्लिकेट हमलावर-पक्ष एसेट बनाया:
72d51497-ccc1-4546-ba14-28fae5d37dbb
डुप्लिकेट की गई फ़ाइल का SHA-256 Alpha के मूल एसेट से बिल्कुल मेल खाता है:
0d4d070f550ba59ba6b30bee62343cf68ea221af7034f131f72f6409cf5a598e
इसने साबित किया कि स्रोत एसेट UUID अकेले हमलावर-नियंत्रित वर्कस्पेस में क्रॉस-वर्कस्पेस सामग्री कॉपी करने के लिए पर्याप्त था।
Bravo के रूप में, मैंने फिर भेजा:
DELETE /api/assets/v2/workspaces/alpha-20260323072017/6ed6ed62-d1b2-4399-8220-336c01b7d72c/
प्लेन ने लौटाया:
HTTP/1.1 204 No Content
जब Alpha ने बाद में उस एसेट को प्राप्त किया, तो सर्वर ने लौटाया:
HTTP/1.1 404 Not Found
इसने साबित किया कि केवल प्रकटीकरण नहीं, बल्कि क्रॉस-वर्कस्पेस अखंडता प्रभाव है।
Bravo के रूप में, मैंने कमजोर वर्कस्पेस-स्तरीय एसेट रूट के माध्यम से Alpha के वर्कस्पेस के विरुद्ध एक WORKSPACE_LOGO एसेट बनाया, हमलावर-नियंत्रित सामग्री अपलोड की, और इसे अंतिम रूप दिया।
उसके बाद, Alpha के वर्कस्पेस मेटाडेटा ने हमलावर-नियंत्रित लोगो एसेट की ओर इशारा किया:
c1032f06-3cf5-4f7e-b139-e6976d8c567d
डाउनलोड किए गए अंतिम लोगो हैश ने हमलावर पेलोड से बिल्कुल मेल खाया:
expected: b9d1ef1de88d61bf55dd18055839bacacb832a752e17a7312547f641113d0e7b
observed: b9d1ef1de88d61bf55dd18055839bacacb832a752e17a7312547f641113d0e7b
इसने साबित किया कि सिर्फ एक छिपी हुई बैकएंड पहुँच मुद्दा नहीं, बल्कि एक दृश्य क्रॉस-वर्कस्पेस अधिलेखन पथ है।
उपरोक्त परिणामों में से कोई भी एक वास्तविक बग रिपोर्ट को सही ठहराने के लिए पहले से ही पर्याप्त होता।
लेकिन पूरी श्रृंखला को मान्य करना दो कारणों से मायने रखता था।
इसने दिखाया कि समस्या केवल पढ़ने-मात्र के जोखिम तक सीमित नहीं थी।
उसी कमजोर सीमा ने सक्षम किया:
यह प्रभाव को एक संकीर्ण "एक फ़ाइल प्राप्त कर सकता है" IDOR की तुलना में बहुत मजबूत बनाता है।
इसने दिखाया कि दो कोड पथ संबंधित थे लेकिन स्वतंत्र रूप से महत्वपूर्ण थे।
एक दोष ने सीधे वर्कस्पेस-स्तरीय एसेट संचालन को उजागर किया। दूसरे दोष ने अपलोड किए गए एसेट UUID को डुप्लिकेशन के माध्यम से पुन: प्रयोज्य एक्सफिल्ट्रेशन प्रिमिटिव में बदल दिया।
इसने समग्र सुरक्षा कहानी को खारिज करना बहुत कठिन बना दिया।
सबसे दृश्यमान अधिलेखन प्रभाव जिसे मैंने मान्य किया वह था:
WORKSPACE_LOGOयह जानबूझकर था क्योंकि इसे सत्यापित करना आसान है और यह स्पष्ट क्रॉस-किरायेदार अखंडता विफलता प्रदर्शित करता है।
लेकिन एंडपॉइंट वर्कस्पेस लोगो तक सीमित नहीं था।
कमजोर वर्कस्पेस-स्तरीय एसेट प्रवाह ने कई इकाई संदर्भों को भी स्वीकार किया, जिनमें शामिल हैं:
यह मायने रखता था क्योंकि इसने दिखाया कि बग संरचनात्मक था, किसी एक ब्रांडिंग फ़ील्ड से बंधा नहीं।
मैंने सीधे वर्कस्पेस-लोगो पथ को मान्य किया। व्यापक कोड पथ ने दृढ़ता से सुझाव दिया कि अतिरिक्त एसेट-समर्थित संदर्भ उसी प्राधिकरण गलती के संपर्क में थे।
इस मुद्दे को उचित रूप से उच्च के रूप में वर्गीकृत किया गया था।
सलाहकार वर्गीकरण था:
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L
यह वर्गीकरण समझ में आता है।
दावा यह नहीं है कि एक अप्रमाणित हमलावर शून्य से प्लेन से समझौता कर सकता है। दावा यह है कि कोई भी सामान्य प्रमाणित उपयोगकर्ता V2 एसेट सबसिस्टम में किरायेदार सीमाओं को पार कर सकता है और अन्य वर्कस्पेस के विरुद्ध उच्च-प्रभाव वाले एसेट संचालन कर सकता है।
यह एक वास्तविक और बचाव योग्य बहु-किरायेदार प्राधिकरण भेद्यता है।
कुछ लोग प्रमाणित क्रॉस-किरायेदार बग को कम आंकते हैं क्योंकि वे सुनते हैं:
"हमलावर को पहले से ही एक खाते की आवश्यकता थी"
यह एक गंभीर बचाव नहीं है।
बहु-वर्कस्पेस सॉफ़्टवेयर में, सामान्य प्रमाणित उपयोगकर्ताओं को अपने स्वयं के प्राधिकरण दायरे के अंदर समाहित माना जाता है।
यदि वर्कस्पेस ब्रावो में एक निम्न-विशेषाधिकार प्राप्त उपयोगकर्ता वर्कस्पेस Alpha में वस्तुओं को पढ़, कॉपी, हटा या अधिलेखित कर सकता है, तो वर्कस्पेस अलगाव टूट गया है।
यह ठीक वही सुरक्षा गुण है जिसे एप्लिकेशन को संरक्षित करना चाहिए।
विशेष रूप से एक प्रोजेक्ट-मैनेजमेंट प्लेटफ़ॉर्म में जो आंतरिक कार्य सामग्री और ब्रांडिंग एसेट्स संग्रहीत करता है, यह वास्तविक गोपनीयता और अखंडता प्रभाव वाला एक सार्थक मुद्दा है।
समस्या प्लेन v1.3.1 में ठीक की गई थी।
v1.3.1 के रिलीज़ नोट्स ने फिक्स को स्पष्ट रूप से वर्णित किया:
WorkspaceFileAssetEndpoint विधियों में @allow_permission जोड़ेंDuplicateAssetEndpoint स्रोत एसेट लुकअप को उन वर्कस्पेस तक सीमित करें जहाँ कॉल करने वाला एक सक्रिय सदस्य हैयह सही सुधार दिशा है क्योंकि यह दोनों विफल सुरक्षा गुणों को संबोधित करता है:
यह ठीक वही है जो इस बग को चाहिए था।
यहाँ एक अच्छा फिक्स UUID को बेहतर छिपाने के बारे में नहीं है। यह प्रिसाइन्ड URL पीढ़ी को बदलने के बारे में नहीं है।
यह सही नियम को बहाल करने के बारे में है:
वर्कस्पेस स्लग प्लस एसेट UUID वर्तमान उपयोगकर्ता के लिए प्राधिकरण के बिना कभी भी पर्याप्त नहीं होना चाहिए
यह वह हिस्सा है जो पैच ने बहाल किया।
यह मुद्दा GitHub सुरक्षा सलाहकारों के माध्यम से निजी रूप से रिपोर्ट किया गया था।
रिपोर्ट में शामिल था:
बाद में समस्या प्रकाशित की गई:
सलाहकार 15 मई, 2026 को प्रकाशित हुआ। फिक्स प्लेन v1.3.1 में भेजा गया।
यहाँ मुख्य सबक सरल है:
साझा एसेट सबसिस्टम प्राधिकरण सीमाएँ हैं, न कि केवल भंडारण सहायक
बहुत सारे डेवलपर इस संदर्भ में सोचते हैं:
वे चीज़ें कार्यान्वयन विवरण हैं।
असली सुरक्षा प्रश्न है:
किरायेदार सीमाओं के पार उस एसेट को हल करने, बदलने, कॉपी करने या पुनः लिंक करने की अनुमति किसे है?
प्लेन में, वह सीमा लगातार लागू नहीं की गई थी।
यह वास्तविक निष्कर्ष है।
यह बग बहु-किरायेदार अनुप्रयोगों की समीक्षा के बारे में कुछ महत्वपूर्ण बात को भी मजबूत करता है:
यह भेद्यता विदेशी भंडारण व्यवहार के बारे में नहीं थी।
यह सही विश्वास-सीमा प्रश्न पूछने के बारे में थी।
प्लेन में, एक प्रमाणित उपयोगकर्ता दूसरे वर्कस्पेस के स्लग और एसेट UUID की आपूर्ति कर सकता था, और V2 एसेट सबसिस्टम ने उन पहचानकर्ताओं पर उससे अधिक भरोसा किया जितना करना चाहिए था।
यही कारण है कि यह CVE-2026-46558 बन गया।
प्लेन v1.3.1 में ठीक किया गया।