laxmipsarva/build-scanner

GitHub: laxmipsarva/build-scanner

一款基于正则表达式的轻量级静态扫描器,用于在本地源码或 CI 流程中快速检测 Web 应用常见的注入与安全配置类漏洞。

Stars: 0 | Forks: 0

# 构建 scanner 静态扫描器,它会遍历本地的构建/源码文件夹,并标记常见的 Web 漏洞模式: - **SQL Injection** — 字符串拼接或模板字面量 SQL 查询,原始数据库错误泄露给客户端,以及黑名单式的 SQLi 过滤器(参见下方的 [SQL injection 场景覆盖](#sql-injection-scenario-coverage)) - **NoSQL Injection** — 将原始请求对象传递给 MongoDB 样式的查询(运算符注入),以及由动态字符串构建的 `$where` 子句(JS 注入) - **GraphQL** — 保留了内省功能,缺少查询深度/复杂性限制,resolver 参数被传递给 `exec`/`eval` - **CORS** — 通配符或反射型的 `Access-Control-Allow-Origin`,通配符源与凭据组合使用 - **CSP** — `unsafe-inline`/`unsafe-eval`,通配符指令源,CSP 被完全禁用 - **CSRF** — 没有 CSRF 保护的状态更改路由,设置了 `SameSite=None` 的 cookies 这是一个基于正则表达式的启发式静态扫描器,旨在快速捕获常见错误 — 它不能替代完整的 SAST/DAST 工具或手动安全审查,并且可能会产生误报/漏报。 ### Vite/CRA 和 Next.js 覆盖范围 除了 Express 样式的服务器代码外,CSP/CORS/CSRF 规则还能识别: - **Vite/CRA**: `index.html` 中的 `` 标签(属性顺序无关紧要)。 - **Next.js CSP**: `next.config.js` 中符合 `{ key: 'Content-Security-Policy', value: "..." }` 结构的 `headers()` 条目(字面量或变量),以及在 `middleware.ts` 中构建为变量并通过 `headers.set('Content-Security-Policy', cspVar)` 应用的策略。 - **Next.js CORS**: `headers.set('Access-Control-Allow-Origin', ...)`(点设置法,如在 `middleware.ts` 和 Route Handlers 中使用的那样),传递给 `NextResponse.json()`/`Response` 的对象字面量 headers,以及 `next.config.js` 中等效的 `headers()`。 - **Next.js CSRF**: App Router Route Handlers(在名为 `route.ts` 的文件中包含 `export function POST(...)` 或 `export const POST = ...`)和 Pages API 路由(在 `pages/api/` 下的 `req.method === 'POST'` 或 `switch`)。包含 `"use server"` 指令的文件(Server Actions)被视为已受保护,因为 Next.js 会对它们应用自动的 Origin-header CSRF 保护。 已知限制:通过多重间接方式(`.join()`、`.replace()`、从另一个文件导入)构建的 CSP/CORS 值无法被解析 — 仅支持同一文件中单个 `const`/`let`/`var` 的字符串或模板字面量赋值。`pages/api/` 之外的通用 `request.method === 'POST'` 分支(例如在 `middleware.ts` 中)不会被标记,因为这种结构在不相关的身份验证/重定向逻辑中过于常见,无法安全地确定其作用域。 ## 安装 ``` npm install npm run build ``` ## 使用说明 ``` # 扫描目录 node dist/cli.js ./path/to/project # 扫描单个文件 node dist/cli.js ./path/to/project/server.js # JSON 输出 (用于 CI / tooling) node dist/cli.js ./path/to/project --format json # 仅运行特定规则 node dist/cli.js ./path/to/project --rules sql-injection,csrf-vulnerabilities # 列出可用规则 node dist/cli.js rules # 如果存在达到或超过特定严重级别的发现,则以非零状态退出 (用于 CI gating) node dist/cli.js ./path/to/project --fail-on high ``` 如果你使用了 `npm link`(或将其全局安装),同样可以通过 `build-scanner` 可执行文件来运行命令,而无需使用 `node dist/cli.js`。 ## 作为 GitHub Action 使用 一旦此仓库被推送到 GitHub 并打上标签(例如 `v1`),任何其他仓库都可以在 CI 中运行此扫描器,而无需自行安装任何内容: ``` - uses: actions/checkout@v4 - uses: laxmipsarva/build-scanner@v1 with: path: . fail-on: high ``` 输入参数与上述的 CLI 标志相映射:`path`(默认为 `.`)、`format`(`text` | `json`,默认为 `text`)、`rules`(逗号分隔的规则 ID)、`fail-on`(`critical|high|medium|low|info`)以及 `list-files`(`true`/`false`)。该 action 会在每次运行时安装自身的依赖并从源码构建,因此任务失败的方式与在本地运行 `--fail-on` 完全一致。 注意:`@v1` 标签尚不存在 — 在为发布版本打上标签之前,请通过分支或 commit SHA 来引用该 action(例如 `laxmipsarva/build-scanner@main`)。 ## 编程式使用 ``` import { scan, allRules, formatText } from "build-scanner"; const result = await scan({ root: "./path/to/project" }, allRules); console.log(formatText(result)); ``` ## 开发 ``` npm run dev -- ./path/to/project # run the CLI from source via tsx npm test # run the unit tests (vitest) npm run typecheck ``` 每个规则都位于 `src/rules/*.ts` 中,并且在 `tests/fixtures/` 中有对应的漏洞/安全测试用例,在 `tests/unit/` 中有相应的测试。要添加新规则:请实现 `Rule` 接口(参见 `src/core/types.ts`),在 `src/rules/index.ts` 中注册它,并添加相应的测试用例和测试。 ## SQL injection 场景覆盖 `src/rules/sql-injection.ts` 会在 `tests/fixtures/sql-scenarios/` 中针对 18 个测试用例进行测试,每个测试用例对应一种经典的 SQL injection 攻击场景(采用 PortSwigger Web Security Academy 的命名方式),相关测试位于 `tests/unit/sql-injection-scenarios.test.ts`。 build-scanner 是一个**静态**扫描器 — 它读取源文件,不会向正在运行的应用程序发送请求。因此,它会检测应用程序自身源码中的*根本原因 sink*(由拼接/插值构建的未参数化查询),而不是模拟攻击者的利用流量。下面的几个场景故意使用了完全相同的 sink,因为它们之间的区别在于攻击者针对实时目标的 payload/技术,而不是易受攻击源代码的结构: | # | 场景 | 实际检测到的内容 | |---|----------|---------------------------| | 1 | WHERE clause — hidden data | 拼接/插值的 `WHERE` 子句 | | 2 | Login bypass | 拼接的 `WHERE username=...AND password=...` | | 3 | DB version query (Oracle) | 相同的 sink — 通过 `UNION SELECT ... FROM v$version` 进行利用 | | 4 | DB version query (MySQL/MSSQL) | 相同的 sink — 通过 `UNION SELECT @@version` 进行利用 | | 5 | List DB contents (non-Oracle) | 相同的 sink — 通过 `information_schema.tables` 进行利用 | | 6 | List DB contents (Oracle) | 相同的 sink — 通过 `all_tables` 进行利用 | | 7–10 | UNION attacks (column count, text column, other tables, multi-value column) | 相同的 sink — 这四种都是针对同一个注入点的 UNION payload 变体 | | 11 | Blind, conditional responses | 相同的 sink,响应内容在 true/false 时有所不同 | | 12 | Blind, conditional errors | 相同的 sink;**不**被标记为错误泄露 — 仅返回状态,不返回错误详情 | | 13 | Visible error-based | 相同的 sink **+ 新增检查**:在查询调用附近将原始 `err.message` 发送给客户端 | | 14–15 | Blind, time delays (+ info retrieval) | 相同的 sink — 时序侧信道对静态分析是不可见的 | | 16–17 | Blind, out-of-band (interaction + exfiltration) | 相同的 sink — OOB 信道对静态分析是不可见的 | | 18 | Filter bypass via XML encoding | **新增检查**:黑名单引号剔除(`.replace(/'/g, "")`)和黑名单关键字测试(`/select|union|.../i.test(...)`)无论使用何种特定的编码技巧,都会被标记为可绕过 | 如果你需要实际确认这些场景的可利用性(而不仅仅是找到源码层面的根本原因),则需要一个动态/主动扫描器,向正在运行的目标发送实时的 payload — 这是一个比此静态工具更大、不同的工具。
标签:CMS安全, JavaScript, MITM代理, SAST, Web安全, 盲注攻击, 自动化攻击, 蓝队分析, 静态代码扫描