fix: bound manifest jinja collection traversal - #1561
Conversation
Performance BenchmarksCompared
|
|
Critical review and focused QA complete. Fixed a false positive where manifests could fail the new embedded-Jinja traversal budget even when Validation:
Adversarial checks covered exact item/depth boundaries, malicious templates collected before exhaustion, disabled scanner selection, and cyclic input to the collector. A pre-existing recursive-YAML alias can still fail closed earlier in other manifest walkers with Published fix: |
Replace recursive embedded-template collection with bounded traversal, preserve recovered findings on incomplete scans, redact budget evidence, and avoid treating plain nested template metadata as executable Jinja.
17a0c58 to
cfe4a53
Compare
mldangelo-oai
left a comment
There was a problem hiding this comment.
I found two traversal correctness issues that should be fixed before merging:
- Repeated YAML aliases are expanded once per reference. A list containing 1,000 references to the same small mapping consumes the item budget and records hundreds of duplicate templates, creating a false-inconclusive result.
- A recursive alias encountered before a sibling
chat_templaterepeatedly descends until the depth limit. The current depth-limitbreakthen stops the entire traversal, so the sibling malicious template is never analyzed. This is a false-negative path, even though the scan is marked inconclusive.
I prepared local commit de309af7 that tracks expanded container identities per traversal mode and skips only the over-depth branch instead of aborting all remaining siblings. It also adds regressions for shared aliases, recursive aliases, and a malicious template ordered after an over-depth branch.
Focused validation:
tests/scanners/test_manifest_scanner.py: 85 passed- traversal subset: 9 passed
- Ruff check/format: clean
- scoped mypy: clean
- direct probes: shared alias case finishes in 1,004 visits with one template; recursive alias finishes in 3 visits and preserves the sibling template
I could not push the commit because the available shell GitHub token is invalid, and these files are too large for the connector's whole-file update endpoint. The finding is therefore still present on remote head cfe4a53f.
|
Addressed both traversal blockers from the review in
Focused QA: complete manifest scanner module |
|
Addressed the existing traversal review and completed an additional false-positive/false-negative pass on head Fixes now published:
Scoped QA: 91 manifest-scanner tests, 8 focused adversarial regressions, Ruff check/format, mypy, direct probes, and exact remote tree/blob verification. No inline review threads remain. Full-suite validation is left to CI. |
|
Integrated current |
Merge current main and prevent attacker-controlled manifest keys from leaking through delegated Jinja findings or oversized-template reports while preserving chat-template context and collisions.
Summary
False-positive / false-negative audit
Validation
PROMPTFOO_DISABLE_TELEMETRY=1 UV_CACHE_DIR=/tmp/modelaudit-uv-cache uv run --frozen pytest -q tests/scanners/test_manifest_scanner.py-> 97 passed, 1 skipped (optionaljinja2.sandboxunavailable)git diff --check origin/mainpassedmainintegrated at43d2fb80731878757b307e3fc018f7097b072fae7565c505d23bc0e794e30a51098a2f49756372826758ae22782d5c73449260648c95b00fa3a431f6The full local suite was intentionally left to CI per the PR-audit workflow.