fix: harden auth, validation, and sandboxing (audit #12-#23)#24
fix: harden auth, validation, and sandboxing (audit #12-#23)#24LKSNDRTMLKV wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR is currently incomplete or mislabeled. While the title and description claim to implement extensive security hardening for audit findings #12 through #23—including authentication fail-closed logic, SQL injection prevention, and Wasm sandboxing—the provided code changes only consist of a version update for the 'reqwest' library in Cargo.toml. None of the eight acceptance criteria are met, and the regression tests mentioned in the description are entirely absent from the diff. This PR should not be merged until the promised implementation is included.
About this PR
- The PR description mentions the inclusion of regression tests for each security fix, but no new test files or modifications to existing tests are present in the change set.
- The implementation is missing all security hardening logic described in the PR summary. No code changes related to audit findings #12-#23 (such as mTLS endpoints, Wasm limiters, or GTIN validation) were found in the provided diff.
Test suggestions
- Verify that an unrecognized API-key scope string defaults to 'Read' access.
- Verify that LIKE-pattern injection attempts in dpp-dal passport queries are neutralized.
- Confirm that Read-scoped keys are blocked from calling dpp-vault mutation handlers.
- Validate GTIN mod-10 checksum enforcement for tyre and steel importers.
- Verify Wasm table-growth limits prevent sandbox escapes or resource exhaustion.
- Test that internal mTLS endpoints reject requests lacking the shared-secret proxy binding.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Verify that an unrecognized API-key scope string defaults to 'Read' access.
2. Verify that LIKE-pattern injection attempts in dpp-dal passport queries are neutralized.
3. Confirm that Read-scoped keys are blocked from calling dpp-vault mutation handlers.
4. Validate GTIN mod-10 checksum enforcement for tyre and steel importers.
5. Verify Wasm table-growth limits prevent sandbox escapes or resource exhaustion.
6. Test that internal mTLS endpoints reject requests lacking the shared-secret proxy binding.
TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| Security | 4 high |
🟢 Metrics 16 duplication
Metric Results Duplication 16
AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.
TIP This summary will be updated as you push new changes.
# Conflicts: # cli/src/cli_args.rs # crates/dpp-resolver/src/handlers/resolve_by_gtin.rs
Summary
Hardening pass across
dpp-engineclosing the open audit findings (#12–#23). Same posture as the core pass: adversarial/malformed input that previously failed open, panicked, or bypassed a check now fails closed with an explicit error, each with a regression test. The fulljust checkgate is green.This PR contains only the audit fixes. An in-progress webhooks feature that happened to be in the working tree is deliberately excluded — see "Scope" below.
Fixes by area
Scope enforcement, end-to-end (#23, #21, #20, #18) — the central finding.
dpp-types(dpp-types: unrecognized API-key scope strings fail open to Admin; retention policy has no lower bound #21): unrecognized API-key scope strings now fail closed toRead(were failing open toAdmin); retention policy gains a lower bound.dpp-dal(dpp-dal: LIKE-pattern injection exposes arbitrary passports; stale compliance-critical columns; fail-open scope default #18): fixed LIKE-pattern injection that exposed arbitrary passports; dropped stale compliance-critical columns from patch writes; made the scope default fail closed; guarded the resubmit path androws_affectedchecks.dpp-vault(dpp-vault: Read-scoped API keys can perform full passport-lifecycle writes #20): every mutation handler (create/update/publish/suspend/archive/eol/transfer + operator) now enforcescan_write(), so Read-scoped keys can no longer perform lifecycle writes.dpp-common (#13) — the request-ID middleware now matches its own
application/problem+jsonerror content-type (it never did), and oversized error bodies pass through with the id in the header instead of being silently emptied.dpp-integrator (#12) — steel/aluminium/tyre importers validate the GTIN mod-10 checksum like the battery importer already did; a malformed vault response is no longer recorded as a successful create.
dpp-identity (#14) — internal mTLS endpoints require a shared-secret proxy binding instead of trusting client-supplied headers alone; key rotation aborts on archive failure instead of failing open; removed a dead per-operator DID route.
dpp-resolver (#15) —
gtin/dppIdare validated at the edge (closes an SSRF / path-traversal surface); the linkset base URL is a fixed constant instead of a tamperableqrCodeUrl-derived value (closes an open redirect).dpp-seal (#16) —
capabilities()reports no sealing support when no QTSP is configured, instead of advertising modes the adapter cannot actually deliver.dpp-plugin-host (#17) — added the missing Wasm table-growth limiter; sandbox-breach metrics are classified from the trap rather than a spoofable message; the in-force compliance gate is applied on the previously-missed output path; unsigned plugins are refused unless explicitly opted in.
dpp-node (#19) — an EU-registry payload that fails validation is no longer sent anyway; the boot-time operator-country lookup surfaces DB errors instead of baking an empty country in for the process lifetime; fixed a token-expiry underflow panic.
odal CLI (#22) — byte-index slicing on untrusted UTF-8 no longer panics (char-safe truncation); the API secret for
odal key useis read from a flag,ODAL_API_SECRET, or a no-echo prompt instead of being accepted as a plaintextargvargument.dpp-evidence verification — also fixes odal-node/dpp-core#25 (its fix lives here, in
dpp-vault): unsigned-but-completed transfer records now fail verification, and a present-but-unresolvablekidreturns an accurate diagnosis instead of silently falling back to the primary key. (GitHub won't auto-close a cross-repo issue on merge — close dpp-core#25 manually.)Scope — webhooks excluded
An unrelated, in-progress webhooks feature (28 modified files + 11 new files) was present in the working tree and is not part of this PR. The commit was assembled to contain only the 42 audit files and verified in isolation —
just checkwas re-run green with the webhooks WIP stashed, so the gate reflects exactly what is committed here. That work continues separately onmain.Deferred follow-ups (not blockers)
test-integrationtier needsDPP_ALLOW_UNSIGNED_PLUGINS=truein the plugin-host feature-gated tests/benches — a consequence of the dpp-plugin-host: Wasm sandbox limiter gap; spoofable sandbox alerts; missing in-force gate on one output path #17 fail-closed change. The fastjust checkgate is unaffected.RegistrySyncPort+RegistrationRequest; left as a follow-up because it interacts with #27's stricter validation (which now rejects an empty operator name/country).Dependency / merge order
Builds against
dpp-corefix/core-auditvia the local[patch.crates-io]. Land the core PR and publishdpp-core0.7.0 first, then this branch can pindpp-* = 0.7.0from the registry and drop the patch.Testing
just checkgreen: fmt-check · clippy--workspace --all-targets -D warnings· debug-check · subjects-check · mod-rs-check ·cargo nextest --workspace· audit.Closes #12, #13, #14, #15, #16, #17, #18, #19, #20, #21, #22, #23