
Drupal 11.4.8 - उच्च - रिमोट - SSRF - oEmbed डिस्कवरी एक अनस्कोप्ड सेकंड-हॉप URL प्राप्त करती है
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · drupal-oembed-ssrf
राइट-अप: https://abraxaslabs.tech/research/drupal-oembed-ssrf
वर्ग: SSRF पहुँच: रिमोट
Drupal core 11.4.8 (61044508) - Drupal
SA-CORE-2026-008 ने discovery document होस्ट को media_oembed_discovery_trusted_host_patterns के साथ गेट किया। UrlResolver::findUrl अभी भी कच्चा link href लौटाता है। इसके बाद ResourceFetcher::fetchResource उस URL पर बिना किसी होस्ट या प्राइवेट-IP जाँच के GET करता है। oEmbed thumbnail_url भी उसी प्रकार का GET है। डिफ़ॉल्ट पैटर्न खाली होते हैं, इसलिए जब तक कोई एडमिन इसे सक्षम नहीं करता, तब तक discovery बंद रहती है।
एडमिन द्वारा discovery सक्षम करने के बाद, जो उपयोगकर्ता oEmbed मीडिया बना सकता है, वह Drupal को ऐसे allowlisted पेज की ओर इंगित कर सकता है जिसका JSON oEmbed लिंक href loopback, RFC1918, या metadata हो।
| ID | अभी तक कोई CVE नहीं |
| वर्ग | SSRF (SA-CORE-2026-008 का दूसरे-हॉप का अवशेष) |
| पहुँच | रिमोट (एडमिन द्वारा discovery होस्ट सेट करने के बाद, प्रमाणित मीडिया निर्माण) |
| CWE | CWE-918 |
| CVSS | मध्यम: 6.1 CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N |
| उत्पाद | Drupal core |
| प्रभावित | 11.4.8 (61044508071749629aaf3380aa85971e94df9e84) |
| प्रमाणीकरण | प्रमाणित मीडिया निर्माण, एडमिन द्वारा discovery होस्ट सेट करने के बाद। AC:H वही एडमिन टॉगल है। |
| लाइसेंस | GNU Affero GPL v3.0 |
| लैब | केवल 127.0.0.1 |
केवल तब जब एडमिन ने discovery trusted-host पैटर्न सेट किए हों। उसके बाद मीडिया निर्माता होना पर्याप्त है। बिना खाते वाला पूर्ण अजनबी डिफ़ॉल्ट पर ऐसा नहीं कर सकता। यह SSRF है, RCE नहीं और एडमिन लॉगिन भी नहीं।
| विशेषाधिकार | विधि / सिंक | प्रकार | लैब-प्रमाणित या अनुमानित |
|---|---|---|---|
| Drupal से हमलावर द्वारा चुना गया URL GET करवाना (इस लैब में loopback) | UrlResolver::findUrl कच्चा href फिर ResourceFetcher::fetchResource GET | रेकॉन (सर्वर-साइड फ़ेच) | लैब-प्रमाणित। http://127.0.0.1:18080/oembed ने DRUPAL-OEMBED-SSRF-WITNESS लौटाया |
| उस URL का HTTP बॉडी PHP में पढ़ना | वही GET; JSON/XML को oEmbed के रूप में पार्स किया गया | रेकॉन | लैब-प्रमाणित। Witness 200 बॉडी में था |
रिसोर्स बनने के बाद thumbnail_url के लिए वही GET | OEmbed::getLocalThumbnailUri ~417-456 | रेकॉन | पिन से अनुमानित। इस लैब ने discovered href पर ही रोका |
| यदि PHP netns कर सके तो RFC1918 / link-local / metadata तक पहुँचना | बिना स्कोप वाला Guzzle GET | रेकॉन | अनुमानित। लैब ने loopback का उपयोग किया, 169.254.169.254 का नहीं |
इस अवशेष पर बंद: पैटर्न खाली होने पर पहला हॉप (लैब-प्रमाणित); जब HTML होस्ट मेल नहीं खाता तब पहला हॉप (लैब-प्रमाणित); मीडिया भूमिका के बिना Standard पर बिना प्रमाणीकरण वाला मीडिया निर्माण; RCE; एडमिन सत्र चोरी।
मैंने SA-CORE-2026-008 के बाद Drupal 11.4.8 को पिन किया। पहला हॉप गेटेड है:
$patterns = \array_map(static fn ($hostPattern) => \sprintf('{%s}i', $hostPattern), Settings::get('media_oembed_discovery_trusted_host_patterns', []));
// ...
if (!$allowed) {
return FALSE;
}
$response = $this->httpClient->get($url);
return $this->findUrl($xpath, 'json') ?: $this->findUrl($xpath, 'xml');
findUrl कच्चा href लौटाता है। ResourceFetcher इसे एक टाइमआउट के साथ GET करता है और कुछ नहीं:
$result = $xpath->query("//link[@type='application/$format+oembed']");
return $result->length ? $result->item(0)->getAttribute('href') : FALSE;
$response = $this->httpClient->request('GET', $url, [
RequestOptions::TIMEOUT => $this->timeout,
]);
लैब उन 11.4.8 फ़ंक्शन्स का एक निष्ठावान गैजेट है, न कि एक लाइव drupal:11.4.8 साइट इंस्टॉल। अंतिम पंक्ति how=gadget का उपयोग करती है। खाली पैटर्न्स ने फ़ेच नहीं किया। एक गैर-मेल खाते होस्ट ने फ़ेच नहीं किया। ^firsthop$ की अनुमति होने पर, discoverResourceUrl ने http://127.0.0.1:18080/oembed लौटाया और अनस्कोप्ड GET ने विटनेस लौटाया।
पहले से दर्ज गलत मोड़: default-off को मिस मानना (यह इच्छित फ़र्स्ट-हॉप गेट है; बचा हुआ हिस्सा हॉप दो है); एक लाइव Standard इंस्टॉल को ओरेकल कहना (यह पैक पिन फ़ंक्शन्स है); Guzzle चलने के कारण RCE का दावा करना। थिएटर: एक रिवर्स शेल। ओरेकल default-off प्लस गलत-होस्ट ब्लॉक्ड प्लस द सेकंड-हॉप विटनेस है।
वही पिन अवशेष: CKEditor 5 FileIsImage skip।
python3 drupal-oembed-ssrf-Abraxas-Labs.py
या
cd lab
./run.sh
केवल लूपबैक: पहला-हॉप HTML http://127.0.0.1:19510 पर। दूसरा हॉप गैजेट netns के अंदर http://127.0.0.1:18080/oembed है।
SUCCESS drupal-oembed-ssrf how=gadget pin=11.4.8 first-hop=allowed second-hop=127.0.0.1:18080 default-off=blocked DRUPAL-OEMBED-SSRF-WITNESS
खोजे गए endpoint और thumbnail_url दोनों पर वही host / private-IP नीति लागू करें। ऐसे href को न लाएँ जिसका host पहले hop में विफल हो जाता।
61044508071749629aaf3380aa85971e94df9e84)UrlResolver.php · ResourceFetcher.phpGNU Affero GPL v3.0. देखें LICENSE. केवल लूपबैक लैब। कोई वारंटी नहीं।