hunt-oauth

SkillDocs & knowledge

Hunting skill for OAuth 2.0 / 2.1, OpenID Connect (OIDC), SAML SSO, and JWT authentication. Built from 365 public OAuth/SSO bug bounty reports across HackerOne, GitHub Security Advisories, PortSwigger Research, GitHub Security Lab, Detectify, Doyensec, Salt Labs, Semperis, Obsidian Security, Trace37 plus 2024-2026 meta verified against NVD — ruby-saml parser differentials (CVE-2025-25291/25292, GHSL-2024-329/330), Authentik regex redirect_uri (CVE-2024-52289), workers-oauth-provider PKCE downgrade and redirect_uri (CVE-2025-4143/4144), Entra ID actor token cross-tenant impersonation (CVE-2025-55241), Hono JWT alg confusion (CVE-2026-22817), nOAuth omniauth-microsoft_graph (CVE-2024-21632), Tekton git resolver token exfil (CVE-2026-40161), Flux Operator OIDC empty claims (CVE-2026-23990), Argo CD project token (CVE-2025-55190), tinyauth OIDC client binding (CVE-2026-32245). Use when hunting OAuth / OIDC / SAML / JWT / SSO bugs on web apps, mobile apps, single-page apps, MCP servers, agentic LLM tool-use plugins, GitOps controllers, K8s admission, identity providers, federated login, or any place a `redirect_uri`, `state`, `code`, `access_token`, `id_token`, `assertion`, `client_id`, `client_secret`, `code_verifier`, `code_challenge`, `nonce`, `aud`, `iss`, `sub`, `kid`, or `jku` parameter is processed.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the hunt-oauth skill

What this skill tells your AI

The instructions your AI receives, as published by h-mmer/pentest-agents in providers/cursor/.cursor/skills/pentest-agents-hunt-oauth/SKILL.md and read by ahel’s review.

Crown Jewel Targets

OAuth/OIDC/SAML/JWT is the universal entry point to every enterprise account. A single missing state check or loose redirect_uri regex turns into a one-click ATO and the program rates it Critical because the impact is multiplicative — once you ride someone's session, you have all their data, all their integrations, all their tokens. The 24-month meta has shifted decisively toward six asset types. All CVEs below verify against NVD.

1. MCP servers and agentic LLM OAuth (the new gold rush, 2025-2026 meta). Model Context Protocol servers exploded in adoption with broken OAuth implementations. CVE-2025-4143 (Cloudflare workers-oauth-provider missing redirect_uri validation, fixed v0.0.5) and CVE-2025-4144 (PKCE downgrade in same library) define the opening salvo. Obsidian Security's Square MCP one-click ATO (July-September 2025 disclosures, fixed late September 2025) showed anonymous-cookie injection chained with IdP consent caching. CVE-2025-6514 (mcp-remote OS command exec via crafted authorization_endpoint URL, 558,846 downloads affected, JFrog disclosure) and CVE-2025-49596 (Anthropic MCP Inspector unauth RCE, 38K weekly downloads). FastMCP OAuth Proxy missing resource validation (GHSA-5h2m-4q8j-pqpj) means tokens issued for one MCP server work against any MCP server sharing the same authorization server. Hunt MCP servers first — every developer is wiring up OAuth for the first time and getting it wrong.

2. SAML on enterprise SSO (parser-differential renaissance). CVE-2025-25291 + CVE-2025-25292 (ruby-saml signature wrapping via REXML/Nokogiri parser differential, ahacker1 + Peter Stöckli, GHSL-2024-329 + GHSL-2024-330, GitHub Security Lab) opened a critical hole in any Ruby app using SAML — including unauthenticated admin access to GitLab Enterprise as demonstrated by Gareth Heyes and Zakhar Fedotkin in PortSwigger's "SAML Roulette" research (March 2025). CVE-2025-46572 (passport-wsfed-saml2 SAML signature wrapping, Auth0/Okta), CVE-2025-47949 (samlify SAML signature wrapping, npm samlify < 2.10.0), CVE-2024-45409 (ruby-saml ahacker1 baseline). Pair this with Admidio SAML (GHSA-p9w9-87c8-m235 ACS URL injection, GHSA-25cw-98hg-g3cg signature validation result discarded — both 2026, high severity). Old SAML libraries on enterprise SSO are paying again.

3. JWT algorithm confusion (the regression class). CVE-2026-22817 (Hono JWT middleware RS256→HS256 confusion, CVSS 8.2, Cloudflare Workers/Deno/Bun ecosystem, fixed 4.11.4), CVE-2026-22818 (Hono JWK middleware untrusted header.alg fallback when JWK lacks alg, GHSA-3vhc-576x-3qv4), CVE-2024-54150 (cjwt C library RS/EC/PS algorithm confusion, fixed 2.3.0), CVE-2024-37568 (Authlib HMAC verification with asymmetric public key, milliesolem disclosure), CVE-2025-61152 (python-jose alg=none, disputed but real on verify_signature: False configurations). Every JWT library that doesn't pin algorithms is exploitable. Greppable in 30 seconds with jwt.verify(token, secret) patterns.

4. nOAuth and Entra ID identity confusion (Microsoft pays directly). CVE-2024-21632 (omniauth-microsoft_graph nOAuth, GHSA-5g66-628f-7cvj, fixed 2.0.0) is the canonical disclosed example of Descope's June 2023 nOAuth research — apps trusting the email claim from Entra ID get cross-tenant ATO. Semperis found 9% of Entra Gallery apps still vulnerable in June 2025; estimated 15,000+ SaaS apps still exposed. Descope earned $75K+ in coordinated bounties for the original nOAuth class. CVE-2025-55241 (Dirk-jan Mollema, Entra ID actor token cross-tenant Global Admin impersonation, CVSS 10.0, fixed July 17 2025) extended the class to Microsoft itself — any free Entra tenant could impersonate any user in any other tenant via the legacy Azure AD Graph API not validating the actort token's originating tenant. Hunt every "Sign in with Microsoft" button by registering a free Entra tenant and changing your email.

5. Authorization server implementations on managed identity platforms. CVE-2024-52289 (Authentik OAuth2 regex redirect_uri bypass via unescaped ., Lukas Omegapoint disclosure, fixed 2024.10.3 / 2024.8.5, GHSA-3q5w-6m3x-64gj), CVE-2024-23647 (Authentik PKCE downgrade by removing code_challenge, fixed 2023.10.7), CVE-2023-48228 (Authentik PKCE bypass by omitting code_verifier), CVE-2024-22258 (Spring Authorization Server PKCE downgrade for Confidential Clients, fixed 1.2.3 / 1.1.6 / 1.0.6), CVE-2026-32245 (tinyauth OIDC code not bound to client on token exchange, GHSA-xg2q-62g2-cvcm). These pay because deploying Keycloak/Authentik/Hydra/Auth0/Spring Auth Server is what every mid-size company does — find one bug, hit thousands of downstream apps.

6. GitOps controllers and Kubernetes OIDC. CVE-2025-55190 (Argo CD project API token retrieves repository credentials, CVSS 7.7, GHSA-786q-9hcg-v9ff, fixed 3.1.2/3.0.14/2.14.16/2.13.9), CVE-2026-23990 (Flux Operator Web UI impersonation bypass via empty OIDC claims, fixed 0.40.0, GHSA-4xh5-jcj2-ch8q), CVE-2026-40161 (Tekton git resolver leaks system Git API token to user-controlled serverURL, CVSS 8.4, GHSA-wjxp-xrpv-xpff). These pay the highest because compromising the GitOps controller gives you cluster-wide admin and supply-chain RCE in one chain.

7. The OAuth/SSO supply-chain — Salesloft Drift class. UNC6395 / ShinyHunters used stolen Drift OAuth tokens to exfiltrate 1.5 billion Salesforce records from 760 companies (August 2025). The pivot was: GitHub repo compromise → AWS access → Drift OAuth refresh tokens → Salesforce + Google Workspace. Cloudflare alone had 104 API tokens leaked through Salesforce support cases. Bug bounty correlate: hunt for third-party OAuth integrations with overscoped tokens and no rotation policy. Programs paying for SaaS connector misconfiguration include Atlassian, Notion, Slack, Asana, Monday — all tracked under their respective HackerOne programs.

What pays the most: pre-auth, no user interaction, single click → ATO. Reddit one-click ATO via Sign-in-with-Apple paid Frans Rosén $10,000 (Detectify 2022, HackerOne Reddit program, disclosed at https://infosecwriteups.com/this-is-how-he-could-hijack-reddit-accounts-with-just-one-click-a-10-000-bug-bounty-7fd8d54d5582, replicated pattern still pays mid-2026 on smaller programs). Anmol Singh Yadav's race-condition OAuth token mint paid $8,500 P1 in 2025 on a Fortune 500 cloud platform — disclosed via InfoSec Write-ups https://infosecwriteups.com/how-i-hijacked-oauth-tokens-through-a-parallel-auth-flow-race-condition-8500-p1-bug-bounty-7af1cccc4d4c. Open redirect → OAuth ATO chain consistently reaches $5K-$15K range when escalating from a "Low" standalone open redirect (DEV.to lucky_lonerusher 2026 disclosed $15K bug bounty program payout https://dev.to/lucky_lonerusher/open-redirect-to-account-takeover-the-exploit-chain-most-hunters-miss-in-2026-3j1g). Vercel's WAF-bypass H1 program pays separately for bypasses against React Server Components endpoints (CVE-2025-66478 / CVE-2025-55182). On GitHub Security Lab: ruby-saml ahacker1 + Peter Stöckli engagement was a paid private bug bounty engagement (amount undisclosed, but classed as "blockbuster" by GitHub). Standalone "missing state parameter on /oauth/callback" pays $200-$2K depending on chainability per disclosed HackerOne corpus pattern — never submit it alone.

Attack Surface Signals

Greppable / fingerprintable / scannable. Every signal below is tied to a specific product class and the resulting CVE candidate.

HTTP-level signals on a live target:

  • Set-Cookie: oauth2_state=, oauth_state=, __Host-state= → custom OAuth client → state CSRF candidate, test removal/replay
  • redirect_uri=https%3A%2F%2F in any 302 Location response → redirect_uri validation candidate (test substring/path/userinfo bypasses)
  • ?state=, ?code=, &code=, #access_token=, #id_token= in URL → OAuth callback page — audit for third-party JS leakage (dirty dancing)
  • WWW-Authenticate: Bearer realm="MCP" or Bearer realm="..."OAuth Resource Server / MCP server — fingerprint via RFC 9728 metadata at /.well-known/oauth-protected-resource
  • WWW-Authenticate: ... resource_metadata="..."MCP 2025-11-25 spec compliant server — discover OAuth flow; test PKCE downgrade and audience confusion
  • Server: nginx-openid-connect, nginx-auth-request, oauth2-proxy/CVE-2025-54576 oauth2-proxy skip_auth_routes query param bypass candidate; CVE-2024-10318 NGINX OIDC nonce session fixation on the nginx-openid-connect family
  • X-Forwarded-User, X-Auth-Request-User, X-Auth-Request-Email, X-Auth-Request-Groups → reverse-proxy auth (oauth2-proxy / Pomerium / authelia / Authentik forward-auth) — try header injection bypass on backend
  • 500/400 errors with goauthentik, Authentik, pyAuth in body → Authentik — CVE-2024-52289 / CVE-2024-23647 / CVE-2023-48228 candidate
  • X-Powered-By: Express, Set-Cookie: connect.sid plus /oauth2/authorize → Node OAuth provider — Hono / Passport.js JWT confusion candidate (CVE-2026-22817 / CVE-2025-46572)
  • 302 from /login / /sso to /saml/sso/, /saml2/idp/SSOService, /idp/profile/SAML2/Redirect/SSO, /Shibboleth.sso/SAML SP — try ruby-saml CVE-2025-25291/25292 parser differential payload
  • wsfed, WS-Federation, passport-wsfed-saml2 in JS or HTML → CVE-2025-46572 candidate
  • kid header in JWT, especially numeric or path-like (../keys/admin) → kid SQLi / path traversal / command injection (Hacking JWT Tokens corpus references)
  • jku header in JWT pointing to attacker-influenceable URL → jku claim misuse — if JWKS URL not pinned, redirect to attacker JWKS
  • iss claim in JWT mismatching the actual issuer endpoint → CVE-2026-23552 cross-realm Keycloak token acceptance candidate
  • aud missing or aud=null in JWT → CVE-2025-27370 / CVE-2025-27371 OpenID Federation audience injection candidate; also CVE-2024-32687 Argo CD aud bypass family
  • Content-Type: application/x-www-form-urlencoded on /oauth/token → standard token endpoint; test code reuse, race condition (Anmol's $8500 finding pattern)
  • application/jwk+json, application/jose+json, application/jwt → JWE/JWS endpoints; test alg=none, alg=dir
  • Sec-Fetch-Dest: iframe allowed on /oauth/authorize (no X-Frame-Options: DENY, no Content-Security-Policy: frame-ancestors) → clickjacking on consent screen (Hacker One #3287060 WakaTime Double Clickjacking 2025) and PKCE bypass via attacker-iframe (trace37 2026)

JS / DOM signals (audit OAuth consent and callback pages for third-party scripts — Frans Rosén dirty-dancing):

  • <script src="https://www.googletagmanager.com/gtm.js", analytics.js, gtag.js on any page reachable in the OAuth flow → GTM/Analytics URL leaklocation.href containing code= or access_token= is sent to third party; combine with response_type switching
  • window.opener.postMessage(, window.parent.postMessage( without explicit origin (* or no second arg) → postMessage origin check missing — exfil OAuth artifact via cross-origin window
  • <iframe src="https://chat.example.com/..."> chat widget on OAuth pages → chat-widget postMessage gadget (Detectify case study)
  • <script src="https://*.fullstory.com/, *.hotjar.com/, *.intercom.io/, *.drift.com/, *.salesloft.com/ on OAuth callback → session-replay tool URL exfil + supply-chain risk (Salesloft Drift August 2025)
  • react-server-dom-webpack, react-server-dom-parcel, react-server-dom-turbopack in package.json or bundles + OAuth callback → CVE-2025-66478 / CVE-2025-55182 React2Shell on the OAuth callback handler (RCE on backend)
  • localStorage.getItem("access_token"), localStorage.setItem("oauth_token", sessionStorage["jwt"] in JS → token in webstorage — XSS becomes ATO

Source-code signals (ripgrep one-liners — see Source Review for the full set):

# Missing state validation
rg -n 'oauth.*callback|/auth/callback|/oauth/callback' --type js --type py --type rb --type go --type java | rg -v 'state'

# alg accepted from token header (algorithm confusion)
rg -n 'jwt\.(decode|verify)\([^,)]+\)' --type js --type py --type ts -g '!*test*'
rg -n 'jwt\.decode\([^,]+,\s*verify=False' --type py

# OAuth client_secret exposed in frontend
rg -n 'REACT_APP_.*SECRET|VITE_.*SECRET|NEXT_PUBLIC_.*SECRET|client_secret\s*[:=]\s*["\x27]' \
   -g 'package.json' -g '*.env*' -g 'src/**/*.{js,jsx,ts,tsx}'

# email used as user identifier (nOAuth pattern)
rg -n 'user.*\.email|claims\.email|userInfo\.email|profile\.email|id_token\.email' \
   --type js --type py --type rb --type go -g '!*test*' | rg 'find|create|update|merge|upsert|getOrCreate'

# OAuth callback writing token to URL fragment
rg -n 'response_type=[^"]*token|response_mode=fragment|window\.location\.hash.*token' \
   --type js --type ts

# redirect_uri validation by substring/regex (instead of exact match)
rg -n 'redirect_uri.*\.(startsWith|contains|matches|test|search|indexOf)' --type js --type ts --type py
rg -n 'redirect_uri\s*[=~][^=]*regex|RegExp.*redirect' --type js --type rb --type py

Insertion Point Taxonomy

Every place attacker-controlled data flows into OAuth/OIDC/SAML/JWT processing — your hunting checklist:

  • URL queryclient_id, redirect_uri, response_type, response_mode, scope, state, nonce, code_challenge, code_challenge_method, prompt, display, id_token_hint, login_hint, acr_values, resource (RFC 8707), audience. Example: append &response_type=token id_token to a code-flow auth URL → Detectify dirty-dancing fragment leak.
  • URL fragment#access_token=, #id_token=, #code= from implicit flow or response_mode=fragment. JS on the callback page reads location.hash; if any third-party script also reads it → leak.
  • HeadersAuthorization: Bearer, Authorization: DPoP, X-Forwarded-User, X-Auth-Request-Email, custom OIDC headers from reverse proxy. Try header injection at the backend after a reverse-proxy strips them. Also Origin: for CORS bypass on OAuth endpoints (Grab partner-api H1 #3631550 — null Origin reflected with credentials).
  • Body (form-urlencoded)/oauth/token body parameters: grant_type, code, code_verifier, client_id, client_secret, refresh_token, redirect_uri, subject_token, subject_token_type, actor_token (RFC 8693 token exchange). PKCE downgrade → drop code_verifier. Race condition → Turbo Intruder 2 parallel exchanges with same code.
  • Body (JSON) — Dynamic Client Registration body: client_name, redirect_uris, grant_types, token_endpoint_auth_method, jwks, jwks_uri, software_statement. SSRF via jwks_uri pointing to internal IPs; supply-chain via redirect_uris: ["http://attacker"].
  • Body (XML / SAML)<samlp:AuthnRequest> with attacker-controlled AssertionConsumerServiceURL (Admidio GHSA-p9w9-87c8-m235); <saml:Assertion> with signature wrapping (CVE-2025-25291). RelayState parameter (Lukas Omegapoint #2263044 user_saml).
  • Cookiesoauth2_proxy_csrf, __oauth_session, __Host-flow_state, XSRF-TOKEN for OAuth client. Anonymous-cookie injection via subdomain takeover (Obsidian Square MCP attack chain). Session fixation via cookie set before login.
  • JWT claims (mutable + verifiable both matter) — sub, email (nOAuth — never trust), email_verified, preferred_username, upn, iss, aud, azp, nonce, at_hash, c_hash, acr, amr, exp, nbf, actort (CVE-2025-55241 Entra ID), kid, jku, x5u, x5c. Always test aud removal and iss swap.
  • JWKS / metadata documentsjwks_uri points to https://attacker.example/.well-known/jwks.json; CIMD client_id as URL pointing to attacker-controlled JSON document (oauth-wg/draft-ietf-oauth-client-id-metadata-document #30 — server fetches arbitrary URL).
  • WebSocket / SSE auth — JWT in subprotocol, query string, or first JSON message after upgrade. Often skipped by middleware that only checks initial HTTP handshake.
  • Mobile custom URL schemescom.example.app://oauth/callback registered as Android <intent-filter> or iOS URL Type. Malicious app on same device registers same scheme → intercepts code (Doyensec OAuth Common Vulnerabilities, January 2025). Universal Links / App Links not always mandatory, especially on legacy code.
  • Background / async paths — refresh token endpoint, token introspection (/introspect), token revocation (/revoke), userinfo (/userinfo), end_session_endpoint (RP-initiated logout). post_logout_redirect_uri is the open-redirect cousin everyone forgets — test it.
  • Indirect / agentic — MCP tool descriptions injected with prompt-injection payloads (Invariant Labs GitHub MCP, May 2025); Salesforce/HubSpot/Zendesk support-case bodies that an OAuth-connected automation reads (Salesloft Drift August 2025); LangChain RAG context that the agent treats as tool instructions.

Step-by-Step Hunting Methodology

  1. Map the OAuth flow with Burp. Log into the application, watch every request to /oauth/, /auth/, /saml/, /sso/, /.well-known/, /connect/, /oidc/. Record client_id, redirect_uri, response_type, response_mode, state, nonce, code_challenge, code_challenge_method. If state is missing → test CSRF immediately. If code_challenge is missing on a public client → flag PKCE absence (CVE-2024-23647 family). If you see SAML, capture both <AuthnRequest> and <Response> bodies — these go to the SAML wrapping tests later.

  2. Fingerprint the authorization server. Hit /.well-known/openid-configuration, /.well-known/oauth-authorization-server, /.well-known/oauth-protected-resource, /oauth/authorize, /oauth/.well-known/jwks.json, /saml/metadata, /.well-known/saml-configuration. The software field, issuer, supported grant types (look for password ROPC, client_credentials, urn:ietf:params:oauth:grant-type:token-exchange), token_endpoint_auth_methods_supported, code_challenge_methods_supported — all of these reveal the AS implementation. Authentik metadata leaks goauthentik strings; Keycloak leaks realm-shaped paths; Auth0 leaks *.auth0.com; Cognito has the cognito-idp.<region>.amazonaws.com issuer. If you see password in grant_types_supported and the AS is internet-exposed → ROPC credential spray (Grab H1 #3635703 concedoidc).

  3. Test redirect_uri validation — the 12 bypass families. Send the original auth request to Burp Repeater. Mutate redirect_uri through this sequence: (a) substring https://target.com.attacker.com; (b) userinfo https://attacker.com@target.com; (c) IDN https://tаrget.com (Cyrillic а); (d) path traversal https://target.com/callback/../../../@attacker.com; (e) URL encoding https%3A%2F%2Fattacker.com; (f) double encoding https%253A%252F%252Fattacker.com; (g) fragment https://target.com/callback#@attacker.com; (h) localhost http://127.0.0.1:80@attacker.com; (i) IPv6 http://[::1]@[::1]@attacker.com (Google bypass per @weirdmachine 2025); (j) regex unescaped dot https://app0example.com/oauth2/callback (CVE-2024-52289 Authentik); (k) wildcard subdomain takeover; (l) any open redirect on the same domain with ?next=https://attacker.com. If any returns 302 to your destination with code= or access_token= → critical, but verify the code is bound to a real victim before reporting (deliver via iframe to admin user, never to yourself).

  4. Break the state parameter intentionally (Frans Rosén dirty dancing). With a Burp-modified flow, switch response_type=code to response_type=code,id_token or response_type=token. Switch response_mode=query to response_mode=fragment or response_mode=form_post. Send your tainted state to a victim — if the victim's browser completes the flow but the website rejects state, the code lands at the OAuth provider but is never consumed. The window between code issuance and expiry is yours to use. Then audit every page reachable in the OAuth dance for third-party JS (GTM, analytics, chat widgets, session replay). Any postMessage listener with no origin check, any location.href read by a third-party, any target=_blank link with no rel=noopener — these become the leak gadget.

  5. PKCE downgrade testing — three variants. Variant 1: drop code_verifier from /oauth/token body — CVE-2023-48228 Authentik. Variant 2: drop code_challenge from the initial authorization request — CVE-2024-23647 Authentik, Spring Authorization Server CVE-2024-22258 for confidential clients only. Variant 3 (Cloudflare workers-oauth-provider CVE-2025-4144 family): omit PKCE from authorization but include code_verifier in token exchange — fail-open libraries accept it. Variant 4 (trace37 2026): you control the authorization URL via iframe/popup, so you choose the code_challenge and you know the code_verifier — PKCE only protects against in-transit interception, not against initiation control. If iframe-able + auto-login → the PKCE protection collapses; chain with postMessage capture for one-click ATO.

  6. JWT algorithm confusion — three variants. Variant 1: change alg to none, strip signature, send. Variant 2: change alg from RS256 to HS256, sign payload with the public key as HMAC secret using jwt_tool -X k -pk public.pem -p public.pem. Variant 3: change alg to none with case variation nOnE, NoNE, NULL, None (CVE-2026-22817 Hono family). Variant 4 (Hono CVE-2026-22818): if JWKS endpoint returns keys without alg field → middleware falls back to header alg → algorithm confusion. Test with kid injection: kid: ../../../../dev/null (forces empty key → HMAC with empty string), kid: ../../../etc/passwd, kid: 1' UNION SELECT 'attacker_key. Test jku redirect: change jku to attacker JWKS URL with same kid. If aud is empty or missing → cross-service relay (CVE-2025-27370 / CVE-2025-27371 OpenID Federation class); replay tokens from one service against another in the same federation.

  7. SAML signature wrapping and parser differentials. Capture a valid <SAMLResponse> from your own login. Use SAML Raider Burp extension. Variant 1 (XSW10): wrap original <Assertion> in attacker-controlled assertion; copy original <Signature> referencing original; many SPs canonicalize first child only. Variant 2 (CVE-2025-25291 ruby-saml DOCTYPE): inject DOCTYPE <!DOCTYPE x [<!ATTLIST y z 'value'>]> that REXML and Nokogiri parse differently — REXML validates signature on one node, Nokogiri reads attributes from another. Variant 3 (CVE-2025-25292 ruby-saml namespace): redefine xmlns:ds to point at a fake <ds:Signature> Nokogiri reads while REXML reads original. Variant 4 (CVE-2026-22-class missing destination check): use any valid signed assertion from any tenant of the IdP, modify NameID to victim, send (Admidio GHSA-25cw-98hg-g3cg discards validateSignature() return value entirely). Variant 5 (CVE-2025-46572 passport-wsfed-saml2): obtain any single signed SAML assertion from same IdP, replace user identity. If the SP's library is ruby-saml, samlify, passport-wsfed-saml2, python3-saml, php-saml, simplesamlphp, omniauth-saml → version check first; out-of-date is a confirmed crit.

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
908
Forks
169
Last commit
Jun 2026
Advanced
Catalog kind
skill
Gateway key
hunt-oauth-2
Source
github.com/h-mmer/pentest-agents