This skill focuses on determining at the source code level whether a "front-end security vulnerability is valid"; the core is verifying whether user input is sufficiently filtered and escaped during output to the HTTP response (HTML/Header/Cookie/redirect). Runtime exploitation techniques such as constructing payloads and bypassing WAFs fall under the scope of the corresponding black-box exploit skill.
In-depth reference
- Dangerous pattern / secure pattern code comparison / EVID evidence examples for the 5 categories of front-end vulnerabilities -> references/frontend-vuln-patterns.md
Quick reference table of the 5 categories of front-end security vulnerabilities
| Type | Typical Sink | Dangerous pattern | Severity |
|---|---|---|---|
| XSS | JSP <%= %>, th:utext, ${var?no_esc}, out.println() |
User input output directly to HTML/JS context without escaping | High-Medium |
| CSRF | State-changing POST/PUT/DELETE endpoints | csrf().disable() or write operation endpoints lacking Token validation |
High-Medium |
| Open redirect | sendRedirect(), return "redirect:" + url |
User-controllable URL passed directly to a redirect function | Medium |
| CRLF injection | setHeader(), addHeader(), addCookie() |
User input not filtered \r\n written directly to HTTP headers |
Medium-High |
| Session management | getSession(), Cookie construction, session-timeout |
Session not regenerated after login / Cookie missing security attributes | Medium-High |
General audit process (4 steps)
Step 1 -- Confirm EVID evidence points: From the java-audit-pipeline EVID_* evidence produced in Phase 3, filter front-end security entries (EVID_XSS_、EVID_CSRF_、EVID_REDIR_、EVID_CRLF_, EVID_SESSION_*). Sinks without EVID evidence can only be marked "to be verified".
Step 2 -- Determine filtering effectiveness: Trace each filtering/escaping operation along the Source->Sink path and evaluate whether it is effective for the current vulnerability type. Common pitfalls: <c:out> is safe but <%= %> does not escape,th:text is safe but th:utext does not escape, URL whitelist can be bypassed by //evil.com .
Step 3 -- Evaluate bypass possibility: When filtering exists but is insufficient, analyze the specific bypass path (context switching, encoding differences, URL parsing differences, etc.). If a bypass approach can be given, mark "confirmed"; otherwise mark "to be verified" and record the known filtering method.
Step 4 -- Determine severity: Use the java-audit-pipeline three-dimensional scoring formula Score = R*0.40 + I*0.35 + C*0.25. XSS stored type I=2-3, reflected type I=1-2; CSRF depends on the impact of the protected operation.
XSS audit key points
- JSP output:
<%= request.getParameter("x") %>and<% out.println(input); %>both do not escape; direct output to HTML is reflected XSS; secure写法:<c:out value="${param.x}"/>or${fn:escapeXml(param.x)}, JSTL escapes HTML entities by default - Thymeleaf:
th:utext="${userInput}"does not escape (raw HTML output) -- dangerous;th:text="${userInput}"automatically HTML-escapes -- safe - FreeMarker: After global configuration
output_format=HTMLOutputFormat+auto_escaping_policy=ENABLE_IF_SUPPORTEDescapes by default;${var?no_esc}explicitly skips escaping -- dangerous; when global escaping is not configured, all${}are dangerous - Context differences: HTML body escaping
< > & " 'is sufficient; HTML attributes require additional handling of quote closure; JavaScript contexts require JS encoding rather than HTML escaping; URL parameters require URL encoding—using the wrong escaping function for different contexts is equivalent to no defense - DOM-based XSS: Backend returns JSON that is rendered by the frontend
innerHTML/document.write()/eval(), backend audit needs to confirm whether the JSON response'sContent-Typeisapplication/jsonrather thantext/html - Stored XSS: Data is output directly without escaping after being retrieved from the database—trace whether filtering was done at the storage point and whether escaping was done at the output point
- Rich text scenarios: Need to use whitelist filtering libraries such as OWASP Java HTML Sanitizer (
PolicyFactory) orJsoup.clean(html, Safelist.basic())
CSRF Audit Key Points
- Spring Security default: CSRF Token is enabled by default, but REST API projects commonly use
.csrf().disable()(older versions) orhttp.csrf(csrf -> csrf.disable())(Lambda DSL)—after global disabling, all state-changing endpoints are exposed - Custom Token: Evaluate generation strength (
SecureRandomsecure vsMath.random()predictable), whether it is bound to Session, and validation timing (Controller layer vs Filter layer) - Token transmission: Forms use
<input type="hidden" name="_csrf" value="..."/>; AJAX uses theX-CSRF-TOKENrequest header together with<meta name="_csrf">reading—if any transmission method is missing, that scenario has no protection - Relationship between CORS and CSRF: Permissive CORS (
Access-Control-Allow-Origin: *+Allow-Credentials: true) can allow cross-origin JS to read the CSRF Token in the response, indirectly bypassing CSRF protection - GET request state change: GET performing write operations (such as
/deleteUser?id=1) inherently has no CSRF protection—<img src="">can trigger it
Open Redirect Audit Key Points
- Servlet direct redirect:
response.sendRedirect(request.getParameter("url"))/response.sendRedirect(request.getParameter("next"))—fully user-controllable - Spring MVC:
return "redirect:" + targetorRedirectView(url)where target comes from request parameters - Bypass techniques:
//evil.com(protocol-relative URL),/\evil.com(some parsers treat\as a path separator), URL-encoded%2F%2Fevil.com、@symbolhttp://trusted.com@evil.com, unicode homoglyphs - Secure mode: Whitelist domain validation + restrict to relative paths only (starting with
/and not starting with//); useUriComponentsBuilderto parse and then validate host
CRLF Injection Audit Key Points
- HTTP Header injection:
response.setHeader("X-Custom", userInput)orresponse.addHeader("Location", "/path?lang=" + input)—injecting\r\nSet-Cookie: admin=1can set arbitrary headers - Servlet container differences: Tomcat 7.0.67+ / Jetty 9.2.15+ reject
\r\nin Header values by default; older versions or custom HTTP frameworks (such as Netty raw API) may lack this protection—confirming the container version is key - Cookie value injection:
new Cookie("lang", userInput)—injecting\r\nSet-Cookie: session=evilcan hijack the Session - Secure mode: Filter or reject
\r、\n、\0control characters in values; upgrade to a newer Servlet container version
Session Management Audit Key Points
- Session fixation: Session ID remains unchanged before and after login—attacker induces victim to use a known Session ID; secure mode: after successful login
request.getSession().invalidate()+request.getSession(true)rebuild; Spring SecuritySessionFixationProtection.migrateSessionenabled by default - Cookie attributes:
HttpOnlyPrevent XSS Cookie theft (cookie.setHttpOnly(true));SecureRestrict HTTPS-only transmission (cookie.setSecure(true));SameSite=Lax/StrictPrevent CSRF (Servlet 4.0+ or Springserver.servlet.session.cookie.same-site) - Timeout configuration:
web.xmlin<session-timeout>30</session-timeout>(minutes); Spring Bootserver.servlet.session.timeout=30m; excessively long timeouts increase the Session hijacking window - Concurrent login control: Spring Security
sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true)— when not configured, the same account can log in from multiple locations, making stolen credentials hard to detect
Detection checklist
- All frontend security-related EVID_* evidence points have been reviewed one by one
- JSP
<%= %>/out.println()All output points have been confirmed whether they are escaped, Thymeleafth:utextall marked - CSRF protection status has been confirmed (whether disabled, Token transmission method, GET write operations)
- The URL source and whitelist validation of redirect Sinks have been confirmed
- User input filtering at HTTP Header/Cookie write points has been checked, and the container version has been recorded
- The Session lifecycle (fixation/timeout/concurrency/Cookie attributes) has been reviewed
- For points with insufficient filtering, specific bypass ideas have been provided or they have been marked "to be verified"
- The severity score uses a unified formula, consistent with the pipeline