fix(jinja): require executable SSTI context - #1647
mldangelo-oai merged 3 commits into
Conversation
Scope static Jinja SSTI regexes to executable template spans so literal chat-template prose does not trigger critical request-call findings. Preserve active expressions, statements, obfuscated traversal, and malformed active payload detection with focused regressions.
|
@codex review |
Performance BenchmarksCompared
|
|
Codex Review: Didn't find any major issues. 🎉 ℹ️ 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". |
ianw-oai
left a comment
There was a problem hiding this comment.
Approved as a focused executable-span Jinja SSTI false-positive fix with preserved active-context coverage and green checks.
Dismissed by approval sweep because GitHub recomputed this current head as dirty after approval; needs conflict resolution before the simple-approval path.
…t25-jinja-ssti-executable-context-20260610
Avoid letting malformed ignored comment/raw regions consume later active Jinja spans in the no-Jinja fallback parser. Add synthetic regressions for later active requests payloads after malformed ignored regions.
Summary
{{ ... }}and{% ... %}spans instead of full extracted template strings.Root Cause
The Jinja scanner extracted
chat_templatevalues correctly, but then applied SSTI regexes across the entire template string. Literal system-preamble prose inCohereLabs/North-Mini-Code-1.0includes phrases likeuser's requests.; therequests\.critical pattern matched that literal prose as if it were an executable request call.Security Tradeoff
This narrows static SSTI indicators to structurally active Jinja spans. Benign prose outside delimiters, Jinja comments, and raw blocks no longer produce security findings. Active payloads such as
{{ requests.get(...) }},{% set x = requests.post(...) %}, dunder traversal,attr(...)obfuscation, command execution, and unterminated active expressions remain detected. When the Jinja lexer is unavailable, a delimiter fallback still scans executable spans conservatively, including unterminated active tags.Validation
PROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest tests/scanners/test_jinja2_template_scanner.py -q-> 419 passed, 1 skipped.PROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest tests/scanners/test_gguf_scanner.py tests/test_simple_jinja2.py -q-> 58 passed, 3 skipped.uv run ruff format --check modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/-> 419 files already formatted.uv run ruff check modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/-> all checks passed.uv run mypy modelaudit/ packages/modelaudit-picklescan/src packages/modelaudit-picklescan/tests tests/-> success, 474 source files.PROMPTFOO_DISABLE_TELEMETRY=1 uv run pytest -n auto -m "not slow and not integration" --maxfail=1-> 18546 passed, 793 skipped, 40 warnings.git diff --check-> passed.Pinned Hugging Face QA
Before fix on exact pinned revision:
Outcome: exit 1; three CRITICAL
requests\.components inchat_template[0].template,chat_template[1].template, andchat_template[2].template.After fix on the same pinned revision:
Outcome: exit 0 clean; JSON summary
success=true,files_scanned=1,issues=0,failed_checks=0.