| 1 | rules: |
| 2 | |
| 3 | - id: cyc-py-http-tainted-url |
| 4 | languages: [python] |
| 5 | severity: WARNING |
| 6 | message: > |
| 7 | HTTP client called with a non-literal URL is an SSRF CANDIDATE if the URL/host is |
| 8 | attacker-controlled with no allowlist. IMPACT GATE: Family 7 (metadata cred / internal admin). |
| 9 | Confirm taint in Joern; prioritize flows that can reach 169.254.169.254 / metadata endpoints. |
| 10 | metadata: |
| 11 | cwe: ["CWE-918: Server-Side Request Forgery"] |
| 12 | confidence: MEDIUM |
| 13 | archetype: [ai-agent-mcp, ml-model-loaders, devops-infra] |
| 14 | impact: ssrf |
| 15 | patterns: |
| 16 | - pattern-either: |
| 17 | - pattern: requests.get($U, ...) |
| 18 | - pattern: requests.post($U, ...) |
| 19 | - pattern: requests.put($U, ...) |
| 20 | - pattern: requests.request($M, $U, ...) |
| 21 | - pattern: requests.head($U, ...) |
| 22 | - pattern: urllib.request.urlopen($U, ...) |
| 23 | - pattern: urllib.request.urlretrieve($U, ...) |
| 24 | - pattern: urllib2.urlopen($U, ...) |
| 25 | - pattern: httpx.get($U, ...) |
| 26 | - pattern: httpx.post($U, ...) |
| 27 | - pattern: aiohttp.ClientSession(...).get($U, ...) |
| 28 | - metavariable-pattern: |
| 29 | metavariable: $U |
| 30 | patterns: |
| 31 | - pattern-not: "\"...\"" |
| 32 | - pattern-not: "'...'" |
| 33 | |
| 34 | - id: cyc-js-http-tainted-url |
| 35 | languages: [javascript, typescript] |
| 36 | severity: WARNING |
| 37 | message: > |
| 38 | fetch / axios / http.get with a non-literal URL is an SSRF CANDIDATE. IMPACT GATE: Family 7. |
| 39 | Confirm taint in Joern. |
| 40 | metadata: |
| 41 | cwe: ["CWE-918: Server-Side Request Forgery"] |
| 42 | confidence: MEDIUM |
| 43 | archetype: [ai-agent-mcp, devops-infra, electron-desktop] |
| 44 | impact: ssrf |
| 45 | patterns: |
| 46 | - pattern-either: |
| 47 | - pattern: fetch($U, ...) |
| 48 | - pattern: axios($U, ...) |
| 49 | - pattern: axios.get($U, ...) |
| 50 | - pattern: axios.post($U, ...) |
| 51 | - pattern: axios.request($U, ...) |
| 52 | - pattern: http.get($U, ...) |
| 53 | - pattern: http.request($U, ...) |
| 54 | - pattern: https.get($U, ...) |
| 55 | - pattern: https.request($U, ...) |
| 56 | - pattern: got($U, ...) |
| 57 | - metavariable-pattern: |
| 58 | metavariable: $U |
| 59 | patterns: |
| 60 | - pattern-not: "\"...\"" |
| 61 | - pattern-not: "'...'" |
| 62 | - pattern-not: "`...`" |
| 63 | |
| 64 | - id: cyc-java-http-ssrf |
| 65 | languages: [java] |
| 66 | severity: WARNING |
| 67 | message: > |
| 68 | new URL(...).openConnection / HttpClient.send / RestTemplate / OkHttp with a tainted URL is an |
| 69 | SSRF CANDIDATE. IMPACT GATE: Family 7. Confirm taint in Joern. |
| 70 | metadata: |
| 71 | cwe: ["CWE-918: Server-Side Request Forgery"] |
| 72 | confidence: MEDIUM |
| 73 | archetype: [devops-infra] |
| 74 | impact: ssrf |
| 75 | patterns: |
| 76 | - pattern-either: |
| 77 | - pattern: new URL($U).openConnection() |
| 78 | - pattern: $CLIENT.send($REQ, ...) |
| 79 | - pattern: $RT.getForObject($U, ...) |
| 80 | - pattern: $RT.exchange($U, ...) |
| 81 | |
| 82 | - id: cyc-ssrf-metadata-host-literal |
| 83 | languages: [python, javascript, typescript, java, go] |
| 84 | severity: ERROR |
| 85 | message: > |
| 86 | A cloud metadata / link-local host literal appears in code reachable by a request sink. If |
| 87 | reachable with attacker influence this is the high-value SSRF->credential path. IMPACT GATE: |
| 88 | Family 7 (metadata cred captured). Prioritize for the oracle. |
| 89 | metadata: |
| 90 | cwe: ["CWE-918: Server-Side Request Forgery"] |
| 91 | confidence: LOW |
| 92 | archetype: [ai-agent-mcp, devops-infra] |
| 93 | impact: ssrf-metadata |
| 94 | patterns: |
| 95 | - pattern-regex: "169\\.254\\.169\\.254|metadata\\.google\\.internal|100\\.100\\.100\\.200|169\\.254\\.170\\.2" |