
Penpot का रिमोट इमेज इम्पोर्ट एक प्रमाणित फ़ाइल संपादक को एक सामान्य मीडिया सुविधा को बैकएंड-उत्पत्ति SSRF में बदलने देता है, क्योंकि हमलावर-नियंत्रित URL बिना गंतव्य फ़िल्टरिंग के रीडायरेक्ट-फ़ॉलो करने वाले सर्वर फ़ेच पथ में पार कर गए।
Penpot की रिमोट इमेज इम्पोर्ट सुविधा ने एक प्रमाणित फ़ाइल संपादक को एक सामान्य मीडिया सुविधा को बैकएंड-उत्पत्ति वाले SSRF में बदलने दिया, क्योंकि हमलावर-नियंत्रित URL बिना गंतव्य फ़िल्टरिंग के एक रीडायरेक्ट-फॉलो करने वाले सर्वर फ़ेच पथ में प्रवेश कर गए।
मुझे यह दोष Penpot की समीक्षा करते समय मिला, जो खुला-स्रोत डिज़ाइन और कोड सहयोग प्लेटफ़ॉर्म है, और मेरे मन में एक बहुत विशिष्ट प्रश्न था:
क्या होता है जब एक सहयोगी डिज़ाइन टूल एक उपयोगकर्ता को बैकएंड को एक दूरस्थ छवि URL देने देता है?
इस मामले में, उस प्रश्न ने एक वास्तविक बग पाया।
Penpot की रिमोट इमेज इम्पोर्ट प्रक्रिया ने उपयोगकर्ता-नियंत्रित URL स्वीकार किया और बैकएंड को सर्वर नेटवर्क संदर्भ से इसे लाने का कारण बनाया, बिना लूपबैक या निजी-नेटवर्क लक्ष्यों के लिए गंतव्य प्रतिबंध लागू किए। साझा HTTP क्लाइंट ने स्वचालित रूप से रीडायरेक्ट का पालन भी किया।
इसने एक सामान्य मीडिया सुविधा को एक प्रमाणित बैकएंड-उत्पत्ति SSRF प्रिमिटिव में बदल दिया और अंततः CVE-2026-45806 बन गया।
Penpot: Penpot GitHub पर
CVE: CVE-2026-45806
CVSS: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
यह Penpot को प्रभावित करता था। इसकी आधिकारिक साइट और मीडिया किट पर, Penpot स्वयं को +1M बढ़ते उपयोगकर्ता आधार के रूप में प्रस्तुत करता है और कहता है कि हज़ारों संगठन इसका उपयोग करते हैं, जिनमें Blender, Mozilla, Fedora, NTT Data, MIT, Société Générale, Cisco, Fujitsu, Indra, और शामिल हैं।

प्रमाणित फ़ाइल संपादक -> हमलावर-नियंत्रित रिमोट इमेज URL -> create-file-media-object-from-url -> बैकएंड download-image फ़ेच रीडायरेक्ट सक्षम के साथ -> अंतिम अनुरोध आंतरिक-केवल इमेज एंडपॉइंट पर पहुँचता है -> बैकएंड-उत्पत्ति SSRF / आंतरिक पहुँच योग्यता
Penpot एक खुला-स्रोत डिज़ाइन और कोड सहयोग प्लेटफ़ॉर्म है।
यह निम्नलिखित चीज़ों को संभालता है:
इसका अर्थ है कि इसका मीडिया आयात पथ एक वास्तविक विश्वास सीमा पर स्थित है।
यहाँ महत्वपूर्ण प्रश्न यह नहीं था कि क्या Penpot रिमोट इमेज आयात का समर्थन करता है।
असली प्रश्न था:
क्या Penpot प्रतिबंधित करता है कि जब कोई उपयोगकर्ता एक रिमोट इमेज आयात करता है तो बैकएंड कहाँ कनेक्ट कर सकता है?
इस मामले में, इसने नहीं किया।
बहुत से लोग रिमोट आयात सुविधाओं को कम आंकते हैं।
यह एक गलती है।
जिस क्षण कोई एप्लिकेशन:
यह एक वास्तविक आउटबाउंड विश्वास सीमा बनाता है।
यही यहाँ समस्या थी।
यह बग इमेज रेंडरिंग में नहीं था। यह फ़ाइल भंडारण में नहीं था। यह किसी फ़ाइल को संपादित करने के लिए सामान्य अनुमति जाँच में नहीं था।
यह एक क्लासिक सर्वर-साइड विश्वास विफलता थी:
एक वास्तविक कमज़ोरी पैदा करने के लिए यह पर्याप्त है।
मैंने Penpot को अंधाधुंध RPC विधियों को फ़ज़ करके या पहले क्रैश देखकर नहीं पहुँचा।
सबसे मजबूत दृष्टिकोण सबसे आशाजनक सुरक्षा सीमा की पहचान करना था।
Penpot के लिए, वह रिमोट मीडिया आयात था।
क्यों?
क्योंकि यह सुविधा इन चीज़ों को जोड़ती है:
यह निरीक्षण करने के लिए सही सीमा थी।
और यह ठीक वहीं था जहाँ बग रहता था।
बग एक छोटी विश्वास श्रृंखला में सिमट जाता है।
फ्रंटएंड में:
(defn upload-media-url
[name file-id url]
(rp/cmd!
:create-file-media-object-from-url
{:name name
:file-id file-id
:url url
:is-local true}))
उपयोगकर्ता-नियंत्रित url सीधे RPC कॉल में भेजा जाता है।
फिर बैकएंड में:
(sv/defmethod ::create-file-media-object-from-url
...
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id] :as params}]
(files/check-edition-permissions! pool profile-id file-id)
...
(let [_ (files/get-minimal-file cfg file-id)
mobj (create-file-media-object-from-url cfg (assoc params :profile-id profile-id))])
और:
(defn- create-file-media-object-from-url
[cfg {:keys [url name] :as params}]
(let [content (media/download-image cfg url)
बैकएंड जाँचता है कि कॉल करने वाला लक्ष्य फ़ाइल को संपादित कर सकता है, फिर हमलावर-नियंत्रित URL को media/download-image में पास करता है।
फ़ेच कार्यान्वयन यहाँ है:
(defn download-image
"Download an image from the provided URI and return the media input object"
[{:keys [::http/client]} uri]
...
(http/req! client
{:method :get :uri uri}
{:response-type :input-stream})
और साझा HTTP क्लाइंट इस प्रकार कॉन्फ़िगर किया गया है:
(http/build-client {:connect-timeout 30000
:follow-redirects :always}))
यह पूरी कमज़ोरी है:
क्योंकि हमलावर को केवल आवश्यकता है:
हमला श्रृंखला सीधी है:
यह पूरा बग है।
महत्वपूर्ण अंतर यह है कि अनुरोध कहाँ होता है।
सवाल यह नहीं है:
"क्या Penpot URL से इमेज आयात कर सकता है?"
असली सवाल है:
"क्या कोई प्रमाणित उपयोगकर्ता Penpot बैकएंड को आंतरिक गंतव्यों से कनेक्ट करने के लिए बना सकता है जिन तक उपयोगकर्ता को एप्लिकेशन के माध्यम से नहीं पहुँचना चाहिए?"
इस मामले में, उत्तर हाँ था।
यह मायने रखता है क्योंकि इसमें वास्तविक अंतर है:
इमेज सत्यापन इस अंतर को नहीं मिटाता।
यह कुछ प्रत्यक्ष डेटा निकासी मामलों को संकीर्ण करता है, लेकिन SSRF की स्थिति या नेटवर्क सीमा उल्लंघन को नहीं हटाता।
मैंने इस मुद्दे को एक नियंत्रित स्थानीय प्रमाण के साथ मान्य किया जो सीधे समीक्षित Penpot कोड पथ से जुड़ा था।
लक्ष्य तीसरे पक्ष के बुनियादी ढांचे को हिट करना नहीं था। लक्ष्य सटीक सुरक्षा गुण साबित करना था:
मैंने एक स्व-निहित Java वैधकर्ता बनाया जो प्रासंगिक व्यवहार को दर्शाता था:
content-type और content-length पर आधारित इमेज स्वीकृति जाँचमैंने दो मामलों को मान्य किया।
वैधकर्ता ने अनुरोध किया:
http://127.0.0.1:7790/internal.png
देखा गया परिणाम:
http://127.0.0.1:7790/internal.pnghttp://127.0.0.1:7790/internal.png200image/pngइसने साबित किया कि इम्पोर्ट-शैली फ़ेच तर्क ने सीधे एक आंतरिक-केवल इमेज एंडपॉइंट को स्वीकार किया।
फिर वैधकर्ता ने अनुरोध किया:
http://localhost:7791/redirect-to-internal
उस एंडपॉइंट ने एक HTTP रीडायरेक्ट लौटाया:
http://127.0.0.1:7790/internal.png
देखा गया परिणाम:
http://localhost:7791/redirect-to-internalhttp://127.0.0.1:7790/internal.png200image/pngआंतरिक-केवल श्रोता ने रीडायरेक्ट किए गए अनुरोध को लॉग किया।
इसने अधिक महत्वपूर्ण दावा साबित किया:
यहाँ पेलोड जानबूझकर सरल था:
यह मायने रखता था क्योंकि Penpot केवल मनमाने बाइट्स नहीं लाता और रुकता नहीं। यह अनुरोध के बाद मीडिया-उन्मुख सत्यापन करता है।
इसलिए सही प्रमाण यह नहीं था:
"बैकएंड कहीं कनेक्ट करने का प्रयास कर सकता है"
अधिक मजबूत प्रमाण था:
"बैकएंड को कहीं आंतरिक कनेक्ट करने और सुविधा द्वारा अपेक्षित समान इमेज-जैसी बाधाओं के तहत अनुरोध को सफलतापूर्वक पूरा करने के लिए बनाया जा सकता है"
यह ठीक वही है जो मान्यकरण ने प्रदर्शित किया।
इस तरह के SSRF बगों पर एक सामान्य प्रतिक्रिया है:
"लक्ष्य को अभी भी एक इमेज लौटानी है"
यह अवलोकन सत्य है लेकिन अधूरा है।
यह कमज़ोरी को नहीं हटाता।
यह केवल आपको बताता है कि कौन से आंतरिक लक्ष्य सबसे अधिक सीधे उपयोगी हैं।
यह मुद्दा अभी भी सक्षम बनाता है:
यह अभी भी एक वास्तविक सुरक्षा सीमा उल्लंघन है।
विशेष रूप से स्व-होस्टेड वातावरण में, आंतरिक सेवाएँ अक्सर उस सीमा के पीछे विशेष रूप से मौजूद होती हैं।
इस मुद्दे को अंततः एक उच्च गंभीरता CVSS सौंपा गया:
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
यह वर्गीकरण समझ में आता है।
दावा यह नहीं है कि एक अप्रमाणित हमलावर किसी भी Penpot तैनाती को शून्य से तुरंत समझौता कर सकता है।
दावा यह है कि कोई भी सामान्य प्रमाणित फ़ाइल संपादक Penpot को आंतरिक गंतव्यों के खिलाफ बैकएंड अनुरोध प्रिमिटिव में बदल सकता है, जिसमें लूपबैक और निजी-नेटवर्क लक्ष्यों तक रीडायरेक्ट-सहायता प्राप्त पहुँच शामिल है।
प्रकटीकरण के दौरान कुछ गंभीरता चर्चा हुई, मुख्य रूप से:
ये चर्चा करने के लिए उचित बाधाएँ हैं।
लेकिन वे मुख्य मुद्दे को नहीं हटाते:
यह एक वास्तविक और बचाव योग्य SSRF कमज़ोरी है।
यहाँ महत्वपूर्ण फिक्स सख्त MIME हैंडलिंग नहीं है।
असली फिक्स आउटबाउंड गंतव्य नीति है।
इस श्रेणी के बग के लिए एक सही उपचार की आवश्यकता है:
http और https की अनुमति देंlocalhostयह सही फिक्स दिशा है क्योंकि यह इमेज पार्सिंग बग नहीं था। यह एक नेटवर्क विश्वास-सीमा बग था।
यह मुद्दा GitHub की सुरक्षा रिपोर्टिंग प्रवाह के माध्यम से निजी रूप से रिपोर्ट किया गया था।
रिपोर्ट में शामिल था:
अनुरक्षकों ने मुद्दे की पुष्टि की और एक समाधान पर काम करना शुरू किया।
बाद में मुद्दे को सौंपा गया:
CVE-2026-45806
यहाँ मुख्य सबक सरल है:
रिमोट मीडिया आयात एक आउटबाउंड विश्वास सीमा है, न कि केवल एक सुविधा
कई डेवलपर इस संदर्भ में सोचते हैं:
ये कार्यान्वयन विवरण हैं।
असली सुरक्षा प्रश्न है:
बैकएंड को एक उपयोगकर्ता की ओर से कहाँ कनेक्ट करने की अनुमति है?
यदि उस प्रश्न का स्पष्ट रूप से उत्तर नहीं दिया जाता है, तो रिमोट आयात जैसी सुविधाएँ डिफ़ॉल्ट रूप से SSRF सतहें बन जाती हैं।
यह बग SSRF समीक्षा के बारे में कुछ महत्वपूर्ण को भी मजबूत करता है:
यह असली निष्कर्ष है।
यह कमज़ोरी एक आकर्षक पेलोड के बारे में नहीं थी।
यह सही विश्वास-सीमा प्रश्न पूछने के बारे में था।
Penpot ने एक प्रमाणित फ़ाइल संपादक को एक रिमोट इमेज URL प्रदान करने दिया, और बैकएंड ने उस URL पर आवश्यकता से अधिक भरोसा किया। रीडायरेक्ट हैंडलिंग ने बाकी किया।
यही कारण है कि यह CVE-2026-45806 बन गया।