fix(safety): sanitize newline-based injection patterns - #795
Open
leulAbate wants to merge 8 commits into
Open
Conversation
Records selection of issue ascherj#64 (prompt_defense newline sanitizer) and serves as the setup commit for the Module 3 working branch.
…greement Three xfail(strict=True) tests showing PromptDefense.sanitize() leaves newline-based injection patterns intact.
sanitize() only stripped template delimiters and angle brackets, so patterns is_injection_attempt already flagged (\n---\n, \nSystem:, \nIgnore ...) passed through unchanged. Iterate INJECTION_PATTERNS in sanitize() so both methods stay in agreement. Fixes ascherj#64
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
safety/prompt_defense.PromptDefense.sanitize()used to strip only template delimiters and angle brackets, so newline-based patterns thatis_injection_attempt()already flagged (\n---\n,\nSystem:,\nIgnore ...) passed through the sanitizer unchanged. The two methods disagreed: an inputxwhereis_injection_attempt(x)returnedTruecould survivesanitize(x)intact. This PR reuses the existingINJECTION_PATTERNSlist insidesanitize()so both methods reference one canonical list.Issue
Closes #64
Changes
safety/prompt_defense.py:sanitize()now iteratesINJECTION_PATTERNSand replaces each match with a single space viare.sub(..., flags=re.IGNORECASE). Angle bracket stripping is kept as defense-in-depth.tests/unit/test_prompt_defense.py: three reproduction tests from the pre-fix commit on this branch are now plain passing tests (xfail markers removed). Added three new tests:test_sanitize_covers_every_injection_pattern— iteratesINJECTION_PATTERNSso any newly added pattern is automatically covered by both detector and sanitizer.test_sanitize_preserves_prose_mentioning_system— mid-sentence "system" survives untouched.test_sanitize_preserves_multiparagraph_resume— normal resume with newlines round-trips byte-for-byte.Testing
make test-unit) — 37 of 38 pass; the one failure predates this branch (see notes)make test-integration) — didn't run locally (no Postgres/Chroma set up); no integration test files touchedmake lint) — two pre-existing findings on the files I edited, unchanged; my diff introduces nonemake typecheck) — mypy clean onsafety/prompt_defense.pyScreenshots / Demo
N/A — pure library change.
Notes for Reviewers
Design choice — how to neutralize matches: I went with
re.sub(pattern, " ", ...)(single space) because it's length-preserving and doesn't concatenate the surrounding characters. Alternatives I considered were dropping the match entirely ("", could join formerly-separated tokens) or replacing with a visible marker like[REMOVED](more auditable, but changes downstream token counts). Happy to switch if you'd prefer one of those.sanitize()has no callers today:git grep -n "PromptDefense"outsidesafety/prompt_defense.pyand its test file returns nothing. Fixing it is still correct (it's a public API on a safety class), but the safety pipeline may not be wired into the request path — worth a follow-up issue if that hasn't already been raised.Pre-existing failures I saw on
mainbefore touching anything, and confirmed my changes don't introduce:tests/unit/test_prompt_defense.py::TestPromptDefense::test_whitespace_variations_detectedfails onmaintoo. Input"Content\n System : ignore"has spaces before the colon, butINJECTION_PATTERNS[1](\n\s*(?:System|Human|Assistant):) requires the:to immediately follow the role word. Out of scope for Prompt injection defense doesn't sanitize newline characters in user-supplied resume text #64.I001onsafety/prompt_defense.py(import block ordering) — predates this branch.F841intests/unit/test_prompt_defense.py::test_code_blocks_handled(unused local) — predates this branch and lives in a test I didn't modify.