Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD across contents and paths, upstream package/repo coordinates -> @golem15/msd-core and golem15com/msd-core. Deep links into upstream history, sibling upstream packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is. Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line, package/plugin identity, regenerated lockfile, install-tree fixtures, derived registries and benchmark baseline; migration checksum baseline re-locked (MSD keeps its own install state, so no install had applied the old sums); sort-order and regex-escaped expectations in tests adjusted.
27 lines
2.5 KiB
Markdown
27 lines
2.5 KiB
Markdown
---
|
||
id: 99
|
||
title: Improved Prompt Injection Scanner
|
||
group: v1.34.0 Features
|
||
---
|
||
|
||
**Hook:** `msd-prompt-guard.js`, `msd-read-injection-scanner.js`
|
||
**Script:** `scripts/prompt-injection-scan.sh`, `scripts/base64-scan.sh`
|
||
|
||
**Purpose:** Defense-in-depth detection of prompt injection attempts in planning artifacts and ingested content. Live hooks inline their own pattern subsets for hook independence (they do not import from `security.cts`). The CI scanner (`scanForInjection` in `security.cts`) provides a centralized engine for codebase-wide scanning in tests.
|
||
|
||
**Requirements:**
|
||
- REQ-SCAN-INJ-01: Live hooks MUST detect invisible Unicode characters (zero-width spaces, soft hyphens, Unicode tag block U+E0000–E007F)
|
||
- REQ-SCAN-INJ-02: Live hooks MUST detect known injection patterns (instruction override, role manipulation, system-prompt extraction, fake message boundaries). Base64-decode scanning is a CI-time control (`scripts/base64-scan.sh`), not a live hook — live hooks match a base64-exfiltration phrase regex only, they do not decode.
|
||
- REQ-SCAN-INJ-03: ~~Scanner MUST apply entropy analysis~~ — Entropy analysis (`scanEntropyAnomalies`) was removed in #2198 as dead code (zero production callers; live hooks do not perform entropy analysis). This requirement is deferred pending a maintainable live implementation.
|
||
- REQ-SCAN-INJ-04: Scanner MUST remain advisory-only — detection is logged, not blocking
|
||
- REQ-SCAN-INJ-05: A scanner that could not establish its file list MUST NOT report clean (#3908). The CI scanners (`prompt-injection-scan.sh`, `base64-scan.sh`, `secret-scan.sh`) distinguish four outcomes rather than collapsing them into exit 0:
|
||
|
||
| Outcome | Exit | Meaning |
|
||
|---|---|---|
|
||
| scanned, no findings | `0` | files were in scope and none matched |
|
||
| findings | `1` | the scan's own verdict |
|
||
| nothing in scope | `NO_INPUT` | the diff resolved and was genuinely empty — e.g. a docs-only PR |
|
||
| could not scan | `UNAVAILABLE` | the file list was never established: a bad ref, no repository, or a repository with no commits |
|
||
|
||
Codes come from the exit-code registry ([ADR-3889](adr/3889-process-exit-contract.md)), sourced from `msd-core/bin/shared/exit-codes.sh`, never written into the scripts. Every one is non-zero, so a caller written `if ! scanner; then` behaves identically for a clean scan and trips for everything else — this can turn a false green red, never a red green. `.github/workflows/security-scan.yml` treats *nothing in scope* as a pass and *could not scan* as a failure; previously the latter passed silently, having scanned nothing.
|