Problem
Krazo CSRF validation currently checks the CSRF header first and then falls back to reading the submitted form body through FormEntityProvider. On some servlet/JAX-RS integrations, the submitted form parameters are already parsed and available through HttpServletRequest, but the JAX-RS form-body path is no longer reliable because the body has already been consumed.
This causes valid CSRF-protected form submissions to fail with 403, even though the submitted _csrf form field is present and correct.
Observed Behavior
On WebLogic with Jersey-based MVC/TCK execution:
- Krazo receives a valid CSRF-protected form POST.
HttpServletRequest#getParameterMap() contains _csrf.
- Jersey logs that the request body has already been consumed.
- Krazo falls through to its form-body validation path and rejects the request with 403.
Expected Behavior
If the CSRF header is absent, Krazo should also accept a valid token from HttpServletRequest.getParameter(token.getParamName()) before depending on re-parsing the JAX-RS entity body.
Why This Belongs In Krazo
This is not a container authorization/role-mapping issue. It is a CSRF validation interoperability issue between servlet request parameter parsing and JAX-RS entity handling. Krazo already owns the CSRF validation flow, so the fallback should live in CsrfValidateFilter.
Reproducer / Evidence
A targeted MVC TCK probe showed:
- With the existing WebLogic runner workaround disabled, valid form submission failed with 403.
- Server diagnostics showed _csrf was present in the servlet request parameters.
- After adding a servlet-request fallback in
CsrfValidateFilter, the same test passed.
Relevant TCK slice:
ee.jakarta.tck.mvc.tests.security.csrf.header.CsrfDefaultHeaderTest
- After the fix: Tests run: 4, Failures: 0, Errors: 0, Skipped: 0
Proposed Fix
In CsrfValidateFilter:
- Check the CSRF header first, as today.
- If the header is absent, check
HttpServletRequest.getParameter(token.getParamName()).
- Only if that also fails, fall back to the existing JAX-RS form-body parsing path.
Test Coverage
Add a unit test covering the servlet-request fallback path so valid CSRF form submissions do not regress when the JAX-RS entity stream is not the reliable source of form parameters.
Problem
Krazo CSRF validation currently checks the CSRF header first and then falls back to reading the submitted form body through
FormEntityProvider. On some servlet/JAX-RS integrations, the submitted form parameters are already parsed and available throughHttpServletRequest, but the JAX-RS form-body path is no longer reliable because the body has already been consumed.This causes valid CSRF-protected form submissions to fail with 403, even though the submitted _csrf form field is present and correct.
Observed Behavior
On WebLogic with Jersey-based MVC/TCK execution:
HttpServletRequest#getParameterMap()contains _csrf.Expected Behavior
If the CSRF header is absent, Krazo should also accept a valid token from
HttpServletRequest.getParameter(token.getParamName())before depending on re-parsing the JAX-RS entity body.Why This Belongs In Krazo
This is not a container authorization/role-mapping issue. It is a CSRF validation interoperability issue between servlet request parameter parsing and JAX-RS entity handling. Krazo already owns the CSRF validation flow, so the fallback should live in
CsrfValidateFilter.Reproducer / Evidence
A targeted MVC TCK probe showed:
CsrfValidateFilter, the same test passed.Relevant TCK slice:
ee.jakarta.tck.mvc.tests.security.csrf.header.CsrfDefaultHeaderTestProposed Fix
In
CsrfValidateFilter:HttpServletRequest.getParameter(token.getParamName()).Test Coverage
Add a unit test covering the servlet-request fallback path so valid CSRF form submissions do not regress when the JAX-RS entity stream is not the reliable source of form parameters.