Skip to content

[Java]Fix flakiness in Test_Lfi_BodyUrlEncoded.test_lfi_post_urlencoded for vertx4#6386

Draft
jandro996 wants to merge 2 commits intomainfrom
alejandro.gonzalez/APPSEC-61455
Draft

[Java]Fix flakiness in Test_Lfi_BodyUrlEncoded.test_lfi_post_urlencoded for vertx4#6386
jandro996 wants to merge 2 commits intomainfrom
alejandro.gonzalez/APPSEC-61455

Conversation

@jandro996
Copy link
Member

@jandro996 jandro996 commented Feb 26, 2026

Motivation

https://datadoghq.atlassian.net/browse/APPSEC-61455

The catch-all RASP route handlers in RaspRouteProvider.java (vertx4) were reading the attack parameter with rc.request().getParam(name) for all non-XML, non-JSON requests:

router.route().path("/rasp/lfi").blockingHandler(rc -> executeLfi(rc, rc.request().getParam(FILE)));

In Vert.x 4, getParam() reads query string parameters. It falls back to form attributes only if isExpectMultipart() is true on the underlying request, which requires the BodyHandler to have called setExpectMultipart(true) before any body data arrives. For small payloads (e.g. file=../etc/passwd) that fit in a single TCP packet, this setup can race against the data arrival under certain conditions (GC pauses, CI scheduler load, JVM JIT state), causing getParam() to return null.

For lfi, shi, sqli, and cmdi, a null parameter causes either a NullPointerException (in new File(null) or String.split()) or silently corrupts the sink input, preventing RASP from evaluating the attack. The result is a non-deterministic 500 Internal Server Error instead of the expected 403.

The flakiness was only observable as a test failure on lfi because executeSql has a broad catch (Throwable) that masks the crash — but all four handlers shared the same underlying bug.

Changes

Added an explicit application/x-www-form-urlencoded route for each affected endpoint this mirrors the existing pattern for application/xml and application/json routes and makes the parameter source explicit and deterministic for each content type. The catch-all with getParam() is preserved for GET requests using query parameters.

Workflow

  1. ⚠️ Create your PR as draft ⚠️
  2. Work on you PR until the CI passes
  3. Mark it as ready for review
    • Test logic is modified? -> Get a review from RFC owner.
    • Framework is modified, or non obvious usage of it -> get a review from R&P team

🚀 Once your PR is reviewed and the CI green, you can merge it!

🛟 #apm-shared-testing 🛟

Reviewer checklist

  • Anything but tests/ or manifests/ is modified ? I have the approval from R&P team
  • A docker base image is modified?
    • the relevant build-XXX-image label is present
  • A scenario is added, removed or renamed?

@github-actions
Copy link
Contributor

CODEOWNERS have been resolved as:

utils/build/docker/java/vertx4/src/main/java/com/datadoghq/vertx4/rasp/RaspRouteProvider.java  @DataDog/apm-java @DataDog/asm-java @DataDog/system-tests-core

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant