diff --git a/data/mcp/mcp_hardcoded_secrets.yaml b/data/mcp/mcp_hardcoded_secrets.yaml new file mode 100644 index 00000000..7d8d5162 --- /dev/null +++ b/data/mcp/mcp_hardcoded_secrets.yaml @@ -0,0 +1,82 @@ +info: + id: "mcp_hardcoded_secrets" + name: "MCP Hardcoded Secrets Detection" + description: "Detect hardcoded credentials, API keys, tokens, and private keys embedded in MCP server source code, which can be exposed if the repository or distribution package is accessible to unauthorized parties." + author: "ATR (Agent Threat Rules)" + categories: + - code + +prompt_template: | + As a professional AI-agent security analyst, precisely detect hardcoded secrets + in MCP server source code. Hardcoded credentials embedded directly in source + files — API keys, access tokens, private keys, passwords — can be extracted by + anyone who gains read access to the repository, package, or running container. + Require concrete evidence of a genuine secret value; only report when the string + matches a known credential pattern with sufficient entropy or format. + + ## Vulnerability Definition + Hardcoded secrets occur when sensitive authentication material — cloud provider + keys (`AKIA…`), API tokens (`sk-…`, `ghp_…`, `xoxb-…`), private keys + (`-----BEGIN … PRIVATE KEY-----`), database passwords, JWT secrets — is + committed directly in source code rather than loaded from environment variables, + a secrets manager, or a properly git-ignored configuration file. + + ## Detection Criteria (require a concrete secret pattern) + + ### 1. Cloud provider credentials + **Code Patterns:** + - AWS access keys: `AKIA[0-9A-Z]{16}`, AWS secret keys assigned as string + literals. + - Azure / GCP keys, service account JSON embedded as a string or object. + - Cloudflare / DigitalOcean / Linode API tokens in assignments. + + ### 2. SaaS API tokens + **Code Patterns:** + - OpenAI / Anthropic / other LLM API keys: `sk-[a-zA-Z0-9]{20,}`, + `sk-ant-…`. + - GitHub tokens: `ghp_[a-zA-Z0-9]{36}`, `gho_…`, `ghs_…`. + - Slack tokens: `xox[baprs]-…`. + - Stripe keys: `sk_live_…`, `rk_live_…`. + - Generic `API_KEY = "…"`, `SECRET_KEY = "…"`, `TOKEN = "…"` assignments + with high-entropy values (>20 chars, mixed case + digits). + + ### 3. Private keys and certificates + **Code Patterns:** + - PEM blocks: `-----BEGIN RSA PRIVATE KEY-----`, `-----BEGIN EC PRIVATE KEY-----`, + `-----BEGIN PRIVATE KEY-----`, `-----BEGIN OPENSSH PRIVATE KEY-----`. + - PGP private key blocks, certificate bundles with private key material. + + ### 4. Database / service passwords + **Code Patterns:** + - Connection strings with embedded passwords: + `mongodb://user:password@host`, `postgres://user:pass@host`. + - Password assignments: `password = "…"`, `DB_PASS = "…"` where the value is + a non-placeholder string (not ``, `your_password`, `changeme`, + `example`, `xxx`). + + ## Strict Judgment Standards + - **Environment variables**: Do not report `os.environ.get('API_KEY')` or + `process.env.API_KEY` — these are correct practices. + - **Placeholders**: Do not report obvious placeholder values (`your_key_here`, + `xxx`, `changeme`, `example`, ``, empty strings). + - **Test fixtures**: Do not report secrets in files under test directories + (`test/`, `__tests__/`, `*_test.*`, `*.spec.*`) that are clearly fake values. + - **Documentation**: Do not report secrets inside comments that serve as + usage examples with placeholder-style values. + - **Low-entropy values**: Do not report short or dictionary-word strings that + do not match any credential format. + + ## Output Requirements + Only output when finding concrete hardcoded secrets: + - Specific file path and line number + - The type of secret (API key, token, private key, password, etc.) + - The redacted value (show only enough to identify the type, e.g. + `AKIA****XXXX`) + - Technical analysis: how the secret could be extracted by an unauthorized party + - Impact assessment: what resources or services the exposed credential grants + access to + - Remediation: move secrets to environment variables or a secrets manager, + rotate the exposed credential, add `.env` to `.gitignore`, use + pre-commit secret scanners. + + **Strict Requirement: provide the file, line number, and secret type with a redacted value. Remain silent when no concrete evidence exists.** diff --git a/data/mcp/mcp_insecure_deserialization.yaml b/data/mcp/mcp_insecure_deserialization.yaml new file mode 100644 index 00000000..20e8dd13 --- /dev/null +++ b/data/mcp/mcp_insecure_deserialization.yaml @@ -0,0 +1,75 @@ +info: + id: "mcp_insecure_deserialization" + name: "MCP Insecure Deserialization Detection" + description: "Detect MCP server tools that deserialize caller-supplied data using unsafe serializers (pickle, marshal, eval-based JSON, yaml.load, unserialize) without validation, enabling remote code execution on the MCP host." + author: "ATR (Agent Threat Rules)" + categories: + - code + +prompt_template: | + As a professional AI-agent security analyst, precisely detect insecure + deserialization vulnerabilities in MCP server tools. The agent (or an upstream + prompt-injection) controls tool arguments; if those arguments are deserialized + using an unsafe serializer, the MCP host can execute attacker-crafted payloads. + Require a concrete argument-to-deserialization-sink path; only report with + evidence. + + ## Vulnerability Definition + An MCP tool handler takes caller-supplied arguments (strings, base64 blobs, or + nested objects) and passes them to a deserializer that can instantiate + arbitrary objects or execute code — `pickle.loads`, `marshal.loads`, + `yaml.load` (unsafe), `unserialize` (PHP), `ObjectInputStream` (Java), + `eval`/`Function()` on JSON-like strings — without type/schema validation. + Because tool arguments are model/attacker-influenced, this is argument-driven + RCE on the MCP host. + + ## Detection Criteria (require tainted argument -> deserialization sink) + + ### 1. Python unsafe deserializers + **Code Patterns:** + - `pickle.loads(args.data)` / `pickle.load(open(args.file))` on + caller-controlled input. + - `marshal.loads(args.data)` / `yaml.load(args.data)` without `Loader=SafeLoader` + / `yaml.unsafe_load()`. + - `dill.loads()` / `shelve.open()` on attacker-influenced data. + - `jsonpickle.decode(args.data)` on caller-controlled input — jsonpickle can + instantiate arbitrary classes via `{"py/object": "..."}` directives, + carrying the same RCE risk as pickle. + + ### 2. JavaScript / dynamic evaluation as deserialization + **Code Patterns:** + - `eval(args.expr)` / `new Function(args.code)` used to parse a structured + argument. + - `vm.runInNewContext(args.script)` / `vm.Script` on caller input. + - `JSON.parse` followed by `eval` of a contained field. + + ### 3. Other language-specific unsafe deserializers + **Code Patterns:** + - PHP `unserialize($args['data'])` without `allowed_classes` restriction. + - Java `ObjectInputStream.readObject()` on caller-controlled bytes. + - .NET `BinaryFormatter.Deserialize()` / `LosFormatter.Deserialize()` on + attacker input. + - Ruby `Marshal.load(args.data)` / `YAML.load` (unsafe) on caller input. + + ## Strict Judgment Standards + - **Safe serializers**: Do not report `json.loads` / `JSON.parse` / + `yaml.safe_load` / `yaml.load(..., Loader=SafeLoader)` — these do not + instantiate arbitrary objects. + - **Trusted data**: Do not report deserialization of server-generated or + statically-defined data with no caller influence. + - **Type-restricted**: Do not report PHP `unserialize` with `allowed_classes: + false` or an explicit allowlist. + - **Test/example**: Do not report sample handlers with hardcoded test payloads. + + ## Output Requirements + Only output when finding a concrete deserialization path: + - Specific file paths and line numbers for the tainted argument and the sink + - The tool parameter name and the exact deserialization call + - Technical analysis: how a crafted payload achieves code execution or object + instantiation + - Impact assessment: RCE scope on the MCP host + - Remediation: use safe serializers (`json`, `yaml.safe_load`), avoid + `eval`/`pickle`/`unserialize` on untrusted data, enforce schema validation, + restrict `allowed_classes`. + + **Strict Requirement: provide the tainted-argument source and the deserialization sink with line numbers. Remain silent when no concrete evidence exists.**