agentleFS
EndikaEndika/eskills/skills/exploit-hunt/SKILL.md

exploit-hunt

Skill0 starsChanged 56 days agoMITView on GitHub

Use when hunting for actually-exploitable vulnerabilities — reachable, user-controlled paths into a real sink (SSRF, SQLi, command injection, RCE, deserialization, path traversal, XSS), discarding theoretical or local-only noise. Offensive triage, the counterpart to security-bar's defensive checklist.

The file

We split this skill into the rules it gives an agent

1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Treat every table reachable via the anon key as a public, unauthenticated endpoint.

    line 53

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

exploit-hunt

Overview

The offensive counterpart to eskills:security-bar. security-bar asks "is this built right?"; this asks "can an attacker actually reach a sink?". Use it for a deeper, on-demand pass on a codebase — not as a per-task lens. It is not in the default eskills:task-flow quality stage; reach for it when a change touches a real boundary, or when auditing an app end-to-end.

The principle

Unreachable is not a finding. A theoretically-unsafe call that no external input can reach is a note, not a vulnerability. Prove that user-controlled input travels from a real boundary to a meaningful sink — or drop it. Bias hard toward remotely reachable, user-driven paths; throw away the rest.

In scope — prove user control reaches the sink

PatternCWEImpact
SSRF via user-controlled URL918internal network, cloud metadata theft
Auth bypass in middleware / API guards287unauthorized account or data access
Remote deserialization / upload→RCE502code execution
SQL injection in a reachable endpoint89exfiltration, auth bypass, data loss
Command injection in a request handler78code execution
Path traversal in file-serving paths22arbitrary file read/write
Auto-triggered XSS79session/admin compromise
Open RLS / PostgREST direct write reachable with the anon key284/639read/overwrite any row, bypassing the app

Skip these — low signal, drop them

  • Local-only pickle.loads / torch.load / equivalent with no remote path
  • eval() / exec() in CLI-only tooling
  • shell=True on a fully hardcoded command
  • Missing security headers on their own
  • Generic rate-limiting complaints with no exploit impact
  • Self-XSS that needs the victim to paste code manually
  • Demo, example, fixture, vendored, or test-only code

My stack: where the real boundary is

The React/PWA UI is not the boundary. My apps ship the Supabase anon key, so the real attack surface is PostgREST + Edge Functions / RPCs — anything reachable with that key is a public API, regardless of what the UI exposes. So:

  • Treat every table reachable via the anon key as a public, unauthenticated endpoint. A guard that lives only in front-end code does not exist for an attacker (see eskills:security-bar for the RLS / server-side-PIN rules this feeds).
  • The sinks that matter are server-side: an RPC that builds dynamic SQL, an Edge Function that fetches a user-supplied URL (SSRF) or shells out, a storage path built from user input.

Workflow

  1. Map entrypoints — HTTP handlers, RPCs, Edge Functions, upload paths, webhooks, background jobs, parsers, any table exposed through PostgREST.
  2. Trace reachability — follow user-controlled input from the boundary inward.
  3. Find the sink — does that input reach SQL, a shell, a URL fetch, a deserializer, a file path, the DOM?
  4. Prove it — confirm user control reaches the sink with the smallest safe PoC (a single request or curl against PostgREST is usually enough).
  5. Triage tooling as input only — semgrep --config=auto --severity=ERROR --severity=WARNING to seed candidates, then manually drop the unreachable / test / vendored hits.
  6. Hand the candidates to a fresh refuter — I can't refute my own trace: I already believe it. Once the list is final, give it to one new agent on Opus, run in series (not one per finding). Skip this step if there are no candidates. Pass it only each candidate's file:line, boundary, input, sink and PoC — never my hunting notes or my reasoning. Its brief: try to refute each one from the source. Re-read every cited line, look for the control that stops the path (an RLS policy, a missing grant, upstream validation, an auth check), and check that the PoC reaches what it claims. For each candidate it returns confirmed, rejected (with the file:line of the control that stops it) or unproven (with the fact it couldn't establish). I apply its verdicts as returned; if I disagree with one, I show both views instead of overriding it.

Output

Per finding: file:line → reachability (which boundary, which input) → what the attacker achieves → the fix, plus the minimal PoC. State the boundary explicitly — if you can't name how it's reached, it goes in a separate "theoretical / needs-confirmation" list, not the findings. Only candidates the refuter confirmed go in the findings; unproven ones go to the theoretical list with the missing fact, and rejected ones are listed in one line each with the control that stopped them, so a later run doesn't re-raise them. Don't re-report an already-accepted, documented risk.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.