Get Request With Body
ID |
javascript.get_request_with_body |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
JavaScript |
Tags |
api, http, reliability |
Description
Reports an HTTP request configured as GET or HEAD while carrying a payload — fetch(url, {method: 'GET', body}), axios({method: 'get', data}), axios.get(url, {data}), and the request equivalents.
An omitted method counts as GET for fetch, because that is the documented default and fetch(url, {body}) throws just the same. For axios the method must be written out: its default is configurable per instance, so an absent one states nothing.
A configuration object holding a spread ({…defaults, body}) is not reported — the spread may carry the method, and what it carries is not visible.
Rationale
// Bad
const response = await fetch('/search', {
method: 'GET',
body: JSON.stringify(query)
});
// Bad — no error at all
const { data } = await axios.get('/search', { data: query });
-
Neither method has a body. The specification says a
GETorHEADrequest must not carry one. -
The two clients disagree only in how they say so. The Fetch API throws
TypeError: Request with GET/HEAD method cannot have body;axios.getsilently drops thedatait was handed. -
The silent case is the expensive one: the request goes out looking healthy, the server sees no filter, and the response is the whole collection instead of a search result.
-
It is normally a half-finished edit — the payload was moved into a search that used to be a
POST, or a body was added to a request whose method nobody re-read.
Remediation
Send the payload in the query string, or make the request a POST if the payload does not belong in a URL.
// Good — the filter travels in the query string
const response = await fetch(`/search?${new URLSearchParams(query)}`);
// Good — axios builds the query string from `params`
const { data } = await axios.get('/search', { params: query });
// Good — a payload too large or too sensitive for a URL goes in a POST
const response = await fetch('/search', {
method: 'POST',
body: JSON.stringify(query)
});