luap.in/java
← 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.

SourceNotes
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 setterPopulated by the params interceptor via OGNL
@RequestBody / @ModelAttributeJackson 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