Jun 18, 2026·6 min read·2 visits
Black Lantern Security BBOT's docker_pull module blindly parses and requests the realm URL from a Docker registry's WWW-Authenticate header, leading to Server-Side Request Forgery (SSRF) and potential credential exposure.
A Server-Side Request Forgery (SSRF) vulnerability exists in the docker_pull module of Black Lantern Security BBOT. By returning a maliciously crafted WWW-Authenticate header from a rogue Docker registry or executing a Man-in-the-Middle (MitM) attack, an attacker can coerce the BBOT scanner into making arbitrary HTTP requests to internal system services or external infrastructure, potentially disclosing sensitive authorization tokens and host metadata.
The Docker Registry HTTP API V2 protocol implements a decentralized, token-based authentication scheme. When an unauthenticated client queries a registry endpoint, the registry responds with an HTTP 401 Unauthorized status and a WWW-Authenticate header. This header contains details on how and where the client can obtain an authentication token, specifically referencing a target realm URL.
In Black Lantern Security's BBOT recursive internet scanner (versions 2.0.0 through 2.8.4), the docker_pull module handles these authentication requests. The module extracts the realm parameter directly from the HTTP response header and issues a subsequent HTTP GET request to retrieve the required token.
Because the application does not validate the authority or target domain of the parsed realm URL, this design creates an unauthenticated Server-Side Request Forgery (SSRF) vulnerability. An attacker can exploit this behavior by hosting a malicious Docker registry or performing a Man-in-the-Middle (MitM) interception of standard registry traffic.
The root cause of this vulnerability lies in the implicit trust placed in the WWW-Authenticate response header. Specifically, the docker_pull module failed to perform validation on the parsed realm parameter prior to using it to construct a outbound HTTP request.
During a standard connection sequence, BBOT initiates an anonymous API call to the registry. If the registry returns an HTTP 401 response, BBOT parses the www-authenticate header using crude, fragile string split operations. This parsing mechanism lacks any sanity checking or input validation.
After retrieving the value of the realm parameter, the application directly passes the constructed URL to its HTTP client helper. This behavior allows any remote endpoint that behaves as a Docker registry to control the destination of BBOT's subsequent outbound HTTP connection, exposing local interfaces, cloud metadata endpoints, and internal network infrastructure to unauthorized web requests.
An analysis of the vulnerable code path in bbot/modules/docker_pull.py reveals how the unvalidated parameter is processed and executed:
async def docker_api_request(self, url: str):
...
response = await self.helpers.request(url, headers=self.headers, follow_redirects=True)
if response is not None and response.status_code != 401:
return response
try:
www_authenticate_headers = response.headers.get("www-authenticate", "")
# Crude, fragile string splits to extract parameters
realm = www_authenticate_headers.split('realm="')[1].split('"')[0]
service = www_authenticate_headers.split('service="')[1].split('"')[0]
scope = www_authenticate_headers.split('scope="')[1].split('"')[0]
except (KeyError, IndexError):
self.log.warning(f"Could not obtain realm, service or scope from {url}")
break
auth_url = f"{realm}?service={service}&scope={scope}"
# SSRF Bottleneck Step: Direct HTTP request to the untrusted realm URL
auth_response = await self.helpers.request(auth_url)
...The split mechanism reads the raw, unescaped string in www-authenticate. The value of realm is used to construct the absolute destination URL auth_url without verifying that the hostname in realm matches the hostname in the parent request url. Because self.helpers.request() carries session headers, any auth tokens or system identifiers configured in the module are transmitted directly to the attacker-specified domain.
An attacker can exploit this vulnerability through two main vectors: a malicious registry domain or a local network Man-in-the-Middle (MitM) attack.
In the malicious registry scenario, the attacker sets up an internet-accessible Docker registry (e.g., evil-registry.com). When BBOT scans this registry, the registry sends a crafted HTTP 401 response with a payload pointing to an internal target:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="http://169.254.169.254/latest/meta-data/",service="registry.docker.io",scope="repository:library/nginx:pull"Upon parsing this header, BBOT issues an internal GET request targeting the AWS or cloud Link-Local Instance Metadata Service (IMDSv1). This allows the attacker to retrieve sensitive system configuration data or cloud environment security credentials.
If the attacker is positioned as a local network MitM, they can intercept standard HTTP outbound connections from BBOT and inject the same challenge response, redirecting the scanner's internal web client to any internal TCP port or web application interface on the local network segment.
Black Lantern Security addressed this vulnerability in commit c2f4bc0f4e4bb4d00f06750dcabf1d9c74c0d3b4. The patch introduces structured parsing of the authenticate header and validation logic to verify the target realm domain:
def _validate_realm(self, registry_url, realm):
registry_host = self.helpers.urlparse(registry_url).hostname or ""
realm_host = self.helpers.urlparse(realm).hostname or ""
_, registry_domain = self.helpers.split_domain(registry_host)
_, realm_domain = self.helpers.split_domain(realm_host)
if not realm_domain or realm_domain != registry_domain:
self.warning(f"Auth realm TLD ({realm_domain}) does not match registry TLD ({registry_domain}), skipping")
return False
return TrueWhile the patch successfully prevents cross-domain open redirection and basic SSRF attacks, several advanced bypass vectors remain open. First, the patch does not perform IP-level validation prior to initiating the HTTP request. This allows private IP DNS mapping, where an attacker maps a wildcard subdomain of their registered registry (e.g., local.evil-registry.com) directly to 127.0.0.1 or 10.0.0.1. Since both the registry and the realm share the registrable domain evil-registry.com, validation passes, and the internal service is queried.
Second, the system is vulnerable to DNS Rebinding attacks. An attacker can set a low TTL on their registry DNS record, resolving to a benign public IP during validation, but changing to an internal system IP immediately before BBOT executes the HTTP request. Lastly, because the validator checks domains but does not restrict port numbers, an attacker can specify alternate ports (such as registry.domain:22 or registry.domain:8080) to conduct internal port scanning.
To fully address this vulnerability, administrators and security engineers must upgrade BBOT to version 2.8.5 or higher. In environments where patching cannot be immediately completed, administrators should enforce network isolation for active scanner nodes.
Scanner instances must be deployed in an isolated Virtual Private Cloud (VPC) with firewall egress rules that strictly block traffic to RFC 1918 networks, the loopback interface, and link-local addresses (such as 169.254.169.254). For cloud instances running on AWS, enforce IMDSv2 and configure the hop limit to 1 to block unauthorized containerized requests to metadata endpoints.
Security teams can monitor SIEM or proxy logs for outbound connections from BBOT instances that target local endpoints immediately following HTTP 401 authentication exchanges. Network detection tools should flag any connections to non-standard ports (such as 22, 3306, or 8080) originating from the Docker pull automation module.
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
BBOT Black Lantern Security | >= 2.0.0, <= 2.8.4 | 2.8.5 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 |
| Attack Vector | Network |
| CVSS v3.1 Score | 3.1 (Low) |
| EPSS Score | 0.00167 |
| Impact | Low-severity information disclosure and Server-Side Request Forgery |
| Exploit Status | none |
| KEV Status | Not Listed |
The web server receives a URL or similar request from an upstream server or client and retrieves the contents of this URL without sufficiently validating that the target is safe or intended.
An unauthenticated Server-Side Request Forgery (SSRF) vulnerability was identified in the Crawl4AI Docker API server before version 0.9.0. The vulnerability exists because the streaming crawl endpoint (/crawl/stream) and the standard crawl endpoint with streaming enabled (/crawl with crawler_config.stream=true) bypass the validate_url_destination security filter. This allows remote, unauthenticated attackers to execute arbitrary HTTP requests targeting internal infrastructure, loopback interfaces, or cloud metadata endpoints like AWS/GCP services.
CVE-2026-12565 is a medium-severity path traversal (Zip-Slip) vulnerability within the internal unarchive module of the BBOT (Black Lantern Security) OSINT framework. The vulnerability exists due to a failure to validate target paths before extracting archives using host-level command-line utilities. This allows remote, unauthenticated attackers to write arbitrary files outside of the target extraction folder on environments running legacy versions of GNU tar.
CVE-2026-12568 is a path traversal vulnerability (CWE-22) in the postman_download module of BBOT (Babbage Border Obsession Tool) version 2.1.0 through 2.8.5. The vulnerability allows an attacker to perform arbitrary file writes on the local machine running the BBOT scan via a maliciously named remote Postman workspace.
The github_workflows module in BBOT (Black Lantern Security OSINT framework) versions 2.0.0 through 2.8.4 constructs local directory paths from user-controlled repository and owner names without validating for symbolic links. A local attacker sharing the scan directory can pre-plant a symlink at the predictable output path, forcing BBOT to write downloaded workflow artifacts or run logs to an arbitrary location on the filesystem.
An unauthenticated remote memory exhaustion vulnerability in the JLine3 Telnet server allows attackers to crash the host Java Virtual Machine (JVM). The flaw exists in the processing of the NEW-ENVIRON option, where the server accepts an arbitrary number of environment variables without limits, storing them in an unconstrained HashMap. Sending as little as 3.25 MB of payload data can exhaust a standard JVM heap and trigger an OutOfMemoryError. This vulnerability affects applications integrating the remote-telnet module of JLine3.
CVE-2026-49975 describes a high-severity remote Denial of Service (DoS) vulnerability in the Apache HTTP Server's mod_http2 module. Unauthenticated attackers can exploit the HPACK compression and cookie-merging behavior to trigger severe, quadratic memory allocation. This resource exhaustion is maintained by manipulating the HTTP/2 flow-control window, ultimately forcing an Out-of-Memory condition on the server host.