Single source of truth for all HardStop detection patterns. Consumed by: Python plugin (planned), npm package, any third-party tool.
hardstop-patterns/
├── package.json # npm package metadata
├── index.js # npm entry: exports all patterns + check functions
├── index.d.ts # TypeScript type definitions
├── patterns/
│ ├── bash-dangerous.json # Dangerous command patterns
│ ├── bash-safe.json # Safe command patterns (allowlist)
│ ├── read-dangerous.json # Dangerous file read patterns
│ ├── read-sensitive.json # Sensitive file read patterns (warn)
│ ├── read-safe.json # Safe file read patterns
│ └── meta.json # Version, stats, compatibility
├── tests/
│ └── patterns.test.js # Structural, regex, and matching tests
├── .gitignore
├── vitest.config.mjs # Test runner config
├── README.md
├── LICENSE
└── SCHEMA.md # This file
- Consumers can load only what they need (bash-only vs read-only)
- Easier to review PRs that touch one category
- Smaller payloads for tools that only care about one scope
- Git diff is readable per-category
{
"version": "1.0.0",
"scope": "bash",
"type": "dangerous",
"match_mode": "search",
"patterns": [
{
"id": "DEL-001",
"pattern": "(?<!echo\\s)(?<!echo ')(?<!echo \\\")rm\\s+(-[^\\s]*\\s+)*(/home/|~/)",
"message": "Deletes home directory",
"category": "deletion",
"severity": "critical",
"platforms": ["linux", "macos"],
"notes": "Excludes echo/printf which just output strings",
"added": "1.0.0",
"tests": {
"should_match": ["rm -rf ~/", "rm -rf /home/user"],
"should_not_match": ["echo 'rm -rf ~/'", "rm -rf node_modules"]
}
}
]
}{
"version": "1.0.0",
"scope": "bash",
"type": "safe",
"match_mode": "fullmatch",
"patterns": [
{
"id": "SAFE-RO-001",
"pattern": "^ls(?:\\s+.*)?$",
"category": "read_only",
"platforms": ["linux", "macos"],
"added": "1.0.0"
}
]
}{
"version": "1.0.0",
"scope": "read",
"type": "dangerous",
"match_mode": "search",
"patterns": [
{
"id": "CRED-SSH-001",
"pattern": "[/\\\\]\\.ssh[/\\\\]id_rsa$",
"message": "SSH private key (RSA)",
"category": "ssh_keys",
"severity": "critical",
"platforms": ["linux", "macos", "windows"],
"added": "1.0.0"
}
]
}{
"schema_version": "1.0.0",
"patterns_version": "1.0.0",
"stats": {
"bash_dangerous": 180,
"bash_safe": 74,
"read_dangerous": 71,
"read_sensitive": 11,
"read_safe": 92
},
"total": 428,
"regex_notes": {
"lookbehinds": "Some patterns use fixed-length lookbehinds. Supported in Python re, Node.js 16+.",
"fullmatch": "Safe bash patterns use fullmatch semantics (anchored ^...$). JS consumers should use the match_mode field.",
"flags": "All patterns use case-insensitive matching."
},
"compatibility": {
"python": ">=3.8",
"node": ">=16.0.0"
}
}| Field | Required | Type | Description |
|---|---|---|---|
id |
yes | string | Unique ID: PREFIX-NNN (e.g. DEL-001, RSHELL-003) |
pattern |
yes | string | Regex pattern (PCRE-compatible) |
message |
dangerous/sensitive | string | Human-readable block/warn reason |
category |
yes | string | Grouping key (see categories below) |
severity |
dangerous/sensitive | string | critical, high, or medium |
platforms |
yes | string[] | linux, macos, windows |
notes |
no | string | Implementation notes, false positive context |
added |
yes | string | Version when pattern was added |
tests |
no | object | Inline test cases (should_match, should_not_match arrays) |
deletion— rm, find -delete on system/home pathsreverse_shell— bash -i, nc -e, python socketcredential_exfil— curl/wget/scp with sensitive filescredential_read— cat on .ssh, .aws, .env, etc.disk_destruction— dd, mkfs, shred on devicesencoded_execution— base64 decode to shell, evalremote_code_execution— curl|bash, wget|shsystem_damage— chmod 777 /, recursive chownhistory_manipulation— clearing bash historyscheduled_persistence— crontab, at jobsprivileged_operations— sudo with dangerous payloadsshell_wrapper— bash -c, env, xargs hiding dangerous commandscloud_destructive— aws/gcloud/kubectl/docker destroy opsdatabase_destructive— DROP, TRUNCATE, FLUSHwindows_deletion— rd, del, Remove-Item on system pathswindows_registry— reg delete, Run keyswindows_credential— mimikatz, SAM copy, vaultwindows_disk— format, diskpart, bcdeditwindows_security— firewall disable, Defender offwindows_reverse_shell— encoded PowerShell, LOLBinswindows_persistence— schtasks, execution policy bypasswindows_admin— net user /add, admin groupmacos_disk— diskutil erase, partitionmacos_keychain— security dump/delete/exportmacos_timemachine— tmutil delete, disablemacos_directory_services— dscl delete users/groupsmacos_system_security— Gatekeeper, SIP, remote loginmacos_privacy— TCC.db, tccutilmacos_persistence— launchctl, LaunchDaemonsmacos_appdata— Library deletion, defaults delete
ssh_keys— .ssh/id_rsa, id_ed25519, etc.cloud_credentials— .aws/credentials, .azure, gcloudenvironment_files— .env, .env.local, .env.productiontoken_files— credentials.json, secrets.yaml, .npmrccontainer_credentials— .docker/config.json, .kube/configdatabase_credentials— .pgpass, .my.cnfprivate_keys— *.pem, *.p12, *.pfxplatform_credentials— .git-credentials, .gh/hosts.ymlbrowser_credentials— Chrome Login Data, Firefox logins.jsonwindows_credentials— SAM, SYSTEM, NTUSER.DATmacos_credentials— Keychains, TCC.db, authorizationci_cd— .travis.yml, .circleci/config.yml
config_files— config.json, config.yaml, settings.jsonbackup_files— .env.bak, .env.backup, credentials.baksuspicious_names— files with password, secret, token, apikey in name
documentation— README, LICENSE, CHANGELOG, .md, .txt, .rstsource_code— .py, .js, .ts, .go, .rs, .java, .sh, etc.project_config— package.json, tsconfig.json, Cargo.toml, go.mod, Dockerfile, etc.template_files— .env.example, .env.template, .env.sampleweb_assets— .html, .css, .scss, .svgdata_formats— .xml
self_management— HardStop's own operationsread_only— ls, cat, head, tail, pwd, etc.git_read— git status, log, diff, showgit_workflow— add, commit, push, pull, mergeregeneratable_cleanup— node_modules, pycache, distpackage_read— npm list, pip freezewindows_read_only— dir, type, Get-Contentwindows_cleanup— rd node_modulesmacos_read_only— diskutil list, sw_vers, defaults read
| Prefix | Scope |
|---|---|
| DEL- | Deletion patterns |
| RSHELL- | Reverse shells |
| EXFIL- | Credential exfiltration |
| CREAD- | Credential reads (bash) |
| DISK- | Disk destruction |
| ENC- | Encoded execution |
| RCE- | Remote code execution |
| SYSD- | System damage |
| HIST- | History manipulation |
| CRON- | Scheduled/persistence |
| SUDO- | Privileged operations |
| WRAP- | Shell wrappers |
| CLOUD- | Cloud CLI destructive |
| DB- | Database destructive |
| WIN- | Windows-specific |
| MAC- | macOS-specific |
| SAFE- | Safe patterns (all) |
| CRED- | Credential file reads |
| SENS- | Sensitive file reads |
const { checkBashDangerous, checkBashSafe, checkReadDangerous } = require('hardstop-patterns');
// Using check functions (recommended — patterns are pre-compiled and cached)
const result = checkBashDangerous('rm -rf ~/');
if (result.matched) {
console.log(`BLOCKED: ${result.pattern.message}`);
}
// Or access raw pattern data directly
const { bashDangerous } = require('hardstop-patterns');
for (const p of bashDangerous.patterns) {
// p.id, p.pattern, p.message, p.category, p.severity, p.platforms
}import json, re
with open('patterns/bash-dangerous.json') as f:
bash_dangerous = json.load(f)
for p in bash_dangerous["patterns"]:
if re.search(p["pattern"], command, re.IGNORECASE):
print(f"BLOCKED: {p['message']}")- Pattern additions: minor version bump (1.0.0 → 1.1.0)
- Pattern removals or behavioral changes: major version bump (1.0.0 → 2.0.0)
- Metadata-only changes: patch version bump (1.0.0 → 1.0.1)
Python re supports fixed-length lookbehinds only (no variable-length).
JS supports lookbehinds since Node 16 / Chrome 62.
All lookbehinds in this repo use fixed-length patterns for cross-runtime compatibility.
dangerouspatterns usesearch(match anywhere in command)safebash patterns usefullmatch(must match entire command)saferead patterns usesearch(match anywhere in path)- The
match_modefield in each file specifies this
All patterns assume case-insensitive matching (re.IGNORECASE / 'i' flag).