Jun 22, 2026·5 min read·3 visits
A flaw in OpenCTI's custom validation plugin allows unauthenticated attackers to bypass GraphQL schema introspection restrictions by modifying whitespaces and control characters, exposing the full database schema.
OpenCTI versions prior to 6.1.9 fail to properly restrict GraphQL schema introspection queries due to a weak pattern-matching implementation. An unauthenticated attacker can bypass the introspection block list by stripping whitespace and carriage returns, enabling complete reconnaissance of the GraphQL schema.
OpenCTI is an open-source cyber threat intelligence platform that utilizes a GraphQL API backend to manage and query threat data and observables. By default, GraphQL APIs expose a feature known as schema introspection, which allows clients to query information about the API's schema itself. Because this can expose internal data structures and sensitive API capabilities, organizations frequently restrict introspection to authenticated administrators.
To enforce this restriction, OpenCTI implemented a custom validation mechanism named secureIntrospectionPlugin within its Apollo Server initialization. This plugin intercepts incoming HTTP POST requests directed at the /graphql endpoint and inspects the raw query payload. If it detects signatures associated with introspection, it rejects the request for unauthenticated users.
However, prior to version 6.1.9, this validation relied on a naive string blacklist. This report analyzes how attackers can easily bypass this filter using formatting tricks, the security implications of such leaks, and the technical drawbacks of the vendor's patch.
The root cause of CVE-2024-37155 lies in a fundamental mismatch between how the validation plugin matches text and how the GraphQL parser interprets it. The secureIntrospectionPlugin attempted to block introspection by searching for specific string sequences like __schema { or __schema(. This regex-like string-inclusion check assumes that all clients format their requests using standard white spacing and indentation rules.
In contrast, the GraphQL specification defines a grammar where white space, carriage returns, and line feeds function merely as separators and are largely ignored during the lexical analysis phase. Consequently, a query string that omits spaces entirely, such as __schema{, is syntactically valid and executes perfectly on the backend parser. The custom validation plugin, however, fails to match this string because it lacks the expected space character.
Furthermore, an attacker can insert alternative control characters or inline comments to disrupt the static string verification. For example, injecting a line break, a carriage return (\r\n), or an inline comment like # comment between the type definition and the opening bracket will completely bypass the block list. The validation layer reads these as non-matching strings, whereas the downstream Apollo Server strips them and processes the introspection command successfully.
In the vulnerable codebase of OpenCTI, the secureIntrospectionPlugin was declared in opencti-graphql/src/graphql/graphql.js. The plugin defined introspectionPatterns as an array of four specific string sequences: ['__schema {', '__schema(', '__type {', '__type(']. The application then evaluated incoming requests using introspectionPatterns.some((pattern) => request.query.includes(pattern)).
The patch committed in f87d96918c63b0c3d3ebfbea6c789d48e2f56ad5 attempted to correct this by modifying the pattern matching array to check for the raw strings directly: ['__schema', '__type'].some((pattern) => request.query.includes(pattern)). While this eliminates the whitespace bypass vector, it introduces a risk of false positives. Legitimate queries containing these substrings as arguments or values will be incorrectly blocked.
There is also a structural fragility in this implementation. The plugin directly accesses request.query.includes(). If Automatic Persisted Queries (APQ) are enabled, the client transmits only a SHA-256 hash instead of the raw query body. In this scenario, request.query is evaluated as undefined, causing the node process to throw a TypeError and crash, resulting in a potential Denial of Service vulnerability.
Exploitation of this vulnerability requires no authentication and can be performed with standard command-line tools. An attacker begins by sending a baseline introspection request formatted with standard spacing. The server intercepts this query and returns a 403 ForbiddenAccess error indicating that the request is not authorized.
To execute the bypass, the attacker reformats the request payload to strip all whitespace between the GraphQL keywords and their arguments. For example, replacing the standard sequence __schema { with __schema{ prevents the custom validator from triggering. The request bypasses the validation plugin entirely and reaches the schema interpreter.
The GraphQL parser successfully resolves this compressed string and executes the introspection query. The server then responds with a complete JSON representation of the schema. This exposes all available types, queries, mutations, and fields to the unauthenticated client.
The primary impact of a schema introspection bypass is comprehensive information disclosure. By dumping the GraphQL schema, an unauthenticated attacker maps out the entire data model of the OpenCTI deployment. This includes hidden administrative fields, experimental queries, and the structural relationships of threat intelligence data.
Additionally, exposure of the schema highlights specific mutation points. This allows attackers to identify potential input parameters and design targeted exploitation payloads for other vulnerabilities, such as injection points or privilege escalation pathways. The leaked metadata significantly reduces the effort required to conduct sophisticated, multi-stage attacks against the application.
From an operational perspective, repeated execution of complex introspection queries can exhaust server CPU and memory resources. Attackers can weaponize these large, nested queries to orchestrate application-layer Denial of Service attacks. Given these factors, the CVSS base score is calculated at 6.5, reflecting partial confidentiality and availability impacts.
The primary remediation strategy is upgrading the OpenCTI platform to version 6.1.9 or later. This replaces the flawed string validation array with a more inclusive filter. To ensure absolute protection, organizations should verify that the backend configuration has PLAYGROUND_ENABLED set to false in production environments.
A more robust programmatical solution is to avoid custom string-matching validation plugins entirely. Instead, developers should rely on native Abstract Syntax Tree (AST) validation rules. Implementing the NoSchemaIntrospectionCustomRule provided by the standard graphql package ensures that introspection requests are blocked safely regardless of request formatting or whitespace encoding.
For immediate network-level mitigation, Web Application Firewalls (WAF) can be configured to inspect payloads destined for /graphql. Rules should match the regular expressions __schema or __type on any unauthenticated requests. Security Operations Centers should also monitor application logs for unhandled TypeError exceptions associated with the GraphQL plugin.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
opencti Citeum | < 6.1.9 | 6.1.9 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-284 |
| Attack Vector | Network |
| CVSS v3.1 Score | 6.5 |
| EPSS Score | 0.00442 |
| Impact | Partial Confidentiality, Partial Availability |
| Exploit Status | poc |
| KEV Status | Not Listed |
Improper Access Control occurs when software does not restrict or incorrectly restricts access to a resource from an unauthorized actor.
An unrestricted file upload vulnerability in Paymenter's support ticket system (prior to version 1.2.11) allows authenticated users to upload arbitrary PHP scripts to a web-accessible directory. The application fails to validate file extensions or MIME types before storing the files, enabling remote code execution under the web server's privilege context.
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.
A critical vulnerability exists in the stigmem-node package when running the opt-in stigmem-plugin-multi-tenant plugin. Due to a failure to enforce tenant-scoping filters on database queries within the decay sweep, quarantine moderation, and right-to-be-forgotten (RTBF) subsystems, an authorized caller belonging to one tenant can access, modify, and delete facts belonging to all other tenants. This broken object level authorization (BOLA) vulnerability allows cross-tenant data manipulation and information leakage.
An origin validation error and cross-site request forgery vulnerability in @zenalexa/unicli prior to version 0.225.2 allows cross-origin web applications to execute arbitrary tools on a user's local machine via the legacy stateless HTTP transport.
EverOS versions 1.0.0 and earlier contain a path traversal vulnerability in the user memory ingestion endpoint. By exploiting this flaw, unauthenticated network attackers can escape the designated database memory root and write arbitrary Markdown files to target directories on the local system.
GHSA-X975-RGX4-5FH4 is a high-severity Cross-Site Scripting (XSS) vulnerability residing in the Model Context Protocol (MCP) User Interface (UI) component of appium-mcp, an NPM package integrating Appium with MCP clients. The flaw exists within the createLocatorGeneratorUI utility function, which renders UI metadata directly into an HTML template page without performing sanitization or encoding. Because MCP clients use window.parent.postMessage to send commands from the UI to the host, this XSS can be escalated to trigger arbitrary MCP tool calls, potentially leading to Remote Code Execution (RCE) on the host running the MCP client.