hunt-api-misconfig – Coding skill for AI agents
Hunt API security misconfiguration
Install the hunt-api-misconfig skill with one command
Pick the tool you use, copy the command and paste it in your terminal. The skill lands in that tool's skills folder and is ready in your next session.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-api-misconfig-879d8.tgz | tar xz -C ~/.claude/skills
Call it in Claude Code: /hunt-api-misconfig – then describe the task you want done.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-api-misconfig-879d8.tgz | tar xz -C ~/.codex/skills
Call it in Codex: $hunt-api-misconfig – then describe the task you want done.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-api-misconfig-879d8.tgz | tar xz -C ~/.hermes/skills
Call it in Hermes Agent: /hunt-api-misconfig – then describe the task you want done.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-api-misconfig-879d8.tgz | tar xz -C ~/.deepcode/skills
Call it in DeepSeek: /hunt-api-misconfig – then describe the task you want done.
SKILL.md content
> ⚠️ 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.
12. API SECURITY MISCONFIGURATION
Mass Assignment
User.update(req.body) // body has {"role": "admin"} → privilege escalationJWT None Algorithm
header = {"alg": "none", "typ": "JWT"}
payload = {"sub": 1, "role": "admin"}
# Pseudocode only: JSON-serialize and base64url-encode without padding.
# A token with alg=none is a candidate; correct verifiers reject it.JWT RS256 → HS256 Algorithm Confusion
# 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")
# Only a misconfigured verifier with compatible key handling could accept it;
# modern libraries commonly reject asymmetric keys as HMAC secrets.Prototype Pollution
// Server-side — Node.js merge without protection
{"__proto__": {"admin": true}}
{"constructor": {"prototype": {"admin": true}}}
// URL: ?__proto__[isAdmin]=true&__proto__[role]=superadminFor 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-13373. 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:
Use only the inert polluted marker in a disposable test process; command/job,
role-changing or inspector properties are escalation hypotheses, not default probes.
5. Stop at an inert controlled marker. Prototype state may be process-global and affect other users. Use a disposable isolated process with approved restart/cleanup; never read secrets or trigger shell/inspector gadgets on a shared production process.
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=emailHunt 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 are routing hypotheses, not proof of server-side interpolation; compare controlled fixtures and inspect server behavior.
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/syntheticCanary, 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. Validate a controlled boundary. Use two owner-controlled synthetic accounts and a harmless protected canary field. Do not retrieve another user’s reset token, complete takeover or send reset messages. An error difference alone is not evidence of data access.
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/syntheticCanary%23
username=administrator%2ffield%2fpasswordResetToken%23CORS Exploitation
# Test: reflected origin + credentials
curl -s -I -H "Origin: https://controlled-origin.example" https://target.example/api/user/me
# If: Access-Control-Allow-Origin: https://controlled-origin.example + Access-Control-Allow-Credentials: true
# → Candidate only: browser credentials, SameSite, preflight and readable sensitive body must be demonstrated with controlled identities---
OData authorization and parser-boundary review
OData query options can expose information or consume resources only when the actual
service’s authorization, parser or query-cost controls are inadequate. Do not assume
operator casing/encoding equivalence, a WAF bypass, SQL injection, XXE or a current
CVE from the presence of OData. Dialect/version/provider behavior differs.
Use a tiny owner-approved sandbox with synthetic data:
1. Establish the exact service/version and an authenticated low-privilege identity.
2. Create owned records A/B with a protected synthetic canary field, documented
expected permissions and a reset path. Inspect the service schema as inert data.
3. Compare $select, $filter, $orderby and $expand against expected field AND
related-object authorization. Do not use real password hashes, cards or PII.
4. For example, if A cannot read canary, ordering/filtering by it must not reveal
its value through a repeatable oracle. Document the controlled difference and
rule, not merely a response count.
5. Test at most an approved small batch/nesting depth; bound work per inner operation
and preserve auth per subrequest. A parsing difference alone is not exploitation.
No destructive SQL, blind extraction loop or unlimited expansion is needed for a
minimal report. Review the provider’s current security advisories and original
research before claiming any historical version range, patch date or public case.
OpenAPI / Swagger exposure
Public documentation may be intentional; it is not itself an authentication bypass,
complete inventory or proof that every described operation is deployed. Fetch only
approved bounded spec URLs, validate schema and treat operation descriptions,
external $ref targets, servers and example URLs as untrusted data. Never automatically
feed every path to a scanner, execute “Try it out”, or follow third-party references.
A useful static check is jq '.paths | keys' approved-spec.json on a private local
copy. Then compare a single owned synthetic object across authorized/unauthorized
identities. Privileged writable DTO fields are candidates requiring persisted-state
verification, not proof from a schema name or 200 status. Remote Swagger UI config
loading/version banners require current bundle conf
… (full content is in the download package)
Related skills
- hunt-aspnet – Hunt ASP.NET-specific surface
- spec-to-repo – Use when the user says 'build me an app', 'create a project from this spec', 'scaffold a…
- hunt-shadow-api – Hunt shadow / zombie / undocumented API surface (OWASP API9 Improper Inventory Management)
- spinning-up-deep-rl – Knowledge base from \"Spinning Up in Deep RL\" by Joshua Achiam (OpenAI, MIT-licensed)…
- hunt-source-leak – Hunt source code and build artifact leakage
- hunt-spa-api – Discover a single-page-app's hidden backend API from its public JS bundle, then test…
- hunt-ssti – Hunt server-side template injection (SSTI) across Jinja2 (Flask/Django), Twig (Symfony)…
- hyperexecute-skill – Operates HyperExecute end-to-end for TestMu AI/LambdaTest cloud test execution: analyze…