You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何开发可集成到CI/CD的Python代码敏感密钥扫描脚本?

Python代码敏感信息扫描脚本实现指南

核心实现思路

  • 规则匹配优先:先覆盖常见的敏感字段命名模式,比如API_KEY、SECRET_KEY、PASSWORD、ACCESS_TOKEN、DB_PASS这类变量名,再匹配常见密钥的格式特征,比如AWS AK通常是AKIA开头的20位字符,阿里云AK是LTAI开头,JWT是三段base64用点分隔的字符串
  • 排除白名单机制:要提前配置不需要扫描的路径,比如__pycache__、.git、虚拟环境目录、测试用例文件夹,还要支持代码注释里的# nosecret标记跳过指定行的校验
  • 误报过滤:遇到值是环境变量引用(比如os.getenv("XXX"))、占位符字符串(比如"******"、"xxx")、空值的情况直接跳过,避免无效报错

可直接参考的最小实现示例

import re
import os
from typing import List, Tuple

# 配置规则
SENSITIVE_VAR_PATTERNS = [
    re.compile(r'(?i)(api[_-]key|secret[_-]key|password|passwd|db[_-]pass|access[_-]token|auth[_-]token)'),
]
SENSITIVE_VALUE_PATTERNS = [
    re.compile(r'AKIA[0-9A-Z]{16}'), # AWS AK
    re.compile(r'LTAI[0-9A-Za-z]{16}'), # 阿里云 AK
    re.compile(r'^[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*$'), # JWT
]
EXCLUDE_DIRS = {'.git', '__pycache__', 'venv', 'env', 'node_modules'}
SKIP_FLAG = '# nosecret'

def scan_single_file(file_path: str) -> List[Tuple[int, str]]:
    """扫描单个Python文件,返回敏感信息的行号和内容"""
    results = []
    with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
        for line_num, line_content in enumerate(f, 1):
            # 跳过标记忽略的行
            if SKIP_FLAG in line_content:
                continue
            # 匹配敏感变量名,且值不是环境变量/空值/占位符
            var_match = any(p.search(line_content) for p in SENSITIVE_VAR_PATTERNS)
            if var_match:
                # 过滤合法赋值情况
                if 'os.getenv' in line_content or 'os.environ' in line_content:
                    continue
                if line_content.strip().endswith(('""', "''", 'None', '"***"', "'***'")):
                    continue
                results.append((line_num, line_content.strip()))
                continue
            # 匹配硬编码的密钥格式
            value_match = any(p.search(line_content) for p in SENSITIVE_VALUE_PATTERNS)
            if value_match:
                results.append((line_num, line_content.strip()))
    return results

def scan_project(root_path: str) -> None:
    """扫描整个项目目录"""
    has_sensitive = False
    for root, dirs, files in os.walk(root_path):
        # 过滤排除目录
        dirs[:] = [d for d in dirs if d not in EXCLUDE_DIRS]
        for file in files:
            if not file.endswith('.py'):
                continue
            file_path = os.path.join(root, file)
            file_results = scan_single_file(file_path)
            if file_results:
                has_sensitive = True
                print(f"\n发现敏感信息:{file_path}")
                for line_num, content in file_results:
                    print(f"  第{line_num}行:{content}")
    if has_sensitive:
        exit(1)
    else:
        print("未检测到敏感信息")
        exit(0)

if __name__ == '__main__':
    scan_project(os.getcwd())

CI/CD集成适配要点

  • 脚本返回值设置:扫描到敏感信息时返回非0状态码,CI/CD流程会自动识别为失败阻断后续步骤
  • 结果输出格式化:支持输出json、markdown格式的报告,方便接入CI平台的告警展示
  • 增量扫描优化:如果代码仓库很大,可以对接git获取本次提交的变更文件,只扫描变更内容,提升校验速度

优化方向

  • 可以引入熵值计算,对随机字符串的熵值做判断,高熵的字符串大概率是密钥,能识别没有明确命名的硬编码密钥
  • 支持自定义规则配置,用户可以通过yaml文件新增自己业务相关的敏感字段规则,不需要改代码
  • 支持批量忽略历史误报,给每个识别结果生成唯一hash,维护忽略列表直接跳过已知的合法情况

内容的提问来源于stack exchange,提问作者julian_h

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 03:54:02