[PER-15532] fix: clear remaining pdp-v2 image CVEs from customer scan (PER-15358) - #328
Conversation
A customer scan of permitio/pdp-v2:0.9.13 surfaced 43 unique CVEs. Most were already fixed after 0.9.13 was cut (Go deps via permit-opa #38, cryptography pin, and the libssl3/pyjwt/aiohttp bumps a rebuild picks up automatically). This covers what was genuinely left. Fixed: * GHSA-27jp-wm6q-gp25 - sqlparse 0.5.0 -> 0.5.5 (fixed in 0.5.4). Note sqlparse is never imported; it has only ever been carried as a floor pin from past vuln sweeps. Flagged inline as a removal candidate. Waived (unreachable code paths, verified against the source): * CVE-2026-48710 - malformed Host header desyncs request.url.path from the routed path. No PDP security decision reads request.url: auth is per-route via FastAPI Depends/HTTPBearer, there is no add_middleware or BaseHTTPMiddleware, and the one path-keyed check (cloud_proxy) reads request.path_params, which the router fills from the raw scope path. * CVE-2026-48817 - unsafe getattr dispatch in starlette HTTPEndpoint. The PDP defines no HTTPEndpoint/WebSocketEndpoint subclass; every route is an APIRouter decorator with explicit methods. Both are fixed only in starlette >=1.x, which OPAL's starlette<1 cap forbids, so they join the two existing starlette waivers. Dropped: * CVE-2026-50163 (oras-go) - waiver removed; oras-go v2.6.2 fixes it and permit-opa now pins it. That bump MUST merge to permit-opa@main before this branch merges, since the PDP build clones permit-opa@main and the scout gate will otherwise fail with the waiver gone. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR reduces remaining CVE findings in the permitio/pdp-v2 container image by bumping a leftover vulnerable Python dependency and updating the project’s OpenVEX waiver document (plus related CI comments) to reflect current “not_affected” determinations for Starlette CVEs that cannot be patched due to OPAL’s starlette<1 constraint.
Changes:
- Bump
sqlparsefrom0.5.0to0.5.5to address GHSA-27jp-wm6q-gp25. - Update
.docker/scout/pdp-v2.vex.json(timestamp/version) to drop theoras-gowaiver and add two additional Starlettenot_affectedstatements. - Refresh the Docker Scout gate workflow comments to match the updated waiver set.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
requirements.txt |
Bumps sqlparse and updates the Starlette CVE waiver explanation comment. |
.github/workflows/tests.yml |
Updates Docker Scout gate comments to list the current waived Starlette CVEs. |
.docker/scout/pdp-v2.vex.json |
Updates OpenVEX statements: removes oras-go waiver and adds/reshuffles Starlette not_affected entries. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
🔍 Vulnerabilities of
|
| digest | sha256:d4a87fe5dd9a7d02b5458a6514a07de5a402911915370626ee0cc5059ef65a21 |
| vulnerabilities | |
| platform | linux/amd64 |
| size | 225 MB |
| packages | 264 |
📦 Base Image python:3.10-alpine3.22
| also known as |
|
| digest | sha256:c8f94b3bb77e6ea9015ccd091b7f8aec1b1fcbca95159675235d9a93788797cd |
| vulnerabilities |
Description
Description
Description
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
|
The Docker Scout gate surfaced a second HIGH beyond the customer's report: CVE-2026-50271 (CVSS 7.5), a remote DoS in ddtrace's W3C baggage propagator. The extract path ignores DD_TRACE_BAGGAGE_MAX_ITEMS and DD_TRACE_BAGGAGE_MAX_BYTES, so an unauthenticated caller can drive unbounded CPU/memory with an oversized baggage header. This is not introduced here - main would fail the same gate today; the advisory simply postdates main's last green run (Jul 14). The fix is only in ddtrace >= 4.8.2 and opal-common 0.9.6 caps ddtrace<4, so it cannot be upgraded away. Rather than waive on the default posture alone, remove the vulnerable parser from the request path: set DD_TRACE_PROPAGATION_STYLE_EXTRACT=datadog,tracecontext, dropping "baggage" from ddtrace's default extract styles. That matters because the exposure is real, just config-gated. ddtrace only reaches inbound requests when PDP_ENABLE_MONITORING=true (default false) calls patch(fastapi=True) - but baggage IS in ddtrace's default extract styles, so anyone who enables monitoring would otherwise be genuinely exposed. A "not in execute path" waiver would have been false for them. Injection is left at its default, so outbound baggage propagation is unchanged. Waived as inline_mitigations_already_exist, which is accurate for both the default and monitoring-enabled configurations. ddtrace is pinned to 3.19.8 so the waiver PURL stays bound (no lockfile in the image build). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Added: CVE-2026-50271 (ddtrace baggage DoS, HIGH 7.5)The first Scout run surfaced a second HIGH beyond the two expected findings, so folding the fix in here. Not introduced by this branch — Why not a plain waiver: the exposure is real but config-gated. ddtrace only reaches the inbound request path when Mitigation: the image now sets
The 4.8.2 fix is blocked by Remaining gate statusThe only expected failure left is CVE-2026-50163 (oras-go), which clears once permitio/permit-opa#42 merges — that PR is green and ready. |
Tested locally — image builds and runs, no platform regression ✅Built Build
Runtime / integration
Scope note: this validates the image still builds and runs with the requirements/Dockerfile changes. The OpenVEX waiver additions + Docker Scout CVE gate are validated separately in CI (they don't affect runtime). 🤖 Tested with Claude Code |
EliMoshkovich
left a comment
There was a problem hiding this comment.
Please re-check it over staging as well , right after you'll merge it
Summary
A customer scanning
permitio/pdp-v2:0.9.13before promoting it into their Artifactory surfaced 57 findings / 43 unique CVEs (10 Critical, 29 High, 18 Medium; no CISA KEV entries).The large majority were already fixed after
0.9.13was cut (May 13) and just need a release: the Go dependency bumps in permit-opa #38, thecryptography>=48.0.1pin, and thelibssl3/libcrypto3/pyjwt/aiohttpupdates a rebuild picks up automatically. This PR covers what was genuinely left over.Fixed
sqlparse0.5.0 → 0.5.5 (fixed in 0.5.4).Note:
sqlparseis never imported anywhere in the codebase; all three commits that ever touched it were vulnerability-sweep floor pins. Flagged inline as a removal candidate rather than removed here, to keep this release low-risk.Waived (verified unreachable against the source)
Two new OpenVEX
not_affectedstatements, joining the two existing starlette waivers. All four are fixed only in starlette >= 1.x, which OPAL'sstarlette<1cap forbids.Hostheader can makerequest.url.pathdiverge from the path actually routed, bypassing security checks that readrequest.url. The PDP makes no security decision onrequest.url: authentication is enforced per-route via FastAPIDepends/HTTPBearer(horizon/authentication.py), there is noadd_middlewareorBaseHTTPMiddlewareanywhere, and no raw ASGIscope[...]reads outside tests. The one path-keyed authorization check — the write-route test incloud_proxy(horizon/proxy/api.py) — readsrequest.path_params, which Starlette's router populates from the raw scope path and which this CVE explicitly leaves unaffected.getattrdispatch instarlette.endpoints.HTTPEndpoint, where the lowercased HTTP method is resolved against the endpoint without restricting the lookup to known verbs. The PDP defines noHTTPEndpointorWebSocketEndpointsubclass; every route is anAPIRouterdecorator with explicit methods, so the vulnerable dispatch class is never instantiated.Dropped
oras-go) — waiver removed.oras-gov2.6.2 fixes it and permit-opa now pins it, so the waiver is no longer needed.Also refreshed the now-stale comments in
requirements.txtandtests.ymlthat still described "two starlette CVEs" and the oras-go waiver.Merge order
permit-opa@main— so if this merges first, the Docker Scout gate will fail on CVE-2026-50163 with no waiver left to suppress it.Test plan
authorremainsPermit.io, matchingvex-authorin the Scout gate step (without which statements are displayed but not suppressed — see Docker Scout cves with vex-location docker/scout-cli#207)libcrypto3/libssl3CVEs clear via the Dockerfile's existingapk upgradeon rebuildHTTPEndpoint/WebSocketEndpointsubclasses, noStaticFilesmount, norequest.form(), noadd_middleware/BaseHTTPMiddleware, no rawscope[...]outside testsWhat still won't be clean after this
Two groups remain in the customer's report and will need scanner exceptions on their side:
starlette<1cap; justifications above.🤖 Generated with Claude Code