
Drupal 11.4.8 - उच्च - रिमोट - SSRF - oEmbed डिस्कवरी एक अनस्कोप्ड सेकंड-हॉप URL प्राप्त करती है
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · drupal-oembed-ssrf
Class: SSRF Reach: Remote
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 को बिना किसी होस्ट या private-IP जाँच के GET करता है। oEmbed thumbnail_url भी उसी प्रकार का GET है। डिफ़ॉल्ट पैटर्न खाली हैं, इसलिए जब तक कोई एडमिन इसे सक्षम नहीं करता, discovery बंद रहती है।
एडमिन द्वारा discovery सक्षम करने के बाद, जो उपयोगकर्ता oEmbed मीडिया बना सकता है, वह Drupal को एक allowlisted पेज की ओर इंगित कर सकता है जिसका JSON oEmbed link href loopback, RFC1918, या metadata हो।
| ID | अभी तक कोई CVE नहीं |
| Class | SSRF (SA-CORE-2026-008 का second-hop अवशेष) |
| Reach | Remote (एडमिन द्वारा discovery hosts सेट करने के बाद, authenticated media create) |
| CWE | CWE-918 |
| CVSS | Medium: 6.1 CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N |
| Product | Drupal core |
| Affected | 11.4.8 (61044508071749629aaf3380aa85971e94df9e84) |
| Auth | authenticated media create, एडमिन द्वारा discovery hosts सेट करने के बाद। AC:H वही एडमिन टॉगल है। |
| License | GNU Affero GPL v3.0 |
| Lab | केवल 127.0.0.1 |
केवल तब जब एडमिन ने discovery trusted-host patterns सेट किए हों। उसके बाद एक media creator पर्याप्त है। बिना खाते वाला पूर्ण अजनबी डिफ़ॉल्ट पर ऐसा नहीं कर सकता। यह SSRF है, RCE नहीं और एडमिन लॉगिन भी नहीं।
| Privilege | Method / sink | Kind | Lab-proven या inferred |
|---|---|---|---|
| Drupal को हमलावर-चयनित URL (इस लैब में loopback) GET करवाना | UrlResolver::findUrl कच्चा href फिर ResourceFetcher::fetchResource GET | recon (server-side fetch) | Lab-proven। http://127.0.0.1:18080/oembed ने DRUPAL-OEMBED-SSRF-WITNESS लौटाया |
| उस URL के HTTP body को PHP में पढ़ना | वही GET; JSON/XML को oEmbed के रूप में पार्स किया गया | recon | Lab-proven। Witness 200 body में था |
resource बनने के बाद thumbnail_url के लिए वही GET | OEmbed::getLocalThumbnailUri ~417-456 | recon | pin से inferred। यह लैब discovered href पर रुकी |
| यदि PHP netns कर सके तो RFC1918 / link-local / metadata तक पहुँचना | Unscoped Guzzle GET | recon | Inferred। लैब ने loopback का उपयोग किया, 169.254.169.254 का नहीं |
इस अवशेष पर बंद: पैटर्न खाली होने पर first hop (lab-proven); HTML होस्ट मेल न खाने पर first hop (lab-proven); media role के बिना Standard पर unauthenticated media create; RCE; एडमिन सत्र चोरी।
मैंने SA-CORE-2026-008 के बाद Drupal 11.4.8 को pin किया। first hop गेटेड है:
$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 इसे एक timeout के साथ 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 फ़ंक्शनों का एक faithful gadget है, लाइव drupal:11.4.8 साइट इंस्टॉल नहीं। अंतिम पंक्ति how=gadget का उपयोग करती है। खाली पैटर्न ने fetch नहीं किया। मेल न खाने वाले होस्ट ने fetch नहीं किया। ^firsthop$ allowed होने पर, discoverResourceUrl ने http://127.0.0.1:18080/oembed लौटाया और unscoped GET ने witness लौटाया।
पहले से दर्ज गलत मोड़: default-off को miss मानना (यह इच्छित first-hop gate है; अवशेष hop two है); लाइव Standard इंस्टॉल को oracle कहना (यह पैक pin फ़ंक्शन हैं); Guzzle चलने के कारण RCE का दावा करना। नाटक: एक reverse shell। Oracle है default-off plus wrong-host blocked plus second-hop witness।
वही pin अवशेष: CKEditor 5 FileIsImage skip।
python3 drupal-oembed-ssrf-Abraxas-Labs.py
या
cd lab
./run.sh
केवल loopback: first-hop HTML http://127.0.0.1:19510 पर। Second hop gadget 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
discovered endpoint और thumbnail_url पर वही host / private-IP नीति लागू करें। ऐसा href fetch न करें जिसका होस्ट first hop में विफल होता।
61044508071749629aaf3380aa85971e94df9e84)UrlResolver.php · ResourceFetcher.phpGNU Affero GPL v3.0। देखें LICENSE। केवल loopback लैब। कोई वारंटी नहीं।