关于 codeprobe-security
codeprobe-security 是用于检查源代码中常见安全漏洞的技能,适合进行安全审查的项目。它分析代码本身,不扫描依赖项中的已知漏洞。
主要功能
- 01检测注入风险
- 02检查身份验证与授权
- 03查找 XSS 和 CSRF 问题
- 04审查批量赋值与访问控制
- 05识别配置风险
- 06使用 SEC 前缀标记发现
适用场景
- 01检查路由是否缺少身份验证
- 02检查查询是否使用不安全的用户输入
- 03查找未转义的用户内容
- 04检查配置中的暴露密钥
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ machineroom-dev/ codeprobe --skill codeprobe-security安装后在 Claude Code 中输入/codeprobe-security确认已加载。
详细介绍
独立模式
如果直接调用(而非通过协调器调用),必须先:
- 读取
../codeprobe/shared-preamble.md(相对于此 SKILL.md 的位置解析,即同级的codeprobe技能目录,而非用户的项目),了解输出约定、执行模式和限制。 - 根据项目的技术栈,从
../codeprobe/references/(按相同方式解析)加载适用的参考文件。 - 除非用户另有指定,否则默认使用
full模式。
安全漏洞扫描器
领域范围
此子技能可检测以下类别的安全漏洞:
- 注入 — SQL 注入、命令注入、LDAP/NoSQL 注入
- 身份验证与授权 — 缺少身份验证、弱凭据、硬编码密钥、JWT 问题
- 跨站脚本攻击(XSS) — 未转义的输出、不安全的 HTML 渲染
- 批量赋值 — 未受保护的模型属性赋值
- 跨站请求伪造(CSRF) — 缺少令牌、未受保护的状态更改路由
- 不安全的反序列化 — 对不可信数据进行不安全的反序列化
- 敏感数据泄露 — 日志中的密钥、已提交的 .env 文件、泄露的堆栈跟踪
- 访问控制失效 — IDOR、缺少策略/门禁检查
- 安全配置错误 — 生产环境中启用调试模式、过于宽松的 CORS、默认凭据
不会标记的内容
- 受 IP 限制访问的内部管理工具 — 这类工具的威胁模型不同,访问限制可能是有意设置的。
- 使用硬编码值的测试文件 — 使用虚假凭据、令牌和 API 密钥的测试固件是预期且恰当的。
- 明确标记为仅用于开发的配置文件(例如,
.env.example、docker-compose.dev.yml、tests/fixtures/中的文件)。 - 存在已知 CVE 的依赖项 — 此子技能分析源代码,而非依赖清单。请使用专用工具(例如,
npm audit、composer audit)扫描依赖项。
检测说明
注入
| ID 前缀 | 检测内容 | 检测方法 | 严重性 |
|---|---|---|---|
SEC | 使用字符串拼接/插值的原始 SQL | 搜索 SQL 关键字(SELECT、INSERT、UPDATE、DELETE、WHERE)与字符串拼接(.、+、f"、${}、"${)、模板字面量或变量插值同时出现的情况。检查用户输入是否未经参数化就进入查询字符串。 | 严重 |
SEC | 使用用户输入的 DB::raw() / 原始查询 | 搜索 DB::raw()、DB::select(DB::raw(、knex.raw()、sequelize.literal()、cursor.execute(f" 及类似的原始查询方法。如果参数包含可能来自用户输入(请求参数、表单数据、查询字符串)的变量,则应标记。 | 严重 |
SEC | 使用未经清理的输入构造 Shell 命令 | 搜索 exec()、system()、shell_exec()、popen()、subprocess.call()、subprocess.run()、child_process.exec()、反引号运算符。如果命令字符串包含来自用户输入的变量,且未经过转义或允许列表验证,则应标记。 | 严重 |
SEC | LDAP/NoSQL 注入向量 | 搜索通过字符串拼接构造 LDAP 过滤器,以及在 $where、$regex 或其他接受任意表达式的运算符中使用用户输入构造 MongoDB 查询的情况。 | 严重 |
身份验证与授权
| ID 前缀 | 检测内容 | 检测方法 | 严重性 |
|---|---|---|---|
SEC | 修改数据的路由缺少身份验证中间件 | 扫描路由定义(例如,Route::post()、router.post()、@app.post())中的 POST/PUT/PATCH/DELETE 端点。检查是否应用了身份验证中间件。标记所有没有任何身份验证层却会修改数据的路由。 | 严重 |
SEC | 仅在视图/前端进行角色检查,后端未检查 | 搜索前端模板或 JavaScript 中的角色/权限检查(例如,v-if="user.isAdmin"、{user.role === 'admin' && ...}),并确认对应的后端端点也执行了该检查。若后端未检查,则标记。 | 重大 |
SEC | 在源代码中硬编码机密/API 密钥 | 搜索以下模式:api_key = "..."、secret = '...'、password = "..."、token = '...'、AWS_SECRET、STRIPE_KEY、Bearer 令牌等。排除 .env.example 文件和测试夹具。检查是否有高熵字符串被赋值给名称类似机密的变量。 | 严重 |
SEC | 密码策略薄弱 | 查找用户注册/密码更改逻辑。检查密码验证是否强制要求最小长度(8 个字符以上)、复杂度,或是否使用验证库。如果接受密码时没有任何验证规则,则标记。 | 重大 |
SEC | JWT 未设置过期时间 | 搜索 JWT 创建/签名代码。检查载荷是否包含 exp(过期时间)声明。标记未设置过期时间,或过期时间过长(访问令牌超过 24 小时)的 JWT。 | 重大 |
跨站脚本攻击(XSS)
| ID 前缀 | 检测内容 | 检测方法 | 严重性 |
|---|---|---|---|
SEC | Laravel Blade 中使用 {!! !!}(未转义输出)输出用户数据 | 在 .blade.php 文件中搜索 {!! ... !!}。检查其中的内容是否来自用户输入、存储用户提供的 HTML 的数据库字段或请求数据。排除静态内容和仅限受信任管理员使用的字段。 | 重大 |
SEC | React 中使用 dangerouslySetInnerHTML 输出不受信任的数据 | 在 .jsx/.tsx 文件中搜索 dangerouslySetInnerHTML。检查 __html 值是否来自用户输入、未经清理的 API 响应,或任何未经 DOMPurify 或等效工具明确清理的来源。 | 重大 |
SEC | Vue 中使用 v-html 输出不受信任的数据 | 在 .vue 文件中搜索 v-html 指令。执行与上述相同的分析;如果绑定值可能包含未经清理的用户输入,则标记。 | 重大 |
SEC | 缺少 Content-Security-Policy | 检查中间件、Web 服务器配置或 meta 标签中是否设置了 CSP 标头。如果项目中任何位置都未配置 CSP,则将其标记为纵深防御方面的缺口。 | 次要 |
批量赋值
| ID 前缀 | 检测内容 | 检测方法 | 严重性 |
|---|---|---|---|
SEC | Laravel 模型未定义 $fillable 或 $guarded | 搜索 Eloquent 模型类(继承 Model 的类)。检查每个模型是否定义了 $fillable(允许列表)或 $guarded(阻止列表)属性之一。标记两者都未定义的模型。 | 重大 |
SEC | 将 $request->all() 用于创建/更新 | 搜索 $request->all()、request.body(未进行解构),以及直接传入 Model::create()、Model::update()、Model::fill() 或 ORM 创建/更新方法的 **request.data。将其标记为批量赋值漏洞。 | 严重 |
跨站请求伪造(CSRF)
| ID 前缀 | 检测内容 | 检测方法 | 严重性 |
|---|---|---|---|
SEC | 未包含 CSRF 令牌的表单 | 搜索带有 method="POST"(或 PUT/PATCH/DELETE)的 <form 标签。检查表单是否包含 CSRF 令牌字段(@csrf、csrf_token()、csrfmiddlewaretoken、_token)。标记缺少令牌的表单。 | 重大 |
SEC | 缺少适当身份验证、会修改状态的 API 路由 | 检查缺少 CSRF 保护和身份验证中间件的 API 路由(POST/PUT/PATCH/DELETE)。使用令牌身份验证的无状态 API 没问题;未包含 CSRF 令牌的基于会话的 API 则不行。 | 重大 |
不安全的反序列化
| ID 前缀 | 检测内容 | 检测方法 | 严重性 |
|---|---|---|---|
SEC | 对用户输入调用 unserialize() | 搜索 unserialize()(PHP)、pickle.loads()(Python)、ObjectInputStream(Java)、Marshal.load(Ruby)。当输入来源由用户控制(请求正文、Cookie、查询参数、上传文件)时进行标记。 | 严重 |
SEC | 未经验证的 JSON.parse() 被用于类似 eval 的上下文 | 搜索对外部数据调用 JSON.parse() 的情况,其中解析结果被传递给 eval()、Function()、setTimeout(string),或用于动态构造代码。标记类似 eval 的用法,而不是 JSON.parse 本身。 | 重大 |
敏感数据泄露
| ID 前缀 | 检测内容 | 检测方法 | 严重性 |
|---|---|---|---|
SEC | 在日志语句中记录密码或令牌 | 搜索包含名为 password、token、secret、key、credential、auth 或类似变量的日志调用(Log::、logger.、console.log、print、logging.)。当敏感数据被写入日志时进行标记。 | 严重 |
SEC | 将 .env 提交到 git | 检查 .gitignore 是否包含 .env。如果仓库中存在 .env 且未被 git 忽略,则标记为严重问题。还要检查是否提交了 .env.production、.env.staging。 | 严重 |
SEC | 配置文件中使用密钥,而非环境变量 | 搜索配置文件中的硬编码凭据、API 密钥、数据库密码。标记那些本应来自环境变量、却硬编码在已跟踪配置文件中的值。 | 重大 |
SEC | 生产配置中的错误消息泄露堆栈跟踪 | 检查错误/异常处理配置。查找 APP_DEBUG=true、DEBUG=True、display_errors=On,或会在响应中暴露堆栈跟踪、文件路径或 SQL 查询的自定义错误处理程序。如果这些内容出现在生产配置中,则进行标记。 | 重大 |
访问控制失效
| ID 前缀 | 检测内容 | 检测方法 | 严重性 |
|---|---|---|---|
SEC | IDOR——使用用户提供的 ID,却未检查资源所有权 | 搜索用于获取资源的路由参数或请求参数(例如 $request->id、params.id、request.args.get('id')),检查是否验证了已通过身份验证的用户拥有该资源。查找没有 where('user_id', auth()->id()) 或策略检查的 Model::find($id)。 | 严重 |
SEC | 访问资源时缺少策略/门控检查 | 对于带有授权系统的框架(Laravel 策略、Django 权限、Express 中间件),检查针对用户拥有的资源执行 CRUD 操作时是否包含授权检查。标记未通过策略或权限验证就读取/修改资源的控制器操作。 | 重大 |
安全配置错误
| ID 前缀 | 检测内容 | 检测方法 | 严重性 |
|---|---|---|---|
SEC | 生产配置中存在 APP_DEBUG=true | 在看起来是生产配置的配置文件(而非 .env.example 或 .env.local)中搜索 APP_DEBUG=true、DEBUG=True、debug: true。 | 重大 |
SEC | CORS 权限过于宽松 | 搜索 CORS 配置。在非公开 API 场景中,标记 Access-Control-Allow-Origin: * 或 allowed_origins: ['*']。同时标记与通配符来源结合使用的 Access-Control-Allow-Credentials: true。 | 重大 |
SEC | 配置中存在默认凭据 | 在配置文件、填充器或初始化代码中,搜索用户名 admin、root、test 等与密码 password、123456、admin、secret、changeme 等配对的情况。排除测试夹具。 | 严重 |
ID 前缀和修复提示词示例
所有发现均使用 SEC- 前缀,并按顺序编号:SEC-001、SEC-002 等。
修复提示词示例
- “在
UserController@update(第 34 行)中,将$request->all()替换为$request->only(['name', 'email']),以防止对is_admin字段进行批量赋值。如果User模型中尚未添加$fillable = ['name', 'email'],也请添加。” - “将
app/Services/SearchService.php第 55 行的用户输入封装在参数化查询中:将DB::select("SELECT * FROM products WHERE name LIKE '%$search%'")更改为DB::select('SELECT * FROM products WHERE name LIKE ?', ["%{$search}%"])。” - “在
routes/api.php中,为第 22 行的POST /api/orders路由添加身份验证中间件:将Route::post('/orders', [OrderController::class, 'store'])更改为Route::post('/orders', [OrderController::class, 'store'])->middleware('auth:sanctum')。” - “将
config/services.php第 15 行的硬编码 API 密钥移至环境变量:将'key' => 'sk-live-abc123...'替换为'key' => env('STRIPE_SECRET_KEY'),并在.env.example中添加STRIPE_SECRET_KEY=。”
评论
支持 Markdown