mcpField
D
dcg

dcg

github.com/dicklesworthstone安全6.2k533 次安装今天更新
代码仓库

关于 dcg

dcg 是用 Rust 编写的命令安全钩子,在 AI 编码 Agent 执行命令前拦截已知的破坏性操作。它采用安全模式优先和默认放行策略,并可按类别启用规则包。

主要功能

  1. 01拦截危险 Git 与文件操作
  2. 02模块化数据库和云规则包
  3. 03安全模式优先匹配
  4. 04默认放行未识别命令
  5. 05解释拦截原因并给出建议

适用场景

  1. 01防止 Agent 清除未提交的 Git 更改
  2. 02避免误删文件或存储数据
  3. 03限制容器、Kubernetes 和云端破坏操作

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dicklesworthstone/destructive_command_guard --skill dcg

安装后在 Claude Code 中输入/dcg确认已加载。

详细介绍

DCG — 破坏性命令防护

一款高性能的 Claude Code 钩子,可在破坏性命令执行前拦截并阻止它们。使用 Rust 编写,并通过 SIMD 加速过滤,实现亚毫秒级延迟。

存在的意义

AI 编码 Agent 功能强大,但并非万无一失。它们可能会意外运行破坏性命令:

  • “我来清理一下构建产物” → rm -rf ./src(拼写错误)
  • “我会重置到上次提交” → git reset --hard(破坏未提交的更改)
  • “我来解决合并冲突” → git checkout -- .(丢弃所有修改)
  • “我会清理未跟踪的文件” → git clean -fd(永久删除未跟踪的文件)

DCG 会在危险命令执行前拦截它们,并提供明确说明,阻止命令执行,让你有机会先暂存更改。

关键设计原则

1. 白名单优先架构

先检查安全模式,再检查破坏性模式。这样可确保明确标记为安全的命令不会被误拦截:

git checkout -b feature    →  Matches SAFE "checkout-new-branch"  →  ALLOW
git checkout -- file.txt   →  No safe match, matches DESTRUCTIVE  →  DENY
2. 故障安全默认值(默认允许)

默认允许无法识别的命令。这可确保:

  • 钩子不会破坏正常工作流
  • 只阻止已知的危险模式
  • 新的 git 命令在被明确归类前均可正常使用
3. 零漏报理念

模式集优先考虑绝不放行危险命令,而非避免误报。多几次需要手动确认的提示可以接受;丢失工作成果则不可接受。

会阻止的命令

会破坏未提交工作的 Git 命令
命令原因
git reset --hard破坏未提交的更改
git reset --merge破坏未提交的更改
git checkout -- <file>丢弃文件修改
git restore <file>(不带 --staged)丢弃未提交的更改
git clean -f永久删除未跟踪的文件
会破坏远程历史记录的 Git 命令
命令原因
git push --force / -f覆盖远程提交
git branch -d、--delete、-D、-f、-M、-C删除或强制覆盖用户拥有的分支引用
会破坏暂存工作内容的 Git 命令
命令原因
git stash drop永久删除一个暂存项
git stash clear永久删除所有暂存项
文件系统命令
命令原因
rm -rf(/tmp、/var/tmp、$TMPDIR 之外)递归删除很危险

会允许的命令

安全操作会静默通过:

始终安全的 Git 操作

git status、git log、git diff、git add、git commit、git push、git pull、git fetch、只读分支列表、git stash、git stash pop、git stash list

明确安全的模式
模式安全原因
git checkout -b <branch>创建新分支
git checkout --orphan <branch>创建孤儿分支
git restore --staged <file>仅取消暂存,不会触及工作树
git restore -S <file>--staged 的简写
git clean -n / --dry-run预览模式,不会实际删除
rm -rf /tmp/*临时目录具有临时性
rm -rf $TMPDIR/*Shell 变量形式
安全替代方案:--force-with-lease
git push --force-with-lease   # ALLOWED - refuses if remote has unseen commits
git push --force              # BLOCKED - can overwrite others' work

模块化规则包系统

DCG 使用模块化的“规则包”系统,按类别组织模式:

核心规则包(始终启用)
规则包说明
core.git破坏性 git 命令
core.filesystem临时目录之外的危险 rm -rf
数据库规则包
规则包说明
database.postgresqlPostgreSQL 中的 DROP/TRUNCATE
database.mysqlMySQL/MariaDB 中的 DROP/TRUNCATE
database.mongodbdropDatabase、drop()
database.redisFLUSHALL/FLUSHDB
database.sqliteSQLite 中的 DROP
容器工具包
工具包描述
containers.dockerdocker system prune、docker rm -f
containers.composedocker-compose down --volumes
containers.podmanpodman system prune
Kubernetes 工具包
工具包描述
kubernetes.kubectlkubectl delete namespace
kubernetes.helmhelm uninstall
kubernetes.kustomizekustomize 删除模式
云服务提供商工具包
工具包描述
cloud.aws具有破坏性的 AWS CLI 命令
cloud.gcp具有破坏性的 gcloud 命令
cloud.azure具有破坏性的 az 命令
基础设施工具包
工具包描述
infrastructure.terraformterraform destroy
infrastructure.ansible危险的 ansible 模式
infrastructure.pulumipulumi destroy
系统工具包
工具包描述
system.diskdd、mkfs、fdisk 操作
system.permissions危险的 chmod/chown 模式
system.servicessystemctl stop/disable 模式
其他工具包
工具包描述
strict_git更严格的 git 保护措施
package_managersnpm unpublish、cargo yank
配置工具包
# ~/.config/dcg/config.toml
[packs]
enabled = [
    "database.postgresql",
    "containers.docker",
    "kubernetes",  # Enables all kubernetes sub-packs
]

环境变量

变量描述
DCG_PACKS="containers.docker,kubernetes"启用工具包(逗号分隔)
DCG_DISABLE="kubernetes.helm"禁用工具包/子工具包
DCG_VERBOSE=1详细输出
DCG_COLOR=auto|always|never颜色模式
DCG_BYPASS=1完全绕过 DCG(紧急出口)

安装

快速安装(推荐)
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/main/install.sh?$(date +%s)" | bash

# Easy mode: auto-update PATH
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/main/install.sh?$(date +%s)" | bash -s -- --easy-mode

# System-wide (requires sudo)
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/main/install.sh?$(date +%s)" | sudo bash -s -- --system
从源码安装(需要 Rust Nightly)
cargo +nightly install --git https://github.com/Dicklesworthstone/destructive_command_guard
预编译二进制文件

适用于:Linux x86_64、Linux ARM64、macOS Intel、macOS Apple Silicon、Windows

Claude Code 配置

将以下内容添加到 ~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash|PowerShell|Monitor",
        "hooks": [
          {
            "type": "command",
            "command": "/absolute/path/to/dcg"
          }
        ]
      }
    ]
  }
}

将 /absolute/path/to/dcg 替换为解析后的二进制文件绝对路径。不要只写 dcg:非交互式钩子 Shell 可能不会继承交互式 PATH。在原生 Windows 上,请使用 install.ps1,以便钩子获得 兼容 PowerShell 的绝对命令和明确的 Shell 选择。

重要: 添加钩子后,请重启 Claude Code。

工作原理

处理流程
┌─────────────────────────────────────────────────────────────────┐
│                        Claude Code                               │
│  Agent executes `rm -rf ./build`                                │
└─────────────────────┬───────────────────────────────────────────┘
                      │
                      ▼ PreToolUse hook (stdin: JSON)
┌─────────────────────────────────────────────────────────────────┐
│                          dcg                                     │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐       │
│  │    Parse     │───▶│  Normalize   │───▶│ Quick Reject │       │
│  │    JSON      │    │   Command    │    │   Filter     │       │
│  └──────────────┘    └──────────────┘    └──────┬───────┘       │
│                                                  │               │
│                      ┌───────────────────────────┘               │
│                      ▼                                           │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │                   Pattern Matching                        │   │
│  │   1. Check SAFE_PATTERNS (whitelist) ──▶ Allow if match  │   │
│  │   2. Check DESTRUCTIVE_PATTERNS ──────▶ Deny if match    │   │
│  │   3. No match ────────────────────────▶ Allow (default)  │   │
│  └──────────────────────────────────────────────────────────┘   │
└─────────────────────┬───────────────────────────────────────────┘
                      │
                      ▼ stdout: JSON (deny) or empty (allow)
阶段 1:JSON 解析
  • 从 stdin 读取钩子输入
  • 验证 Claude Code 的 PreToolUse 格式
  • 立即允许非 Bash 工具
阶段 2:命令规范化
  • 去除绝对路径:/usr/bin/git status → git status
  • 保留参数路径
阶段 3:快速过滤
  • 使用 SIMD 加速的子字符串搜索查找 "git" 或 "rm"
  • 不包含这些内容的命令会完全跳过正则表达式(占所有命令的 99% 以上)
阶段 4:模式匹配
  • 首先检查安全模式(匹配时短路 → 允许)
  • 然后检查破坏性模式(匹配时 → 拒绝)
  • 无匹配 → 默认允许

退出代码

代码含义
0命令安全,可以继续
2命令已阻止,不要执行

CLI 用法

手动测试命令:

# Show version with build metadata
dcg --version

# Test a command
echo '{"tool_name":"Bash","tool_input":{"command":"git reset --hard"}}' | dcg

阻止消息示例

════════════════════════════════════════════════════════════════════════
BLOCKED  dcg
────────────────────────────────────────────────────────────────────────
Reason:  git reset --hard destroys uncommitted changes. Use 'git stash' first.

Command:  git reset --hard HEAD~1

Tip: If you need to run this command, execute it manually in a terminal.
     Consider using 'git stash' first to save your changes.
════════════════════════════════════════════════════════════════════════
上下文建议
命令类型建议
git reset、git checkout --"建议先使用 'git stash'"
git clean"建议先使用 'git clean -n' 预览"
git push --force"建议使用 '--force-with-lease'"
rm -rf"手动运行前,请仔细确认路径"

已处理的边缘情况

路径规范化
/usr/bin/git reset --hard          # Blocked
/usr/local/bin/git checkout -- .   # Blocked
/bin/rm -rf /home/user             # Blocked
标志顺序变体
rm -rf /path          # Combined flags
rm -fr /path          # Reversed order
rm -r -f /path        # Separate flags
rm --recursive --force /path    # Long flags

所有变体均已处理。

Shell 变量展开
rm -rf $TMPDIR/build           # Allowed (temp)
rm -rf ${TMPDIR}/build         # Allowed
rm -rf "$TMPDIR/build"         # Allowed
rm -rf "${TMPDIR:-/tmp}/build" # Allowed
暂存区与工作树还原
git restore --staged file.txt    # Allowed (unstaging only)
git restore -S file.txt          # Allowed (short flag)
git restore file.txt             # BLOCKED (discards changes)
git restore --worktree file.txt  # BLOCKED (explicit worktree)
git restore -S -W file.txt       # BLOCKED (includes worktree)

性能优化

DCG 的设计目标是实现零感知延迟:

优化技术
惰性静态变量通过 LazyLock 编译一次正则表达式模式
SIMD 快速拒绝使用 memchr crate 执行 CPU 向量指令
提前退出安全匹配后立即返回
零拷贝 JSONserde_json 直接操作输入缓冲区
零分配使用 Cow<str> 规范化路径
发布配置opt-level="z"、LTO、单个代码生成单元

**结果:**典型命令的执行时间低于 1 毫秒。

模式数量

类型数量
安全模式(白名单)34
破坏性模式(黑名单)16

安全注意事项

DCG 防护的风险
  • 因 git checkout -- 或 git reset --hard 导致意外数据丢失
  • 因强制推送导致远程历史记录被破坏
  • 因 git stash drop/clear 导致暂存内容丢失
  • 因在临时目录之外执行 rm -rf 导致文件系统事故
DCG 无法防护的风险
  • 恶意行为者(可以绕过钩子)
  • 非 Bash 命令(Python/JavaScript 文件写入、API 调用)
  • 已提交但尚未推送的工作
  • 脚本内的命令(不会检查 ./deploy.sh 的内容)
威胁模型

DCG 假设 AI Agent 出于善意,但可能犯错。它能捕获无心之失,而非对抗性攻击。

故障排除

钩子未拦截命令
  1. 确认 ~/.claude/settings.json 中配置了钩子
  2. 重启 Claude Code
  3. 手动测试:echo '{"tool_name":"Bash","tool_input":{"command":"git reset --hard"}}' | dcg
钩子拦截了安全命令
  1. 检查是否存在未覆盖的边缘情况
  2. 提交 GitHub issue
  3. 临时绕过:使用 DCG_BYPASS=1,或手动运行命令

常见问题

问:为什么同时拦截 git branch -d 和 git branch -D?

小写 -d 会检查合并状态,但仍会删除分支名称、上游跟踪配置和便捷的 reflog 引用。这些都属于用户拥有的状态,因此每种删除形式都需要明确批准。请先使用 git branch -vv、git branch --merged 和 git branch --no-merged 进行检查。会检查合并状态的形式有自己的规则 core.git:branch-delete,因此设置 [policy.rules] "core.git:branch-delete" = "ask" 会将其变为审批提示,而 -D(core.git:branch-force-delete)仍会被拒绝。

问:为什么允许 git push --force-with-lease?

Force-with-lease 会在远程仓库包含你尚未看到的提交时拒绝推送,从而防止意外覆盖。

问:为什么拦截临时目录之外的所有 rm -rf?

递归强制删除极其危险。拼写错误或变量错误都可能删除关键文件。临时目录专为短期使用而设计。

问:如果我确实需要运行被拦截的命令,该怎么办?

DCG 会指示 Agent 请求许可。经过审慎考虑后,请在单独的终端中手动运行该命令。

与 Flywheel 集成

工具集成方式
Claude Code原生 PreToolUse 钩子
Agent MailAgent 可以向协调器报告被拦截的命令
BV标记反复触发 DCG 的任务
CASS跨会话搜索 DCG 拦截模式
RUDCG 可防止 agent-sweep 执行破坏性提交

评论

支持 Markdown