Skip to content

VNX-488: Exposure of Data Element to Wrong Session

Per-request or per-user data stored in a field of a Java component that one instance serves every request: a class that extends HttpServlet/GenericServlet, is annotated @WebServlet, @Controller or @RestController, or extends a Struts Action. A request handler assigns a non-final field (instance or static) from the request (getParameter, getHeader, getAttribute, getSession, getRemoteUser, getUserPrincipal, getCookies, getInputStream/getReader, getQueryString), directly or through a local variable assigned from the request a few lines above. Concurrent requests share the field, so one user's data is served to another. Not reported: locals, final fields, assignments in init() or a constructor, fields of classes that are not request singletons (including Spring beans annotated @RequestScope, @SessionScope or @Scope request/session/prototype), fields set from servlet configuration, and the pattern in comments or string literals.

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-488
Severity Low
SARIF level note
Kind sast
Languages Java
CWE CWE-488
CAPEC CAPEC-66
ATT&CK T1190
CWSS vector CWSS:1.0/TI:L/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:L/DI:H/EX:L/EC:N/P:L
Tags servlet shared-state session race-condition cwe-488
Source internal/sast/rules/vnx-488.rego

Overview

VNX-488 maps to CWE-488: Exposure of Data Element to Wrong Session. It reports request data written into a field of a servlet or Spring controller, which one instance shares across all requests.

Why This Matters

The container creates one servlet instance, and Spring creates one controller instance, and every request thread runs through it at once. A field set from request A can be read while serving request B, so one user sees another user’s name, account or cart.

What Gets Flagged

public class ProfileServlet extends HttpServlet {
    private String userName;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) {
        userName = request.getParameter("user");     // FLAGGED
        response.getWriter().println(render(userName));
    }
}
@RestController
public class CartController {
    private static String lastUser;

    @GetMapping("/cart")
    public Cart cart(HttpServletRequest req) {
        String user = req.getRemoteUser();
        lastUser = user;                              // FLAGGED
        ...

Not flagged: the same value kept in a local variable, a final field, or a field set in init() from servlet configuration.

Remediation

  1. Keep per-request data in local variables or pass it as method arguments.
  2. Store per-user data in the request (request.setAttribute) or the session, never in a field of the servlet or controller.
  3. If a component must hold per-request state, make it request-scoped (@RequestScope) rather than a singleton.

References

Suppressing this rule

Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):

# nosec vnx-488
// nosec vnx-488

Or record an ignore rule: vulnetix ignore add --rule vnx-488 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-488.rego, cli/internal/sast/docs/vnx-488.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.