Compiler Explorer
Connects to Compiler Explorer API for listing programming languages, retrieving available compilers, and compiling source code with customizable options, enabling developers to compare compiler behaviors and explore language features without context switching.
0Tools
8Findings
15Stars
Mar 19, 2026Last Scanned
1 critical · 5 high · 1 medium · 1 low findings detected
Security Category Deep Dive
Prompt Injection
Prompt & context manipulation attacks
69
Maturity
14
Rules
5
Sub-Categories
1
Gaps
64%
Implemented
56
Tests
1
Stories
100%3 rules
Injection via tool descriptions and parameter fields
GAP-001Prompt Injection Coverage GapMissing detection coverage for emerging prompt injection attack variants not addressed by current rules
100%4 rules
Hidden instructions via external content and tool responses
100%2 rules
Context window saturation and prior-approval exploitation
100%3 rules
Payload hiding via invisible chars, base64, schema fields
100%2 rules
Injection via prompt templates and runtime tool output
Findings8
1critical
5high
1medium
1low
Critical1
criticalQ13MCP Bridge Package Supply Chain AttackMCP10-supply-chainAML.T0054
Pattern "(?:mcp|fastmcp|langchain-mcp|llama-index-mcp)(?:>=|~=|==)?(?!\d)" matched in source_code: "mcp" (at position 96)
MCP bridge packages (mcp-remote, mcp-proxy, @modelcontextprotocol/sdk, fastmcp) are high-value supply chain targets — CVE-2025-6514 (CVSS 9.6) in mcp-remote affected 437,000+ installs. Always pin exact versions (no ^ or ~ ranges). Use lockfiles (package-lock.json, pnpm-lock.yaml, uv.lock). Never run `npx mcp-remote` without version pinning. Verify package integrity with `npm audit` or `pip-audit` before deployment. Reference: CVE-2025-6514, OWASP ASI04.
High5
highD1Known CVEs in DependenciesMCP08-dependency-vuln
Dependency "mcp@null" has known CVEs:
Update dependencies to versions that patch known CVEs. Run 'npm audit fix' or 'pip-audit' to identify and resolve vulnerable dependencies.
highK13Unsanitized Tool OutputMCP02-tool-poisoningAML.T0054
Pattern "(?:query|execute|select|find).*(?:return|respond|result|rows|data)(?!.*(?:sanitize|escape|encode|map|filter|select|pick))" matched in source_code: "execute: Include execution result" (at position 705)
Sanitize all external data before including in tool responses. Implement output encoding that neutralizes prompt injection patterns. Truncate excessively long content. Validate structure before passing database results. Apply the principle: treat all external data as untrusted, even in tool outputs. Required by CoSAI MCP-T4.
highC3Server-Side Request Forgery (SSRF)MCP04-data-exfiltrationAML.T0057
Pattern "\.(?:get|post|put|delete|patch|request)\s*\([^)]*(?:url|uri|target|endpoint|host)[^)]*(?:req|input|param|args|f['"]|\+)" matched in source_code: ".request(method, url, **kwargs" (at position 2935)
Validate ALL user-supplied URLs before making HTTP requests:
1. Parse the URL and check the hostname against an explicit allowlist of permitted domains.
2. Block requests to RFC 1918 private ranges: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16.
3. Block loopback (127.0.0.0/8), link-local (169.254.0.0/16), and IPv6 equivalents.
4. Block file:// and other non-http(s) protocols explicitly.
5. Disable automatic redirect following, or re-validate each redirect destination.
6. In cloud environments: block requests to IMDS endpoints (169.254.169.254,
metadata.google.internal) at both the application AND network layer.
Example (Node.js): Use the `ssrf-req-filter` package or implement URL validation
against an allowlist before calling fetch/axios/got.
highN3JSON-RPC Request ID CollisionMCP07-insecure-configAML.T0054
Pattern "(?:requestId|request_id|reqId|id)\s*[:=]\s*(?:(?:\+\+|\-\-)|(?:count|counter|sequence|seq|next))" matched in source_code: "id = next" (at position 8172)
Use cryptographically random or UUID-based request IDs to prevent collision attacks. Do not use sequential integers — an attacker can predict the next ID and inject a response before the legitimate server responds (response spoofing). Validate that response IDs match pending request IDs. Reference: JSON-RPC 2.0 Section 4.1 — 'id' must be unique within a session.
highO8Timing-Based Covert ChannelMCP04-data-exfiltrationAML.T0057
Pattern "(?:delay|sleep|timeout|wait)\s*[:=]\s*(?:[^;]*(?:charCodeAt|charAt|bit|byte|\&\s*1|>>|<<|\[i\]))" matched in source_code: "timeout=30.0,
)
async def _make_request(self, method: str, url: str, **kwargs) -> Any:
"""Make HTTP request with error handling.
Args:
method: HTTP method to use (GET, POST, etc.)
url: URL to make the request to
**kwargs: Additional arguments to pass to the request
Returns:
Parsed JSON response from the API
Raises:
CompilerExplorerError: If the request fails or returns invalid JSON
"""
try:
response = await self.client.request(method, url, **kwargs)
response.raise_for_status()
# Ensure we have valid JSON response
try:
return response.json()
except json.JSONDecodeError as e:
print(f"Response content: {response.text}") # Debug log
raise CompilerExplorerError(f"Invalid JSON response: {str(e)}")
except httpx.TimeoutException:
raise CompilerExplorerError("Request timed out")
except httpx.HTTPStatusError as e:
raise CompilerExplorerError(
f"HTTP error occurred: {str(e)}", status_code=e.response.status_code
)
except Exception as e:
raise CompilerExplorerError(f"Unexpected error: {str(e)}")
async def list_languages(self) -> list[dict[str, str]]:
"""Get list of supported programming languages.
Returns:
List of dictionaries containing language information, each with keys:
- id: Unique identifier for the language
- name: Display name of the language
- extensions: List of file extensions associated with the language
Raises:
CompilerExplorerError: If the API request fails
"""
return await self._make_request("GET", f"{self.base_url}/languages")
async def list_compilers(self, language: str | None = None) -> list[dict[str, str]]:
"""Get list of available compilers.
Args:
language: Optional language filter to get compilers for a specific language
Returns:
List of dictionaries containing compiler information, each with keys:
- id: Unique identifier for the compiler
- name: Display name of the compiler
- semver: Version string of the compiler
- language: Programming language the compiler supports
Raises:
CompilerExplorerError: If the API request fails
"""
url = f"{self.base_url}/compilers"
if language:
url += f"/{language}"
return await self._make_request("GET", url)
async def compile_code(
self,
source: str,
compiler: str,
options: str = "",
filters: CompilationFilters = CompilationFilters(),
libraries: list[Library] = [],
) -> dict:
"""Compile code using specified compiler.
Args:
source: Source code to compile
compiler: Compiler ID to use (e.g., 'gcc-12.2')
options: Optional compiler flags and options
filters: Optional configuration for filtering compiler output
libraries: Optional list of library dependencies
Returns:
Dictionary containing compilation results with keys:
- code: Exit code of the compilation
- stdout: Standard output from the compiler
- stderr: Standard error from the compiler
- asm: Generated assembly (if applicable)
Raises:
CompilerExplorerError: If compilation fails or API request fails
"""
data = {
"source": source,
"options": {
"userArguments": options or "",
"filters": filters.dict() if filters else CompilationFilters().dict(),
"libraries": [lib.dict() for lib in libraries] if libraries else [],
},
}
return await self._make_request(
"POST", f"{self.base_url}/compiler/{compiler}/compile", json=data
)
async def get_opcode_documentation(self, instruction_set: str, opcode: str) -> dict:
"""Get documentation for a specific opcode in a given instruction set.
Args:
instruction_set: Instruction set to search for opcode documentation
opcode: Opcode to search for documentation
"""
return await self._make_request(
"GET", f"{self.base_url}/asm/{instruction_set}/{opcode}"
)
def get_unversioned_compiler_name(compiler_name: str, semver: str) -> str:
"""Get the unversioned compiler name from the versioned name.
Args:
compiler_name: Full compiler name including version
semver: Version string to remove
Returns:
Cleaned compiler name without version information
Example:
>>> get_unversioned_compiler_name("gcc-12.2", "12.2")
"gcc"
"""
return (
compiler_name.replace(semver, "").replace("none", "").replace("()", "").strip()
)
def infer_compiler_id(
compiler_name_or_id: str, compilers: list[dict[str, str]]
) -> str | None:
"""Infer the compiler ID from a name or ID string.
Args:
compiler_name_or_id: Either a compiler ID or name to match
compilers: List of available compilers from the API
Returns:
Matching compiler ID if found, None otherwise
Example:
>>> compilers = [{"id": "gcc-12.2", "name": "GCC 12.2"}]
>>> infer_compiler_id("gcc", compilers)
"gcc-12.2"
"""
if compiler_name_or_id in [c["id"] for c in compilers]:
compiler_id = compiler_name_or_id
else:
# Get the compiler ID from the name
compiler_id = next(
(
c["id"]
for c in compilers
if c["name"].lower().strip() == compiler_name_or_id.lower().strip()
),
None,
)
return compiler_id
# Create an MCP server
mcp = FastMCP("Compiler Explorer Bridge")
ce_client = CompilerExplorerClient()
@mcp.tool()
async def list_languages() -> list[dict[str, str]]:
"""Get a list of supported programming languages.
Returns:
List of dictionaries containing language information, each with keys:
- id: Unique identifier for the language
- name: Display name of the language
- extensions: List of file extensions associated with the language
Raises:
HTTPException: If the API request fails
"""
try:
return await ce_client.list_languages()
except CompilerExplorerError as e:
raise HTTPException(status_code=e.status_code, detail=str(e))
# @mcp.tool()
# async def list_compilers() -> List[str]:
# """Get available compilers for a language"""
# try:
# compilers = await ce_client.list_compilers()
# return list(
# {get_unversioned_compiler_name(c["name"], c["semver"]) for c in compilers}
# )
# except CompilerExplorerError as e:
# raise HTTPException(status_code=e.status_code, detail=str(e))
@mcp.tool()
async def list_compilers_for_language(language: str) -> list[str]:
"""Get available compilers for a specific programming language.
Args:
language: Programming language to get compilers for (e.g., 'cpp', 'rust')
Returns:
List of unversioned compiler names available for the language
Raises:
HTTPException: If the API request fails
Example:
>>> await list_compilers_for_language("cpp")
["gcc", "clang", "msvc"]
"""
try:
compilers = await ce_client.list_compilers(language)
return list(
{get_unversioned_compiler_name(c["name"], c["semver"]) for c in compilers}
)
except CompilerExplorerError as e:
raise HTTPException(status_code=e.status_code, detail=str(e))
@mcp.tool()
async def list_compiler_versions(compiler_regex: str) -> list[dict[str, str]]:
"""Get available compiler versions matching a compiler name regex.
NOTE: This may return a lot of results! Choose a specific regex to narrow down the results and not overflow the MCP client.
Args:
compiler_regex: Regular expression to match compiler names (case-insensitive)
Returns:
List of dictionaries containing matching compiler information, each with keys:
- id: Unique identifier for the compiler
- name: Display name of the compiler
- semver: Version string of the compiler
Raises:
HTTPException: If the API request fails
Example:
>>> await list_compiler_versions("gcc")
[{"id": "gcc-12.2", "name": "GCC 12.2"}, {"id": "gcc-11.3", "name": "GCC 11.3"}]
>>> await list_compiler_versions("clang.*trunk")
[..., {"id": "irclangtrunk", "name": "clang (trunk)", "lang": "llvm", "compilerType": "", "semver": "(trunk)", "instructionSet": "amd64"}, ...]
"""
compilers = await ce_client.list_compilers()
return [
c
for c in compilers
if re.search(compiler_regex, c["name"], re.IGNORECASE)
or re.search(compiler_regex, c["id"], re.IGNORECASE)
]
@mcp.tool()
async def compile_code(
source: str,
language: str,
compiler: str,
ctx: Context,
options: str = "",
filters: CompilationFilters = CompilationFilters(),
libraries: list[Library] = [],
) -> dict:
"""Compile source code using specified compiler and options.
Args:
source: Source code to compile
language: Programming language of the source code
compiler: Compiler name or ID to use
ctx: MCP context for logging and error reporting
options: Compiler flags and options
filters: Configuration for filtering compiler output
libraries: List of library dependencies
Returns:
Dictionary containing compilation results with keys:
- code: Exit code of the compilation
- stdout: Standard output from the compiler
- stderr: Standard error from the compiler
- asm: Generated assembly (if applicable)
Raises:
HTTPException: If compilation fails, compiler not found, or API request fails
Example:
>>>" (at position 2377)
Remove all code that calculates sleep/delay durations from application data, secrets, or any variable-length content. Tool response times should be constant or determined only by legitimate processing time. If rate limiting is needed, use fixed intervals not derived from data values. Monitor for anomalous response time patterns that could indicate timing-based exfiltration.
Medium1
mediumK17Missing Timeout or Circuit BreakerMCP07-insecure-configAML.T0054
Pattern "(?:fetch|axios|got|request|urllib|httpx|http\.get|http\.post)\s*\((?!.*(?:timeout|signal|AbortSignal|deadline|cancel))" matched in source_code: "request(" (at position 2422)
Add timeouts to ALL external calls: HTTP requests (30s), database queries (10s), subprocess execution (60s), and MCP tool calls (30s). Implement circuit breakers that open after N consecutive failures (e.g., opossum, cockatiel). Use AbortSignal for cancellable operations. Required by EU AI Act Art. 15 and OWASP ASI08.
Low1
lowF4MCP Spec Non-ComplianceMCP07-insecure-config
Server fails MCP spec compliance checks: required:server_name; required:server_version; required:protocol_version; recommended:tool_descriptions; recommended:parameter_descriptions
Follow the MCP specification for server metadata. Include server name, version, and protocol version. Provide descriptions for all tools and parameters.