Hotdry.
security

Claude Code代理层拦截与重写:动态注入环境变量的工程实现

通过HTTP/HTTPS代理层拦截Claude Code请求,实现请求/响应重写技术,动态注入环境变量防止敏感信息泄露的工程化实现细节。

在 AI 辅助编程工具日益普及的今天,Claude Code 作为 Anthropic 推出的代码助手,为开发者提供了强大的编程支持。然而,其安全模型存在一个关键挑战:Claude Code 可以访问终端会话中的所有环境变量,包括敏感的 API 密钥、数据库凭证等机密信息。一旦这些信息被恶意利用或意外泄露,将带来严重的安全风险。本文深入探讨通过 HTTP/HTTPS 代理层拦截 Claude Code 请求,实现请求 / 响应重写技术,动态注入环境变量的工程实现细节。

安全挑战与代理层架构

Claude Code 的安全隔离机制虽然提供了基本的沙箱保护,但在环境变量管理上存在明显缺陷。开发者在终端中设置的ANTHROPIC_API_KEYDATABASE_URLAWS_ACCESS_KEY_ID等敏感信息,会毫无保留地暴露给 Claude Code。更糟糕的是,即使使用.env文件并通过.gitignore排除,只要文件存在于 Claude Code 的工作目录中,就会被读取。

代理层拦截的核心思想是:将凭证存储与凭证使用分离。Claude Code 不再直接持有真实的 API 密钥,而是使用一个无效的或临时的占位符。当请求离开 Claude Code 的沙箱环境时,代理层拦截请求,动态注入真实的凭证,然后将请求转发给目标 API。

Claude Code 支持两种代理配置模式:

  1. HTTP_PROXY 环境变量:适用于 Claude Code 主进程发起的 HTTP 请求

    export HTTP_PROXY=http://127.0.0.1:8080
    export HTTPS_PROXY=http://127.0.0.1:8080
    
  2. sandbox httpProxyPort 配置:适用于沙箱内 bash 命令发起的 HTTP 请求

    {
      "sandbox": {
        "httpProxyPort": 8080
      }
    }
    

这两种配置相互独立,需要根据实际使用场景选择或组合使用。主进程代理适用于 Claude Code 自身的 API 调用,而沙箱代理则覆盖了通过curlwget等命令发起的网络请求。

mitmproxy addon 实现请求重写

mitmproxy 是一个功能强大的 HTTP 代理工具,支持通过 Python addon 实现请求拦截和修改。以下是一个完整的密钥注入 addon 实现:

#!/usr/bin/env python3
"""
Claude Code API密钥注入addon
将无效的API密钥替换为真实的Anthropic API密钥
"""

from mitmproxy import http
import os

class ClaudeCodeAuthInjector:
    def __init__(self):
        # 从环境变量或安全存储中读取真实API密钥
        self.real_api_key = os.getenv("REAL_ANTHROPIC_API_KEY", "")
        self.invalid_api_key = "sk-ant-dummy-invalid-key-123456"
        
        # 需要注入的目标域名
        self.target_domains = [
            "api.anthropic.com",
            "api.anthropic.com:443"
        ]
        
        print(f"ClaudeCodeAuthInjector loaded. Real API key: {self.real_api_key[:10]}...")

    def request(self, flow: http.HTTPFlow) -> None:
        """拦截请求并注入API密钥"""
        
        # 检查是否为Anthropic API请求
        host = flow.request.host
        if host not in self.target_domains:
            return
        
        # 检查请求头中是否包含无效的API密钥
        auth_header = flow.request.headers.get("x-api-key", "")
        if auth_header == self.invalid_api_key:
            # 替换为真实API密钥
            flow.request.headers["x-api-key"] = self.real_api_key
            print(f"Injected real API key for request to {flow.request.path}")
        
        # 可选:记录请求信息用于审计
        self._log_request(flow)

    def response(self, flow: http.HTTPFlow) -> None:
        """拦截响应,可选:过滤敏感信息"""
        
        # 如果响应中包含敏感信息,可以在此处过滤
        content_type = flow.response.headers.get("content-type", "")
        if "application/json" in content_type:
            # 可以解析JSON并过滤特定字段
            pass

    def _log_request(self, flow: http.HTTPFlow):
        """记录请求信息用于安全审计"""
        log_entry = {
            "timestamp": flow.request.timestamp_start,
            "method": flow.request.method,
            "url": flow.request.pretty_url,
            "path": flow.request.path,
            "headers": dict(flow.request.headers),
            "injected": flow.request.headers.get("x-api-key") == self.real_api_key
        }
        # 这里可以写入日志文件或发送到监控系统
        print(f"Request logged: {log_entry}")

# mitmproxy addon注册
addons = [ClaudeCodeAuthInjector()]

这个 addon 的核心逻辑在request()方法中:

  1. 检查请求是否指向目标 API 域名
  2. 检查请求头中是否包含预定义的无效 API 密钥
  3. 如果匹配,将x-api-key头替换为真实的 API 密钥
  4. 记录请求信息用于安全审计

TLS 拦截与证书管理

由于 Claude Code 与 Anthropic API 的通信使用 HTTPS,代理层需要能够解密 TLS 流量。这涉及到中间人(MITM)证书的生成和管理:

# 生成mitmproxy CA证书
mitmproxy --set confdir=~/.mitmproxy

# 导出CA证书供Node.js进程使用
export NODE_EXTRA_CA_CERTS=~/.mitmproxy/mitmproxy-ca-cert.pem

# 临时禁用TLS证书验证(仅用于开发环境)
export NODE_TLS_REJECT_UNAUTHORIZED=0

重要安全考虑NODE_TLS_REJECT_UNAUTHORIZED=0会禁用 TLS 证书验证,这在生产环境中是危险的。建议的替代方案是:

  1. 将 mitmproxy CA 证书添加到系统信任存储

    # macOS
    sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/.mitmproxy/mitmproxy-ca-cert.pem
    
    # Ubuntu/Debian
    sudo cp ~/.mitmproxy/mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/
    sudo update-ca-certificates
    
  2. 使用证书固定(Certificate Pinning) 在 addon 中验证目标服务器的证书指纹,确保不会拦截非预期的流量。

工程化部署与监控

1. 容器化部署

将 mitmproxy 和 addon 打包为 Docker 容器,便于部署和管理:

FROM python:3.11-slim

RUN pip install mitmproxy==10.0.0

WORKDIR /app
COPY claude_auth_injector.py .

# 设置环境变量
ENV REAL_ANTHROPIC_API_KEY=${REAL_API_KEY}
ENV MITMPROXY_PORT=8080

# 生成CA证书
RUN mkdir -p /root/.mitmproxy && \
    mitmproxy --set confdir=/root/.mitmproxy --quiet

EXPOSE ${MITMPROXY_PORT}

CMD ["mitmdump", "-s", "/app/claude_auth_injector.py", "--listen-port", "${MITMPROXY_PORT}"]

2. 性能监控指标

代理层需要监控的关键指标:

# 在addon中添加性能监控
import time
from collections import deque

class PerformanceMonitor:
    def __init__(self, window_size=100):
        self.request_times = deque(maxlen=window_size)
        self.error_count = 0
        self.injection_count = 0
    
    def record_request(self, duration_ms):
        self.request_times.append(duration_ms)
    
    def get_latency_stats(self):
        if not self.request_times:
            return {"avg": 0, "p95": 0, "p99": 0}
        
        sorted_times = sorted(self.request_times)
        avg = sum(sorted_times) / len(sorted_times)
        p95 = sorted_times[int(len(sorted_times) * 0.95)]
        p99 = sorted_times[int(len(sorted_times) * 0.99)]
        
        return {
            "avg_ms": avg,
            "p95_ms": p95,
            "p99_ms": p99,
            "total_requests": len(self.request_times),
            "injections": self.injection_count,
            "errors": self.error_count
        }

3. 故障恢复策略

代理层作为关键基础设施,需要实现高可用:

  • 健康检查端点:在代理上暴露/health端点,返回服务状态
  • 自动重启机制:使用 systemd 或 supervisor 监控进程状态
  • 连接池管理:为上游 API 连接实现连接池,避免频繁建立 TLS 连接
  • 降级策略:当代理故障时,可以回退到直接连接(需要评估安全风险)

安全最佳实践

1. 密钥管理

  • 使用 HashiCorp Vault、AWS Secrets Manager 或 Azure Key Vault 存储真实 API 密钥
  • 定期轮换 API 密钥,并在 addon 中实现密钥自动更新
  • 为不同的环境(开发、测试、生产)使用不同的密钥

2. 访问控制

  • 限制代理服务的网络访问,只允许来自 Claude Code 沙箱的流量
  • 实现基于 IP 或客户端证书的认证
  • 记录所有注入操作,用于安全审计和异常检测

3. 请求验证

  • 验证请求来源,确保只有合法的 Claude Code 实例可以使用代理
  • 实施速率限制,防止滥用
  • 检查请求内容,过滤潜在的恶意负载

实际部署示例

以下是一个完整的部署脚本,展示了如何配置 Claude Code 使用代理层:

#!/bin/bash
# deploy_claude_proxy.sh

# 1. 启动mitmproxy容器
docker run -d \
  --name claude-proxy \
  -p 8080:8080 \
  -e REAL_ANTHROPIC_API_KEY=$(vault read -field=value secret/anthropic/api-key) \
  -v ./claude_auth_injector.py:/app/claude_auth_injector.py \
  claude-proxy:latest

# 2. 配置Claude Code环境变量
export HTTP_PROXY=http://localhost:8080
export HTTPS_PROXY=http://localhost:8080
export ANTHROPIC_API_KEY="sk-ant-dummy-invalid-key-123456"

# 3. 设置Node.js TLS配置
export NODE_EXTRA_CA_CERTS=/path/to/mitmproxy-ca-cert.pem

# 4. 启动Claude Code
claude --project ./my-project

总结

通过 HTTP/HTTPS 代理层拦截 Claude Code 请求并动态注入环境变量,是一种有效的安全防护模式。这种架构实现了以下几个关键优势:

  1. 凭证隔离:敏感 API 密钥永远不会进入 Claude Code 的上下文
  2. 最小权限:Claude Code 只能使用代理层允许的凭证
  3. 集中审计:所有 API 请求都经过代理层,便于监控和审计
  4. 灵活控制:可以在代理层实现复杂的访问控制策略

然而,这种方案也带来了额外的复杂性:需要管理 TLS 证书、维护代理服务、处理性能开销。在实际部署中,需要根据组织的安全要求和资源情况,权衡利弊。

随着 AI 编程助手的普及,类似的安全挑战会越来越多。代理层拦截模式不仅适用于 Claude Code,也可以扩展到其他 AI 辅助工具,为组织提供一个统一的安全管控层。

资料来源

  1. Formal 博客:使用代理隐藏 Claude Code 的秘密(https://www.joinformal.com/blog/using-proxies-to-hide-secrets-from-claude-code/)
  2. mitmproxy 官方文档和 addon 示例(https://github.com/mitmproxy/mitmproxy)
查看归档