← Index · 07 · Reference
18 sinks · 12 sources
The sink catalogue
The same request.getParameter("id") is inert beside a
println and critical beside a Statement. Taint
analysis is about what consumes the value, not how dangerous the input looks.
Each entry gives the Java mechanism, both forms of the code, what is not a fix,
and how to find it without manufacturing a false positive.
ASources — where untrusted data enters
Every one of these is attacker-controlled. The first four are the ones most often assumed otherwise.
| Source | Notes |
|---|---|
| request.getHeader("Host") | Not set by the proxy unless the proxy overwrites it. Cache poisoning, password-reset links |
| request.getHeader("X-Forwarded-For") | Trusted only behind RemoteIpValve with internalProxies. Otherwise an ACL and rate-limit bypass |
| request.getContentType() | Fully attacker-controlled. The S2-045 entry point |
| request.getRequestURI() | Undecoded, unlike getServletPath(). The filter/servlet mismatch |
| request.getParameter(name) | Query string and form body, merged. Parsed lazily |
| request.getParameterMap() | Feeds bean population — see mass assignment |
| request.getCookies() | Values and names both |
| request.getPathInfo() | Decoded; the usual traversal carrier |
| request.getInputStream() | Raw body. Reading it destroys form parameters |
| request.getPart() | Upload: filename and content are separate sources |
| Struts Action setter | Populated by the params interceptor via OGNL |
| @RequestBody / @ModelAttribute | Jackson or WebDataBinder; nested paths reach further than expected |
And one that is easy to forget: a row read back from the database. If it was ever user-supplied it is still tainted. That is the whole of stored XSS, and it is why output encoding belongs at the point of output, not at input.
luap.in/java · source
Java 21 · Tomcat 10.1.61 · Struts 6 · Spring Boot 3