CWE-598 describes a web application that processes a request with an HTTP method but puts sensitive information in the query string. The part after the question mark is the problem.
Every web app, API, and device with a built-in web interface can make this mistake, and the recent examples in MITRE's record show it keeps happening in modern products.
How it happens
It starts with convenience. A GET request is easy to build, easy to test in a browser, and easy to share. So an API key, a session token, or a password gets passed as a parameter.
GET /api/report?user=alice&token=9f3a1c... HTTP/1.1
The trouble is where URLs travel. They are written into web server and proxy logs, saved in browser history, copied into bookmarks and chat messages, and often sent along to other sites in the Referer header. A URL is treated as non-secret by almost every tool that touches it.
MITRE's record lists four recent examples:
- CVE-2025-1738, a security camera that includes a password in its query string.
- CVE-2025-31954, an ML/NLP-based automation product that calls a GET method with sensitive information in the query string.
- CVE-2024-31842, a web-based communication product that includes an access token in the query string of a GET request.
- CVE-2022-23546, a discussion platform that leaks private information in GET requests.
What an attacker gains
The consequence in the record is confidentiality. At a minimum, attackers can gather information from query strings that helps them escalate, such as details about the internal workings of the application or database column names. If the query string carries credentials or tokens, the attacker does not need to break anything. They read a log line or a history entry and replay the value.
How to find it
Static analysis (SAST) can find some instances by modelling data flow in source or compiled code. You can also check from the outside.
- Open your browser dev tools, use the app normally, and scan the network tab for requests with parameters named token, key, password, secret, or session.
- Search access logs for those same parameter names. If they appear, they are already stored in places you may not control.
- Review API docs and client SDKs for examples that put credentials in the URL.
Click through it at your own pace, or open it full screen.
How to fix it
MITRE's guidance: when sending sensitive information, only include it in the request body or request headers instead of the query string. This may require avoiding GET requests.
POST /api/report HTTP/1.1
Authorization: Bearer 9f3a1c...
Content-Type: application/json
{"user": "alice"}
Practical steps:
- Move tokens to the Authorization header and credentials to a POST body.
- Strip sensitive parameter names from access logs and proxy logs as a stopgap.
- Rotate any value that has already appeared in a URL, since it should be treated as exposed.
- Fix the client too. A server that accepts the header but a mobile app that still builds the URL leaves the leak open.
Quick check
Why is a query string worse than a request header for a token?
URLs are routinely stored in logs, browser history, and bookmarks, and can be passed on to other sites. Headers and bodies are not recorded by those tools by default.
Is switching to POST enough on its own?
It is the usual fix, but the point is where the secret lives. The value must be in the body or a header, not the URL, and exposed values should be rotated.