fix(contrib/azure/apim-callout): restore AppSec body inspection on oversized inline bodies and Boomi block enforcement#4966
Conversation
…ead of failing open decodeRawBase64Body returned an error for any inline body whose decoded size exceeded BodyParsingSizeLimit, and the callout handlers treated that as fail-open: they logged it and skipped OnRequestBody/OnResponseBody. A remote client could therefore pad a body past the limit to skip WAF body inspection entirely, even with the payload at the start of the body. Bound the base64 decode to one group past the limit so an oversized body decodes to a prefix strictly larger than the limit. The proxy body buffer then truncates it to the exact limit and flags it truncated, so the WAF still inspects the retained prefix (matching the proxy body pipeline). The truncated flag is required: the JSON encoder only tolerates incomplete input when truncated is set, so a plain byte cap would miss payloads split by padding. Add a regression test asserting a malicious prefix padded past the limit is still blocked.
…with callout templates The Boomi request/response block Groovy policies gated on dd-action/dd-resp-action == 'block' and read dd-block-body/dd-resp-block-body, but the callout templates never set those attributes: they extract the decision into dd-block/dd-resp-block and the body into dd-block-content/dd-resp-block-content. The block condition was therefore always false and AppSec block decisions were never enforced for Boomi deployments. Gate on the extracted dd-block/dd-resp-block attribute (guarding against null/empty/'null') and read the body from dd-block-content/dd-resp-block-content. Add a static test asserting every attribute read by each block policy is set by the matching callout template, with no Groovy runtime dependency.
Config Audit |
🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: bda2f6d | Docs | Datadog PR Page | Give us feedback! |
… attributes are coherent Adds TestBoomiRequestResponseBlockCoherence: the request (dd-block*) and response (dd-resp-block*) callout templates must extract the same block sub-fields from the same $.block... JSON paths. Catches drift where one side adds, drops, or renames a block field without the other.
BenchmarksBenchmark execution time: 2026-06-30 17:13:42 Comparing candidate commit bda2f6d in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 321 metrics, 2 unstable metrics, 1 flaky benchmarks without significant changes.
|
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep it up! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
What does this PR do?
Fixes two AppSec control bypasses in the Azure APIM / Boomi HTTP callout security processor (
contrib/azure/apim-callout):1. Oversized inline bodies were skipped instead of analyzed.
decodeRawBase64Bodyreturned an error for any inline body whose decoded size exceededBodyParsingSizeLimit, and the callout handlers treated that error as fail-open — they logged it and skippedOnRequestBody/OnResponseBody. A client could pad a body past the limit to skip WAF body inspection entirely, even with the payload at the start of the body. This diverged from the proxy body pipeline, which truncates to the limit and still analyzes the retained prefix.The decoder now bounds the base64 decode (still preventing the OOM the limit was added for) but returns a prefix one group past the limit, so the proxy body buffer truncates it to the exact limit and flags it
truncated. The WAF then still inspects the retained prefix. Thetruncatedflag is required: the JSON encoder only tolerates incomplete input when it is set, so a plain byte cap would miss payloads split by padding.2. Boomi block decisions were never enforced.
The Boomi request/response block Groovy policies gated on
dd-action/dd-resp-action == 'block'and readdd-block-body/dd-resp-block-body, but the callout templates never set those attributes — they extract the decision intodd-block/dd-resp-blockand the body intodd-block-content/dd-resp-block-content. The block condition was therefore always false and block decisions were silently dropped. The policies now read the attributes the callout templates actually set, with a guard againstnull/ empty /'null'.Motivation
Both issues were flagged as high-severity AppSec body-inspection / blocking bypasses in the apim-callout integration. (1) was a regression from the inline-body OOM hardening; (2) was introduced with the Boomi deployment templates.
Tests
TestAppSecBodyParsing/blocking-event-on-oversized-inline-request-body— a malicious prefix padded past the limit is now blocked (the regression guard for go tools bootstrap #1).TestBoomiTemplateAttributeConsistency— static check that every context attribute each block policy reads is set by the matching callout template; no Groovy runtime required (the regression guard for [core] Implementation of the tracing package #2).TestDecodeRawBase64Bodyand renamedTestOversizedInlineBodyFailsOpen→TestOversizedInlineBodyStillAnalyzed.Reviewer's Checklist
make lintlocally.make testlocally.make generatelocally.make fix-moduleslocally.