Claude Code | | 约 22 分钟 | 8,520 字

Claude Code 安全实践指南

权限控制、敏感信息保护和安全审计的完整方案

为什么要关注安全

Claude Code 拥有强大的能力——它可以读写文件、执行 shell 命令、访问网络。这些能力在提升效率的同时,也带来了安全风险。

想象一下:

  • 它不小心读取了 .env 文件中的 API Key
  • 它执行了一个 rm -rf 命令
  • 它把敏感信息写进了 commit

这些都是真实可能发生的场景。所以我们需要一套完整的安全实践来防范。


权限模式

Claude Code 提供了三种权限模式来控制工具的执行:

模式行为适用场景
ask每次执行前询问用户确认默认模式,最安全
auto-accept自动允许执行信任的操作,提升效率
deny禁止执行危险操作,完全阻止

在 settings.json 中配置

{
  "permissions": {
    "allow": [
      "Read",
      "Glob",
      "Grep",
      "Write(src/**)",
      "Edit(src/**)",
      "Bash(npm run lint)",
      "Bash(npm run test)",
      "Bash(npm run build)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(curl * | bash)",
      "Write(.env*)",
      "Write(*.pem)",
      "Write(*.key)"
    ]
  }
}

权限配置的粒度

权限可以精确到工具 + 参数级别:

{
  "permissions": {
    "allow": [
      "Read",
      "Write(src/**)",
      "Write(tests/**)",
      "Edit(src/**)",
      "Edit(tests/**)",
      "Bash(npm *)",
      "Bash(npx *)",
      "Bash(git status)",
      "Bash(git diff *)",
      "Bash(git log *)",
      "Bash(git add *)",
      "Bash(git commit *)"
    ],
    "deny": [
      "Write(.*)",
      "Write(*.env*)",
      "Bash(git push --force*)",
      "Bash(git reset --hard*)",
      "Bash(rm -rf *)",
      "Bash(sudo *)",
      "Bash(chmod 777 *)"
    ]
  }
}

权限优先级

当 allow 和 deny 冲突时,deny 优先:

{
  "permissions": {
    "allow": ["Write(src/**)"],
    "deny": ["Write(src/config/secrets.ts)"]
  }
}

即使允许写入 src/**src/config/secrets.ts 仍然被禁止。


敏感文件保护

.gitignore 是第一道防线

确保敏感文件不会被 Git 追踪:

# 环境变量
.env
.env.local
.env.production

# 密钥文件
*.pem
*.key
*.p12
*.pfx

# 凭证
credentials.json
service-account.json
*-credentials.json

# IDE 和工具
.claude/settings.local.json

在 CLAUDE.md 中声明禁区

## 安全规则

### 禁止访问的文件
- `.env*` - 环境变量文件
- `*.pem`, `*.key` - 密钥文件
- `credentials.json` - 凭证文件
- `src/config/secrets.ts` - 密钥配置

### 禁止执行的操作
- 不要读取或输出任何 API Key、密码、Token
- 不要执行 `curl | bash` 类型的命令
- 不要修改文件权限(chmod)
- 不要使用 sudo

使用 .claudeignore

类似 .gitignore.claudeignore 可以让 Claude Code 完全忽略某些文件:

# .claudeignore
.env
.env.*
*.pem
*.key
credentials/
secrets/
node_modules/

.claudeignore 忽略的文件,Claude Code 不会读取、不会在搜索结果中出现、也不会被修改。


网络访问控制

Claude Code 可以通过 WebFetch 工具访问网络。在某些环境中,我们需要限制这个能力:

禁止网络访问

{
  "permissions": {
    "deny": [
      "WebFetch"
    ]
  }
}

限制访问域名

在 Hook 中实现域名白名单:

#!/bin/bash
# .claude/hooks/check-url.sh
INPUT="$CLAUDE_TOOL_INPUT"
URL=$(echo "$INPUT" | jq -r '.url // empty')

# 域名白名单
ALLOWED_DOMAINS=(
  "github.com"
  "npmjs.com"
  "developer.mozilla.org"
  "docs.astro.build"
)

if [ -n "$URL" ]; then
  DOMAIN=$(echo "$URL" | awk -F/ '{print $3}')
  ALLOWED=false
  for d in "${ALLOWED_DOMAINS[@]}"; do
    if [[ "$DOMAIN" == *"$d"* ]]; then
      ALLOWED=true
      break
    fi
  done
  if [ "$ALLOWED" = false ]; then
    echo "BLOCKED: 不允许访问域名 $DOMAIN"
    exit 1
  fi
fi
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "WebFetch",
        "hook": {
          "type": "command",
          "command": "bash .claude/hooks/check-url.sh"
        }
      }
    ]
  }
}

审计日志

记录 Claude Code 的所有操作,便于事后审查:

基础审计日志

#!/bin/bash
# .claude/hooks/audit-log.sh
LOG_DIR=".claude/logs"
mkdir -p "$LOG_DIR"

LOG_FILE="$LOG_DIR/audit-$(date +%Y%m%d).log"

TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
TOOL="$CLAUDE_TOOL_NAME"
SESSION="$CLAUDE_SESSION_ID"

echo "[$TIMESTAMP] session=$SESSION tool=$TOOL" >> "$LOG_FILE"

# 记录文件操作
if [ -n "$CLAUDE_FILE_PATH" ]; then
  echo "  file=$CLAUDE_FILE_PATH" >> "$LOG_FILE"
fi

# 记录 Bash 命令(注意脱敏)
if [ "$TOOL" = "Bash" ]; then
  COMMAND=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.command // empty')
  # 脱敏:替换可能的密钥
  SAFE_COMMAND=$(echo "$COMMAND" | sed -E 's/(key|token|password|secret)=[^ ]*/\1=***REDACTED***/gi')
  echo "  command=$SAFE_COMMAND" >> "$LOG_FILE"
fi

配置所有工具都记录日志:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": ".*",
        "hook": {
          "type": "command",
          "command": "bash .claude/hooks/audit-log.sh"
        }
      }
    ]
  }
}

审计日志示例

[2026-03-11 14:23:01] session=abc123 tool=Read
  file=src/components/Header.astro
[2026-03-11 14:23:05] session=abc123 tool=Edit
  file=src/components/Header.astro
[2026-03-11 14:23:08] session=abc123 tool=Bash
  command=npm run lint
[2026-03-11 14:23:15] session=abc123 tool=Bash
  command=git add src/components/Header.astro
[2026-03-11 14:23:16] session=abc123 tool=Bash
  command=git commit -m "feat(header): add search icon"

日志轮转

避免日志文件无限增长:

#!/bin/bash
# .claude/hooks/rotate-logs.sh
LOG_DIR=".claude/logs"

# 删除 30 天前的日志
find "$LOG_DIR" -name "audit-*.log" -mtime +30 -delete

团队安全策略

统一安全配置

在项目的 .claude/settings.json 中定义团队级安全策略:

{
  "permissions": {
    "allow": [
      "Read",
      "Glob",
      "Grep",
      "Write(src/**)",
      "Write(tests/**)",
      "Write(docs/**)",
      "Edit(src/**)",
      "Edit(tests/**)",
      "Bash(npm run *)",
      "Bash(npx *)",
      "Bash(git *)"
    ],
    "deny": [
      "Write(.env*)",
      "Write(*.pem)",
      "Write(*.key)",
      "Write(credentials*)",
      "Bash(rm -rf *)",
      "Bash(sudo *)",
      "Bash(curl * | bash)",
      "Bash(wget * | bash)",
      "Bash(git push --force*)",
      "Bash(git reset --hard*)",
      "Bash(chmod 777 *)",
      "Bash(npm publish*)"
    ]
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": ".*",
        "hook": {
          "type": "command",
          "command": "bash .claude/hooks/audit-log.sh"
        }
      },
      {
        "matcher": "Bash",
        "hook": {
          "type": "command",
          "command": "bash .claude/hooks/safety-check.sh"
        }
      }
    ]
  }
}

安全配置的版本控制

.claude/
├── settings.json          ← 团队共享,提交到 Git
├── settings.local.json    ← 个人配置,不提交
└── hooks/
    ├── audit-log.sh       ← 提交到 Git
    ├── safety-check.sh    ← 提交到 Git
    └── check-url.sh       ← 提交到 Git

.gitignore 中:

.claude/settings.local.json
.claude/logs/

安全检查清单

在项目中使用 Claude Code 之前,过一遍这个清单:

文件安全

  • .gitignore 包含所有敏感文件模式
  • .claudeignore 排除了敏感目录
  • 权限配置禁止写入敏感文件
  • 环境变量通过 .env 管理,不硬编码

命令安全

  • 禁止了危险的 shell 命令
  • 禁止了 sudo 操作
  • 禁止了 curl | bash 模式
  • 限制了 git push --force

网络安全

  • 评估是否需要限制网络访问
  • 如需限制,配置了域名白名单
  • WebFetch 的使用有审计记录

审计

  • 启用了操作审计日志
  • 日志中敏感信息已脱敏
  • 配置了日志轮转策略

团队

  • 安全配置已提交到版本控制
  • 团队成员了解安全策略
  • 定期审查安全配置

常见安全场景

场景 1:防止 API Key 泄露

#!/bin/bash
# .claude/hooks/check-secrets.sh
# 在写入文件前检查是否包含密钥模式

INPUT="$CLAUDE_TOOL_INPUT"
CONTENT=$(echo "$INPUT" | jq -r '.content // .new_string // empty')

# 密钥模式
PATTERNS=(
  'sk-[a-zA-Z0-9]{20,}'
  'AKIA[0-9A-Z]{16}'
  'ghp_[a-zA-Z0-9]{36}'
  'glpat-[a-zA-Z0-9\-]{20,}'
  'xoxb-[0-9]{10,}'
)

for pattern in "${PATTERNS[@]}"; do
  if echo "$CONTENT" | grep -qE "$pattern"; then
    echo "BLOCKED: 检测到可能的密钥/Token,请勿将敏感信息写入文件"
    exit 1
  fi
done

场景 2:限制文件系统访问范围

{
  "permissions": {
    "allow": [
      "Read(src/**)",
      "Read(tests/**)",
      "Read(docs/**)",
      "Read(package.json)",
      "Read(tsconfig.json)",
      "Read(*.config.*)"
    ],
    "deny": [
      "Read(/etc/**)",
      "Read(/home/**/.ssh/**)",
      "Read(~/.aws/**)",
      "Read(~/.config/**)"
    ]
  }
}

场景 3:生产环境保护

#!/bin/bash
# .claude/hooks/protect-production.sh
COMMAND=$(echo "$CLAUDE_TOOL_INPUT" | jq -r '.command // empty')

# 检查是否在操作生产环境
PROD_PATTERNS=(
  "production"
  "prod"
  "--env=prod"
  "deploy.*prod"
)

for pattern in "${PROD_PATTERNS[@]}"; do
  if echo "$COMMAND" | grep -qi "$pattern"; then
    echo "WARNING: 检测到可能影响生产环境的操作"
    echo "命令: $COMMAND"
    echo "如果确认需要执行,请手动在终端中运行"
    exit 1
  fi
done

安全与效率的平衡

安全配置不应该让 Claude Code 变得难以使用。这里有几个平衡的建议:

1. 分层配置

  • 开发环境:宽松一些,提升效率
  • CI 环境:严格一些,确保安全
  • 生产相关:最严格,禁止大部分操作

2. 白名单优于黑名单

与其列举所有危险命令(总会遗漏),不如只允许已知安全的命令:

{
  "permissions": {
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test)",
      "Bash(npm run build)",
      "Bash(git status)",
      "Bash(git diff *)",
      "Bash(git log *)"
    ]
  }
}

3. 渐进式放开

刚开始使用时保持默认的 ask 模式,观察一段时间后,把确认安全的操作加入 allow 列表。


安全不是限制,而是信任的基础。当我们为 Claude Code 建立了清晰的安全边界,我们才能放心地让它发挥全部能力。好的安全实践不会减慢你的速度——它会让你跑得更快、更稳。

评论

加载中...

相关文章

分享:

评论

加载中...