Why must bearer tokens not be sent in the query string of a URL?
Because URLs are logged and copied in many places (server and proxy logs, browser history, bookmarks, Referer headers sent to other sites), so a token in the URL leaks to parties that were never meant to see it, and a bearer token works for whoever finds it.
RFC 6750 defined three ways to present a bearer token: the Authorization: Bearer header, a form-encoded body parameter, and a access_token= URI query parameter. The third was always the weakest:
- Web servers, load balancers and proxies routinely write full request URLs, including query strings, to log files.
- Browsers keep URLs in history and may sync them across devices.
- When a page links to another site, the browser can send the full URL in the
Refererheader.
Each of these is a copy of the token outside the protected channel. Because a bearer token needs no proof of possession, any such copy can be used to call the API. OAuth 2.1 therefore forbids the query-string method; the header method is the standard.
Go deeper:
RFC 6750, Section 5.3: Summary of Recommendations — includes "don't pass bearer tokens in page URLs".
RFC 6750, Section 2.3: URI Query Parameter — the method and its warnings.