Skip to content

Add security/prompt_injection_firewall skill - #267

Open
mrmasa88 wants to merge 1 commit into
ARPAHLS:mainfrom
mrmasa88:feat/issue-46-prompt-injection-firewall
Open

Add security/prompt_injection_firewall skill#267
mrmasa88 wants to merge 1 commit into
ARPAHLS:mainfrom
mrmasa88:feat/issue-46-prompt-injection-firewall

Conversation

@mrmasa88

@mrmasa88 mrmasa88 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds security/prompt_injection_firewall — a deterministic, offline-only pre-flight scanner that inspects untrusted text before an agent consumes it. Zero network, zero keys; every response carries offline: true. There is no auditing model in the loop, so there is nothing for an injection to hijack. This also opens the new security category.

Detectors: hidden text incl. HTML and markdown comments, zero-width/bidi/tag characters, variation-selector (emoji) smuggling, confusables skeleton for homoglyphs, and bounded nested decoding (base64/hex/percent, depth <= 3). The instruction-override lexicon lives in kb/injection_patterns.json (17 patterns) alongside a 221-entry kb/confusables.json — all self-authored with provenance, no third-party corpus import. False-positive control via mention-vs-use downgrade plus a corroboration rule; sensitivity: strict|balanced|lenient (default balanced), with a floor that fails a lone critical exfiltration hit at every level. Output keeps the issue-spec fields exactly and adds risk_level / findings[] / offline / sensitivity.

Fixes #46

Type of change

  • New skill

Testing

black / flake8 clean; bundle 26 passed; repo suite 179 passed; sync_extras.py --check clean; no stale compliance/... references; no LLM/network surface outside negative assertions.

@rosspeili

Copy link
Copy Markdown
Contributor

Thanks @mrmasa88, this was a good start as expected when following the AI native workflow from earlier today. Some things to address before merge:

The heuristic core is solid and useful as a Layer-1 trust-boundary scanner, but I would remove the Gemini use_llm_evaluator path from v0.1**, sending untrusted text to a cloud LLM breaks the offline/private posture we refreshed on #46. Happy path = zero network, zero keys. Add offline: true (or equivalent) on responses.

Coverage is a good base but not complete yet. Still add detectors + golden tests for: homoglyphs/confusables, variation-selector / emoji smuggling, markdown/HTML comments actually wired, and at least one nested encoding case. Include one false-positive fixture so the lexicon isn’t hair-trigger. Overal, think about it, and discuss with your model to see what kind of protection a prompt injection firewall could have locally, then pass your insights to the worker model.

On category, I have a feeling this could be under security later, but compliance is good for now as requested from the issue, need to think about it.

Some minor things

  • Add examples/prompt_injection_firewall_demo.py (local execute) + row in examples/README.md
  • Point docs/usage/agent_loops.md at that example (not catalog-only)
  • Update docs/usage/install_extras.md (skill row + compliance list)
  • Complete manifest outputs / parameter defaults, prefer from .firewall import … over sys.path hacks
  • Keep green: black / flake8, bundle tests, test_registry_docs, test_card_ui_schema, python scripts/sync_extras.py --check, these are already green and correctly formatted, make sure they are run again before your next commit just to be sure after any changes.

on PR process

Since this was automatically opened by the agent, it's ok, but as with the previous PR notice, please try to manually open PRs from your fork, and not let the agent to do it. Agents can commit and push to your fork, from where it is recommended you manually open PR, review the code one last time before PR, and use PR template in content block, short is fine, eg. skip empty N/A noise, also don’t include “Made with Cursor.”

Ping when updated and I’ll re-review and merge if green. This is good as a v0.1. In short, I would take some time to think, or discuss with AI, what kind of practices and methods we should use to run this locally without relyig on external models to review prompts, considering if prompt injection is found, it can harm also the auditing model. There was a good repo karpathy shared with context about prompt injection patterns and types that could be used as local reference set, similar to wallet screening or mica skills. Just an idea, don't take it by word, maybe you find a better format. <3

@mrmasa88

mrmasa88 commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

Hey! @rosspeili

Updated per your review — LLM path fully removed (offline-only, offline: true on every response), all five coverage items added with golden tests (homoglyphs via confusables skeleton, variation-selector smuggling, HTML+markdown comments wired, nested base64 at depth 2, and a false-positive fixture: a blog visibly quoting attack strings passes at balanced). Lexicon moved to kb/injection_patterns.json — all 17 patterns self-authored with source provenance, so no external-corpus licensing question. Minors done: demo + examples row, agent_loops points at the example, install_extras updated, package-relative imports. Sensitivity renamed to strict/balanced/lenient. All green locally — ready for re-review.

One housekeeping note: the first commit (5b5fa4c, from the auto-opened PR) still carries the Co-authored-by: Cursor trailer — the new commit is clean. If you squash-merge, feel free to drop it from the message; or if you'd rather I rewrite the branch for clean history, happy to do that instead. Your call.

Warm regards,

Masa

@rosspeili

Copy link
Copy Markdown
Contributor

Thanks @mrmasa88, this is clearly better <3

I’d still take a hit on:

  1. Rebase onto main and fix the CHANGELOG.md conflict (keep both Unreleased lines: citation + this skill).
  2. Manifest defaults, JSON Schema default for sensitivity (balanced) and input_mode (auto).
  3. Imports, drop the importlib fallback, keep from .firewall import … only.
  4. Unicode KB, expand kb/confusables.json a bit beyond the small curated set (more Latin/Cyrillic/Greek lookalikes used in jailbreak samples - check a few articles or datasets on prompt injection cases) + 1–2 extra golden cases.
  5. Encoding coverage, add golden tests for nested/hex and URL-encoded smuggling (base64 depth-2 is there, close the other decode paths).
  6. Sensitivity, either make lenient still fail on lone critical exfil, or call that out explicitly in instructions/docs so operators aren’t surprised.
  7. Maintainer test, add tests/skills/compliance/test_prompt_injection_firewall.py (loader + a couple execute paths) alongside the bundle suite.
  8. Squash, drop the Cursor co-author trailer from the first commit message when merging. (I would also disable from cursor settings, or explicitly tell Cursor that the only author is your github username and email, no co authors, especially no Cursor).

Ping after that and we can merge as v0.1. <3

@mrmasa88
mrmasa88 force-pushed the feat/issue-46-prompt-injection-firewall branch from 4529dee to f482880 Compare July 28, 2026 08:14
@mrmasa88

Copy link
Copy Markdown
Contributor Author

Hey! @rosspeili

Updated — all eight addressed:

  1. Rebased onto main; both [Unreleased] lines kept (citation [RFC]: CITATION.cff + Zenodo concept DOI for formal Skillware citation #269 + this skill).
  2. Schema defaults added: sensitivity: balanced, input_mode: auto.
  3. kb/confusables.json expanded to 221 self-authored Latin/Cyrillic/Greek/fullwidth/math-alphanumeric mappings (still no verbatim corpus import), plus two golden cases (Greek override, mixed-script) asserting the skeleton still resolves to the lexicon pattern.
  4. Encoding goldens added: hex-of-base64, URL percent-encoding, and percent-of-base64 nested.
  5. Went with the strict option — a lone critical exfiltration finding now fails at every sensitivity including lenient (floor bypasses corroboration), with a golden test and a one-line note in both instructions and the catalog page.
  6. Added tests/skills/compliance/test_prompt_injection_firewall.py (loader + execute paths) alongside the bundle suite.
  7. Squashed to a single commit — the Cursor co-author trailer is gone from the history entirely, and I've turned off Cursor's commit/PR attribution settings so it won't come back.

One thing I want to flag rather than quietly diverge on — item 3: I removed importlib completely, but I couldn't get to relative-import-only. SkillLoader exec's skill.py as a flat module with no package parent, so from .firewall import ... raises ImportError under the loader. It now tries the relative import first and only falls back to a sibling import when there's no package parent (same shape as office/pdf_form_filler). If you'd rather have zero sys.path touching, the clean fix is folding firewall.py into skill.py — happy to do that if you prefer it, just say the word.

Green locally: black/flake8 clean, bundle 26 passed, repo suite 179 passed, sync_extras --check clean, no LLM/network references outside the negative assertions.

Warm regards,

Masa

@rosspeili

Copy link
Copy Markdown
Contributor

Thanks @mrmasa88, re-reviewed the amended branch, re-ran the skill locally, and this now makes sense to me as a solid local/offline v0.1 for 46. From my side, I don’t see another functional blocker in the current shape.

One structural point to decide before merge is category:

  • Semantically, I think this belongs under security/ more than compliance/.
  • If we want that now, let’s do it cleanly in this PR with the full category move and matching docs/index updates.
  • If we want to keep this PR narrow, I’m also fine merging it now under compliance/ and tracking a later move once we formalize security/ as a top-level home for guardrail / hardening skills.

One nuance I noticed in live smokes

Quoted critical exfil phrases in benign explanatory prose can still trip unsafe and get sanitized, so the mention-vs-use downgrade is not yet as forgiving there as it is for quoted negation strings. I don’t see that as a merge blocker for this trust-boundary scanner, but it is the main thing I’d tune next, just to keep in mind for next upgrades.

Follow-up upgrade references for next iterations

Again, not blockers for v0.1, but good next upgrades:

  1. Broaden mention-vs-use handling for quoted critical exfil phrases in clearly explanatory prose, without weakening hidden/encoded detections.
  2. Add a small realistic fixture corpus: benign security-writing samples, docs/blog/tutorial prose, and adversarial payload sets beyond unit-style goldens.
  3. Return a bit more operator-facing metadata for encoded findings (decode chain/type/layers, maybe removed-span count) to improve auditability.
  4. Expand hidden-channel coverage over time (CSS class-driven hiding, more metadata channels, richer HTML hiding heuristics) while keeping false positives controlled.
  5. Add a short docs section on recommended deployment pattern: run before RAG chunk injection, HTML/PDF summarization, email/chat ingestion, and tool/MCP output handoff.
  6. If/when the repo grows a security/ category, this is a strong candidate to be one of the reference skills there.

Net: I’m happy with this as v0.1. Nice work. <3 Let me know if you wanna move to security or keep in compliance for now and move later, eg. in next upgrade. We can merge as is.

@mrmasa88
mrmasa88 force-pushed the feat/issue-46-prompt-injection-firewall branch from f482880 to 07050c5 Compare July 29, 2026 09:31
@mrmasa88 mrmasa88 changed the title Add compliance/prompt_injection_firewall skill Add security/prompt_injection_firewall skill Jul 29, 2026
@mrmasa88

Copy link
Copy Markdown
Contributor Author

Hey! @rosspeili

Done — moved to the new security category. security/prompt_injection_firewall is now the first entry under a ## Security section in the catalog (placed between Compliance and Dev Tools), described as offline, local-first defense for untrusted input before it reaches model context.

Carried the rename through everything: bundle path and skills/security/__init__.py, manifest name and category field, catalog page incl. the Domain line and recommended install string, card fixture filename, the loader test (now under tests/skills/security/), agent_loops, both install_extras tables, the demo example, and the CHANGELOG entry. Extras regenerated via sync_extras.pysecurity_prompt_injection_firewall in, compliance_prompt_injection_firewall out. Left the compliance/pii_masker cross-references alone since that skill genuinely lives there.

All green: black/flake8 clean, bundle 26 passed, repo suite 179 passed, sync_extras --check clean, no stale references. Amended into the single commit so the history stays clean. Ready when you are — and looking forward to the upgrade issue.

Warm regards,

Masa

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[New Skill]: Prompt Injection Firewall

2 participants