Skip to content

fix: add embedded safe defaults to SecurityValidator#932

Open
dalepike wants to merge 1 commit intodanielmiessler:mainfrom
dalepike:fix/security-validator-hardening
Open

fix: add embedded safe defaults to SecurityValidator#932
dalepike wants to merge 1 commit intodanielmiessler:mainfrom
dalepike:fix/security-validator-hardening

Conversation

@dalepike
Copy link

@dalepike dalepike commented Mar 8, 2026

Problem

SecurityValidator.hook.ts looks for security patterns in two locations:

  1. PAI/USER/PAISECURITYSYSTEM/patterns.yaml (user rules)
  2. PAI/PAISECURITYSYSTEM/patterns.example.yaml (system defaults)

v4.0.3 ships neither the PAISECURITYSYSTEM/ directories nor the pattern files. The installer does not create them. The hook's getPatternsPath() returns null, and loadPatterns() returns empty arrays for all pattern categories:

bash: { trusted: [], blocked: [], confirm: [], alert: [] },
paths: { zeroAccess: [], readOnly: [], confirmWrite: [], noDelete: [] },

The result: every fresh v4.0.3 install has a SecurityValidator that runs on every tool call but blocks nothing. Destructive filesystem commands, disk operations, and repo deletions pass through unchecked.

The hook's own docstring (line 35) says "Missing patterns.yaml: Uses default safe patterns" but no such defaults exist in the code.

Fix

Adds a getEmbeddedDefaults() function with hardcoded patterns for catastrophic operations:

  • Blocked: filesystem destruction, disk operations (diskutil eraseDisk/zeroDisk/partitionDisk, dd if=/dev/zero, mkfs), repo deletion (gh repo delete)
  • Confirm: force push (git push --force/-f), hard reset (git reset --hard)
  • Alert: piping remote content to shell (curl | sh/bash)
  • Path protection: SSH keys, GnuPG, AWS credentials, gh token

When no external config is found or parsing fails, loadPatterns() now falls back to these embedded defaults instead of empty arrays.

This is intentionally a minimal safety net. Users who create their own patterns.yaml override these defaults entirely, preserving the existing cascading config design.

What this does NOT change

  • No path changes (the v4.0 PAI/USER/... convention is correct and untouched)
  • No output format changes
  • No schema validation additions
  • No changes outside SecurityValidator.hook.ts

Test plan

  • Fresh install without patterns.yaml: verify destructive commands trigger exit(2)
  • Fresh install without patterns.yaml: verify git push --force triggers confirm prompt
  • With user patterns.yaml present: verify user patterns are used (not embedded defaults)
  • With malformed patterns.yaml: verify fallback to embedded defaults with error logged to stderr

SecurityValidator.hook.ts references patterns.yaml and
patterns.example.yaml for security rules, but v4.0.3 ships
neither the PAISECURITYSYSTEM directories nor the pattern
files. The installer does not create them either. This means
every fresh install has a SecurityValidator that runs on every
tool call but blocks nothing — the hook fails open to empty
arrays.

This adds a getEmbeddedDefaults() function with hardcoded
patterns for catastrophic operations (filesystem destruction,
disk erasure, repo deletion) and common credential paths.
When no external config is found or parsing fails, loadPatterns
now falls back to these embedded defaults instead of empty
arrays.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

2 participants