Whistlelink: Site-access password exposed in web server access logs via GET query string
Full Disclosure mailing list archives
Whistlelink: Site-access password exposed in web server access logs via GET query string
From: Red Nanaki via Fulldisclosure <fulldisclosure () seclists org>
Date: Sun, 21 Jun 2026 09:44:34 +0000
Whistlelink: Site-access password exposed in web server access logs via GET query string Severity: CRITICAL SUMMARY The Whistlelink reporting portal protects optionally-enabled, password-gated whistleblowing sites with a site-access password. When a visitor unlocks such a site, the client validates the password by issuing an HTTP GET request that carries the password as a URL query-string parameter: GET /sys/api/v1.0/wl/publish_site/check_password?password= The value is only Base64-encoded (js-base64), which is a reversible transport encoding, not encryption or hashing. Because the secret travels in the request line / URI, it is written verbatim into the front-end web server's access log (the deployment fronts the application with nginx, which logs the full request URI by default) on every unlock attempt, and is similarly retained by any reverse proxy, load balancer, WAF, CDN, observability / log-aggregation pipeline, log backup, and the user's browser history. Anyone able to read those logs can trivially Base64-decode the value and recover the cleartext site-access password, defeating the access control for the entire protected whistleblowing site. For a whistleblowing platform - where the confidentiality of who may reach the reporting channel is a primary protection goal - this is treated as CRITICAL. CVSS CVSS v3.1 Base: 7.7 (High) CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N CVSS v3.1 Environmental (whistleblowing asset, Confidentiality Requirement High): 9.8 (Critical) CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N/CR:H CVSS v4.0: High CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:L/SI:N/SA:N The operative rating for this product class is the environmental score: the protected asset is a whistleblowing channel whose access confidentiality is paramount (potential whistleblower-safety consequences), justifying CR:H, which raises the score to 9.8 / Critical and the CRITICAL tag. Metric justification (v3.1 Base): - Attack Vector: Network. Access logs are routinely centralized to network-reachable systems (log/observability platforms, off-host backups, object storage). If logs are only local files, AV:L applies and the Base score drops to ~6. - Attack Complexity: Low. The secret is present, in recoverable form, in every check_password log line; decoding Base64 is trivial. - Privileges Required: Low. Reading the logs requires some access to logging / operations infrastructure - a materially lower and broader-trust bar than knowing the site password itself. If logs are exposed to an unauthenticated party (e.g. a misconfigured log bucket), PR:N applies and Base ~ 8.6. - User Interaction: None. No victim interaction needed to read the stored value. - Scope: Changed. The vulnerable component (the web application) writes the secret into a separate security authority (the host / log subsystem), and the impact lands on the protected site and its users. - Confidentiality: High. Full disclosure of the site-access credential (and, where reused, the underlying password), granting access to the protected whistleblowing site. - Integrity / Availability: None. The flaw discloses data; it does not directly modify or deny service. Score derivation (v3.1): - ISCBase = 1 - (1 - 0.56) = 0.56 - Impact (Scope Changed) = 7.52 x (0.56 - 0.029) - 3.25 x (0.56 - 0.02)^15 ~ 3.99 - Exploitability = 8.22 x 0.85 (AV) x 0.77 (AC) x 0.68 (PR, scope-changed) x 0.85 (UI) ~ 3.11 - Base = Roundup(min(1.08 x (3.99 + 3.11), 10)) = Roundup(7.67) = 7.7 (High) - Environmental with CR:H: MISC = min(1 - (1 - 0.56 x 1.5), 0.915) = 0.84 -> Modified Impact ~ 5.93 -> Roundup(min(1.08 x (5.93 + 3.11), 10)) = 9.8 (Critical) COMPONENT backend (API endpoint design) / packaging (web server logging configuration) FOUND BY Passive HAR traffic audit + static analysis of the published client bundle. AFFECTED ENDPOINT GET /sys/api/v1.0/wl/publish_site/check_password?password= Client request construction (published JS bundle, de-minified): // password validation service checkPassword: function (t) { return C.a.get("".concat(T, "/check_password"), { params: { password: t } }); } // caller - submit handler of the password gate submit: function () { // ... cs.checkPassword(ds["a"].encode(this.password)).then(function (e) { if (e.data.data) { localStorage["authtoken"] = ds["a"].encode(this.password); // reversible Base64, also reused as the Auth header // route into the protected site } }); } ds is js-base64 v3.7.8 (standard alphabet A-Za-z0-9+/=), so ds.a.encode(password) is plain, reversible Base64 - not a hash and not encryption. DETAILS Two distinct defects combine: 1. CWE-598 - Sensitive information transmitted in a GET request query string. The site-access password is sent as the "password" query parameter rather than in a request body. URLs / query strings are persisted far more widely than request bodies: front-end web server access logs (nginx logs the full request URI by default), reverse proxies, load balancers, WAFs, CDNs, log-aggregation / observability pipelines, log backups, and the local browser history. Even over TLS, the value is recorded in cleartext at these endpoints. 2. CWE-261 / CWE-312 - Weak (reversible) encoding of a credential. The value is only Base64-encoded. Base64 provides no confidentiality; anyone reading a log line recovers the cleartext password by decoding it. The same reversible token is also placed in localStorage and replayed as the Auth header on every request, broadening exposure. The combined result (CWE-532 - Insertion of Sensitive Information into Log File): the cleartext site-access password is durably stored, in recoverable form, in web server access logs on every unlock attempt. The password is a single shared secret gating the whole protected site, so a single log read defeats the access control for all visitors. IMPACT - Disclosure of the site-access credential to any party with read access to web server / proxy / aggregated logs or their backups - a broader and lower-trust population than those authorized to access the protected site (operations staff, log-platform users, backup holders, third-party log processors, or an attacker who obtains logs via a separate flaw). - Complete bypass of the password gate for the protected whistleblowing site, exposing the existence, configuration, and reporting channel that the password was meant to keep confidential. - Credential-reuse blast radius: if the configured site password is reused elsewhere (common for shared, human-chosen site passwords), the impact extends beyond the platform. - Long-lived exposure: log retention and backups mean the secret remains recoverable long after any password rotation, until all historical logs are purged. ATTACK SCENARIO 1. A whistleblowing site is configured with site-access password protection. 2. Visitors (and the operator during setup / testing) unlock the site; each unlock emits GET .../check_password?password=, logged by nginx and downstream systems. 3. A log-platform user, backup holder, third-party log processor, or an attacker who has obtained the access logs greps for "check_password", Base64-decodes the captured value, and recovers the cleartext password. 4. The actor unlocks the protected whistleblowing site at will; rotating the password does not remediate historical log copies. REMEDIATION 1. Stop sending the password in the URL. Validate via POST with the credential in the request body (TLS-encrypted, not logged in the request line). This is the primary fix. 2. Never log the secret. Ensure the body-based credential is excluded from access / error logs and from any observability / WAF capture; scrub historical logs and backups that contain check_password?password=. 3. Do not rely on Base64 for confidentiality. Treat the site password as a secret end-to-end; do not persist a reversible copy in localStorage / the Auth header - derive a short-lived, server-issued session token instead (as already done for case authentication). 4. Rotate any site passwords that may have been logged, and treat reused passwords as compromised. 5. Server-side enforcement: confirm the password gate is enforced on the protected data endpoints server-side, not only via the client-side route guard. 6. Throttle check_password and avoid a plain boolean oracle to limit brute force. REFERENCES - CWE-598: Use of GET Request Method With Sensitive Query Strings - CWE-532: Insertion of Sensitive Information into Log File - CWE-312: Cleartext Storage of Sensitive Information - CWE-261: Weak Encoding for Password - OWASP ASVS v4.0.3 7.1.1 (no sensitive data in logs), 8.3.1 (sensitive data not sent in URL parameters) _______________________________________________ Sent through the Full Disclosure mailing list https://nmap.org/mailman/listinfo/fulldisclosure Web Archives & RSS: https://seclists.org/fulldisclosure/
Current thread:
- Whistlelink: Site-access password exposed in web server access logs via GET query string Red Nanaki via Fulldisclosure (Jul 02)
How it works
Once you click Generate, Ollama reads this article and crafts 5 comprehension questions. Your answers are graded against the article content — general knowledge won't be enough. Score 70+ to count toward your certificate.
Questions are cached — you'll always get the same 5 for this article.