Jun 22, 2026·7 min read·37 visits
A semi-blind Server-Side Request Forgery (SSRF) in OpenCTI allows authenticated low-privileged users to probe internal network services and query cloud metadata endpoints by supplying absolute URLs to the platform's feed ingestion engine.
A technical analysis of CVE-2026-21887, a Server-Side Request Forgery (SSRF) vulnerability in OpenCTI. The flaw occurs in the platform's data ingestion mechanism, which processes user-supplied feed URLs via Axios under a default configuration. Authenticated users with low privileges can exploit this to pivot into internal infrastructure, target metadata services, and scan private networks.
The OpenCTI platform relies on an ingestion engine to import external cyber threat intelligence knowledge. This ingestion framework supports various data schemas and delivery methods, such as TAXII streams, RSS updates, and structured CSV documents. Analysts use these feeds to synchronize indicators of compromise and observables directly into their central repository.
Because threat intelligence feeds are hosted on external infrastructures, the platform exposes an input surface allowing authorized users to register remote server URLs. Once registered, the backend scheduling engine periodically issues HTTP requests to pull the feeds. This mechanism creates an attack surface if input validation is missing, as the backend server acts as a proxy for any outbound HTTP communication initiated by users.
CVE-2026-21887 represents a classic Server-Side Request Forgery vulnerability where the platform fails to restrict or validate the target destination before sending the request. The application relies on the Axios library under its default settings to execute HTTP requests. This architecture allows low-privileged, authenticated users to abuse the system's role and manipulate outbound requests to target internal interfaces and local services.
The primary technical defect resides in the execution flow of the data ingestion scheduler. When processing ingestion configurations, the backend retrieves the user-configured URL string directly from the database and passes it to an Axios client instance. Axios is a promise-based HTTP client designed for Node.js applications that handles absolute and relative URLs dynamically.
Axios contains a design pattern where any parameter containing an absolute URI scheme (such as http:// or https://) overrides any configured baseURL. In OpenCTI's implementation, even if the Axios instance is constructed with restrictions, passing the user-defined absolute URL forces Axios to discard local constraints and target the supplied address directly. The application does not deploy a custom connection agent or an IP filter to screen resolving addresses.
This behavior is problematic when deploying applications within private cloud environments or isolated networks. Because the Node.js runtime executes with the host's networking permissions, Axios resolves and routes requests to loopback adapters, internal gateways, and cloud metadata services. The system does not implement a validation pass or custom DNS resolution checking before establishing the TCP connection socket.
Prior to version 6.8.16, the data ingestion component implemented direct, unvalidated connections. The following simplified snippet illustrates the vulnerable implementation pattern inside the ingestion module:
// Vulnerable Implementation
async function fetchThreatFeed(userSuppliedUrl) {
const config = {
timeout: 10000,
headers: { 'Accept': 'application/xml, application/json' }
};
// Axios resolves the absolute URL directly without validating the destination host
const response = await axios.get(userSuppliedUrl, config);
return response.data;
}To remediate this issue, the maintainers integrated strict URL parsing and address verification. The patched version validates that the target host does not resolve to an IP address within private or loopback ranges before initiating the TCP handshake. The following code illustrates the safe implementation introduced in the patch:
// Patched Implementation with Safe Lookup Validation
const dns = require('dns');
const ipRangeCheck = require('ip-range-check');
const PRIVATE_RANGES = ['127.0.0.0/8', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', '169.254.0.0/16'];
async function validateUrl(targetUrl) {
const parsedUrl = new URL(targetUrl);
const hostname = parsedUrl.hostname;
return new Promise((resolve, reject) => {
dns.lookup(hostname, (err, address) => {
if (err) return reject(new Error('DNS resolution failed'));
if (ipRangeCheck(address, PRIVATE_RANGES)) {
return reject(new Error('Forbidden target: IP is within a private network range'));
}
resolve(address);
});
});
}Although this validation pass reduces the attack surface, developers must ensure that the validation is not vulnerable to DNS rebinding. If the application resolves the DNS record once during validation, and then resolves it again during the actual HTTP request, an attacker can configure a malicious nameserver to return a public IP first and then a private IP. Implementing a pinned IP connection agent or using the validated IP directly in the Axios request is necessary to prevent DNS rebinding variants.
An attacker must obtain standard credentials with permissions to define or modify ingestion feeds to exploit this flaw. Once logged in, the attacker initiates a request to register a new threat feed, passing a target loopback or cloud metadata address as the source URI. For instance, to target the internal Redis or Elasticsearch instances within the container network, the attacker enters http://elasticsearch:9200/_cat/indices or http://127.0.0.1:6379/.
The diagram below outlines the communication flow during an exploitation attempt:
Because the ingestion worker expects a highly specific XML or JSON structure, querying generic internal services causes the parser to fail. The application logs the connection details or the parsing failure, exposing the internal service's presence and state to the attacker. This error channel enables port scanning and asset discovery across the private network, transforming the OpenCTI server into an internal network reconnaissance tool.
The impact of CVE-2026-21887 is significant due to the role OpenCTI plays in security operations environments. By acting as a trusted node within a corporate network, the OpenCTI server often has direct network routes to critical assets like log management platforms, directories, and internal development tools. An attacker leverages this trusted path to bypass traditional perimeter firewalls and access unauthenticated internal APIs.
In cloud environments, the SSRF can lead to a full infrastructure takeover if the host can reach the Instance Metadata Service. On AWS, querying http://169.254.169.254/latest/meta-data/iam/security-credentials/ reveals the temporary access keys assigned to the server's IAM role. If the IAM role possesses write permissions over AWS resources, the attacker gains control over external infrastructure assets.
The CVSS v3.1 score is calculated at 7.7. The changed scope (S:C) reflects that the vulnerability allows the attacker to pivot from the application layer to the host's physical or virtual network, breaching the isolation boundaries of the platform. Since the attacker must be authenticated to access the ingestion configuration, the privilege requirement is set to Low, which moderates the score.
The primary remediation path requires upgrading all OpenCTI components and associated client libraries, such as pycti, to version 6.8.16 or higher. The update replaces default HTTP clients with secure instances that restrict network resolution to public IP addresses. Organizations must verify that all worker nodes and backend API servers run the patched container images.
When patching is not immediately feasible, system administrators should deploy egress firewall policies on the OpenCTI host. In a Docker or Kubernetes environment, configure network policies to explicitly deny outgoing traffic to private subnets (RFC 1918) and the link-local address 169.254.169.254. This ensures that even if the application processes an arbitrary absolute URL, the underlying network layer blocks the connection.
Additionally, cloud engineers should configure metadata services to enforce version 2 tokens and restrict token hop limits. On AWS, setting the IMDSv2 Hop Limit to 1 prevents containerized workloads on a bridge network from accessing host metadata. This mitigation prevents credential extraction even if an application-layer SSRF vulnerability exists.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
OpenCTI Citeum | < 6.8.16 | 6.8.16 |
pycti Citeum | < 6.8.16 | 6.8.16 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 |
| Attack Vector | Network |
| CVSS v3.1 Score | 7.7 |
| EPSS Score | 0.00212 (0.21%) |
| Impact | Semi-Blind Server-Side Request Forgery |
| Exploit Status | No Public Exploit Available |
| KEV Status | Not Listed |
The web application fetches a remote resource without validating the user-supplied URL, allowing requests to be sent to arbitrary destinations, including internal systems.
An information disclosure vulnerability in Craft CMS allows users with administrative or non-sandboxed template-authoring privileges to read arbitrary system and configuration files. The issue stems from an incomplete class instantiation blocklist in the Twig template extension, which omitted PHP's built-in SplFileObject class.
An authorization bypass vulnerability in Craft CMS allows authenticated control panel users with low privileges to reorder global sets. This alters structure and writes to the project configuration database schema without administrative rights.
Prior to versions 10.9.8 and 11.16.1, Mermaid is vulnerable to prototype pollution via its deep-merge utility function assignWithDepth. This helper is invoked by public configuration-setting interfaces, specifically mermaid.initialize, mermaidAPI.setConfig, and mermaidAPI.updateSiteConfig. Because assignWithDepth recursively merges developer-provided properties into Mermaid's internal configuration state without proper sanitization, an attacker who can control or influence the configuration payload can corrupt the global Object.prototype. This vulnerability can lead to security bypasses, cross-site scripting (XSS), or execution flow modifications in applications using vulnerable Mermaid integrations.
A high-severity path traversal vulnerability exists in Traefik's Kubernetes Ingress NGINX provider. The flaw resides in the RewriteTarget middleware, which is auto-generated when an Ingress resource specifies the `nginx.ingress.kubernetes.io/rewrite-target` annotation. This allows remote, unauthenticated attackers to bypass route-level authentication and access restricted downstream endpoints by exploiting a parser differential.
CVE-2026-65600 is a path traversal vulnerability in the ReplacePathRegex middleware component of Traefik. An unauthenticated remote attacker can exploit the vulnerability to inject directory traversal sequences. When Traefik forwards the resulting un-normalized path, downstream backend web servers normalize the request to execute administrative or protected paths, bypassing gateway-enforced security policies.
A critical authentication bypass and context spoofing vulnerability exists in Traefik's BasicAuth, DigestAuth, and ForwardAuth middlewares prior to versions 2.11.51, 3.6.22, and 3.7.6. The flaw arises because Traefik's header cleanup mechanisms rely on Go's standard library header canonicalization, which does not modify or delete headers containing underscores. Consequently, unauthenticated remote attackers can inject custom underscore-variant headers (e.g., X_Auth_User) that bypass Traefik's stripping filters and reach backend application servers. When downstream backends normalize both hyphens and underscores into the same environment variables, the attacker's spoofed identity value is processed as trusted authorization data.