Hard-deny: PowerShell patterns + drift-proof the label list
Four new compiled-in hard-deny rules covering PowerShell + cmd.exe catastrophic patterns (mirror of the POSIX 10): - Remove-Item / del / rd / ri / rm / erase / rmdir targeting C:\ or user home / appdata - Format-Volume / Clear-Disk with any flag (= an invocation, not a Get-Help lookup) - iwr | iex pipe form (PowerShell web-to-execute) - iex (irm ...) parenthesized form Universal application — no shell-aware scoping yet. PS cmdlet identifiers are distinctive enough that bash false-positives are vanishingly unlikely. Shell-aware policy scoping remains a known follow-up. Drift-proof the "Always blocked" label list: backend now exposes hard_deny_rules() via a new mcp_hard_deny_labels Tauri command, and PolicyTab loads it at mount instead of hardcoding the list. Avoids the 11→15 manual sync that would have been needed (and that had already drifted twice this week). cargo test --lib: 138 passed; 0 failed (118 prior + 20 new fuzz cases for rules 11-14; hard_deny_rules_count bumped 10 → 14). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f3ab54252e
commit
5b970f8b48
6 changed files with 264 additions and 16 deletions
26
memory.md
26
memory.md
|
|
@ -52,6 +52,32 @@ Durable memory for this project. Read at session start, update before session en
|
|||
|
||||
## Session log
|
||||
|
||||
### 2026-05-26 — Hard-deny: PowerShell patterns + label list de-duplicated
|
||||
|
||||
Mirrors the POSIX hard-deny rules with their Windows/PowerShell equivalents. Four new patterns:
|
||||
|
||||
1. **`Remove-Item` / `del` / `rd` / `ri` / `rm` / `erase` / `rmdir` targeting `C:\` / `~` / `$HOME` / `$env:USERPROFILE` / `$env:APPDATA`.** Covers the canonical `Remove-Item -Recurse -Force C:\` along with bare `del C:\` and `rd /S /Q ~`. PS aliases vary per environment so the alternation is wide.
|
||||
2. **`Format-Volume` / `Clear-Disk` with any flag.** Bare cmdlet mentions (e.g. `Get-Help Format-Volume`) are fine; presence of `-DriveLetter` / `-Number` / similar means an actual invocation.
|
||||
3. **`iwr|iex` pipe form** — `Invoke-WebRequest`/`Invoke-RestMethod`/`iwr`/`irm`/`curl.exe` piped into `Invoke-Expression`/`iex`. The PS web-to-execute primitive. (`curl` in PS land is an alias for `Invoke-WebRequest` which doesn't pipe-string into anything bash-like; the actual `curl.exe` binary does, hence the literal `curl\.exe`.)
|
||||
4. **`iex (irm ...)` parenthesized form.** More common than the pipe form in real install one-liners.
|
||||
|
||||
**Universal application — no shell-aware policy scoping yet.** PS cmdlet names (`Remove-Item`, `Format-Volume`, `iwr`, `iex`) are distinctive enough that a bash session triggering one is virtually impossible. The "scope rules by `shellKind` of the target pane" work is a known follow-up but doesn't block this.
|
||||
|
||||
**Label list de-duplicated.** `PolicyTab.tsx` previously hardcoded the 10 POSIX labels. Adding PS rules would have forced updating both sides — and the comment in the new `mcp_hard_deny_labels` Tauri command notes it had already drifted from the backend twice this week. Now: backend is the SoT, frontend calls `mcpHardDenyLabels()` at panel mount. "Always blocked" section now renders all 14 labels live from the backend.
|
||||
|
||||
**Tests:** 20 new fuzz cases (Rule 11–14), 3-5 positive + 1-2 negative each. `hard_deny_rules_count` bumped from 10 → 14. **138 passed; 0 failed** on Windows.
|
||||
|
||||
**Notes for next time someone adds a hard-deny pattern:**
|
||||
|
||||
- Update only `HARD_DENY_PATTERNS` and `hard_deny_rules_count`. The UI list auto-syncs via the Tauri command. README's mention of "10 patterns" is now also drift-prone but lower-stakes.
|
||||
- PowerShell cmdlets are identified with `-` in the middle (`Remove-Item`). `\bRemove-Item\b` works because the `\b` anchors are between word and non-word chars (R/string-start, m/non-word-after) — the `-` in the middle is fine.
|
||||
- Common PS quoting forms not yet caught (filed as follow-up if it bites): single-quoted paths (`Remove-Item -Recurse -Force 'C:\'`) and trailing flags after the path (`Remove-Item -Recurse -Force C:\ -Confirm:$false`). The regex anchor requires path → whitespace → end/operator/comment; flag-after-path doesn't fit. Common attacker copy-paste forms put the path last, so this is real-world-fine.
|
||||
|
||||
Open follow-ups specific to this session:
|
||||
|
||||
- **Shell-aware policy scoping.** Today PS rules apply universally (low false-positive risk but architecturally fuzzy). Per-leaf-shellKind discrimination would let users `Allow write_pane(*) on bash` while still gating PS. Memory'd long-standing follow-up.
|
||||
- **README drift.** README's "10 hard-deny patterns" mention is stale. Either remove the count or rewrite to enumerate via a build-time script. Low priority.
|
||||
|
||||
### 2026-05-26 — Hard-deny rework: fix latent enforcement gaps surfaced by PR-4
|
||||
|
||||
Re-enabling the policy test module in PR-4 (the `policy_with` compile fix) exposed **16 pre-existing test failures**. Triaged: 2 wrong assertions, 14 real bugs. Fixed all in one focused pass on `mcp_policy.rs`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue