lohith80/JSecPy
GitHub: lohith80/JSecPy
JSecPy 是一款基于 AST 与污点分析的 Java 静态安全测试工具,通过数据流追踪减少误报并输出 SARIF 报告集成到 CI 中。
Stars: 0 | Forks: 0
# JSecPy
[](https://github.com/lohith80/JSecPy/actions/workflows/ci.yml)
[](LICENSE)
[](pyproject.toml)
**针对 Java 的静态应用安全测试 (SAST),由 AST + 污点分析驱动,映射到 CWE 和 OWASP Top 10,并输出 SARIF 以用于 GitHub 代码扫描。**
JSecPy 将 Java 源代码解析为抽象语法树,并追踪攻击者可控的数据如何从**源**(servlet 参数、标头、请求体、CLI 参数)流向危险的**汇聚点**(SQL、OS 命令、文件路径、URL、LDAP、XPath)。因为它理解数据流,所以只有当用户输入真正到达查询时才会报告 SQL 注入,而不是每一行仅仅提到 `Statement` 的代码都会被报告。
```
flowchart LR
A[Java source] --> B[javalang AST]
B --> C[Taint analysis
source to sink] B --> D[Config / crypto rules] C --> E[Findings: CWE + OWASP] D --> E E --> F[CLI] E --> G[JSON] E --> H[SARIF to GitHub code scanning] ``` ## 为什么不直接用 grep? 关键字扫描器会在 `MessageDigest`、`Statement` 或 `exec` 出现的任何地方进行标记,并让你陷入误报的泥潭。JSecPy 则不同: ``` // FLAGGED (JSEC-SQLI, HIGH): user input flows into the query String name = req.getParameter("name"); stmt.executeQuery("SELECT * FROM users WHERE name = '" + name + "'"); // NOT FLAGGED: parameterized query, input is bound safely PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE name = ?"); ps.setString(1, req.getParameter("name")); ps.executeQuery(); ``` 两行代码都提到了 SQL。只有第一行是漏洞,并且只有第一行会被报告。 ## 安装 ``` pip install "jsecpy @ git+https://github.com/lohith80/JSecPy@v2.1.0" # 或从源码: git clone https://github.com/lohith80/JSecPy && cd JSecPy && pip install -e ".[dev]" ``` ## 用法 ``` jsecpy src/main/java # scan a directory jsecpy App.java --min-severity MEDIUM # single file, raise the floor jsecpy src/ --format sarif -o out.sarif # SARIF for code scanning jsecpy src/ --format json -o report.json # machine-readable jsecpy --list-rules # show the rule catalog ``` 示例检测结果: ``` [CRITICAL] SQL Injection (JSEC-SQLI, high confidence) src/UserDao.java:42 > ResultSet rs = st.executeQuery(query); SQL Injection: attacker-controlled input reaches st.executeQuery(). CWE: CWE-89 OWASP: A03:2021-Injection flow: line 39 source: req.getParameter flow: line 42 sink: st.executeQuery Fix: Use PreparedStatement with parameterized queries... ``` ## 检测项 跨 OWASP Top 10 的 14 条内置规则。运行 `jsecpy --list-rules` 获取实时列表;完整目录见 [docs/RULES.md](docs/RULES.md)。 | 规则 | 检测内容 | CWE | OWASP | |------|---------|-----|-------| | JSEC-SQLI | SQL 注入(污点流入 JDBC/JPA 查询) | CWE-89 | A03 | | JSEC-CMDI | OS 命令注入 | CWE-78 | A03 | | JSEC-PATH | 路径遍历 | CWE-22 | A01 | | JSEC-SSRF | 服务端请求伪造 | CWE-918 | A10 | | JSEC-LDAP | LDAP 注入 | CWE-90 | A03 | | JSEC-XPATH | XPath 注入 | CWE-643 | A03 | | JSEC-REDIR | 开放重定向 | CWE-601 | A01 | | JSEC-HASH | 弱哈希(MD5、SHA-1) | CWE-328 | A02 | | JSEC-CIPHER | 弱加密算法 / ECB 模式 | CWE-327 | A02 | | JSEC-RANDOM | 不安全的随机性 | CWE-330 | A02 | | JSEC-XXE | XML 外部实体暴露 | CWE-611 | A05 | | JSEC-DESER | 不安全的反序列化 | CWE-502 | A08 | | JSEC-TLS | 禁用 TLS 校验 | CWE-295 | A07 | | JSEC-COOKIE | 不安全的 Cookie 标志 | CWE-614 | A05 | | JSEC-SECRET | 硬编码密钥 | CWE-798 | A07 | 此外还提供了一个 **YAML 规则引擎**,让团队无需编写代码即可添加自己的汇聚点,并支持使用 Python 编写任何结构化的规则。详见 [docs/WRITING_RULES.md](docs/WRITING_RULES.md)。 ## GitHub Action 为任何 Java 仓库添加 SAST,并以 PR 批注的形式获取检测结果: ``` # .github/workflows/security.yml name: JSecPy on: [pull_request] permissions: contents: read security-events: write # required to upload SARIF jobs: sast: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: lohith80/JSecPy@v2.1.0 with: paths: src/main/java fail-on: HIGH ``` ## CI 易用性 - **退出码:** `0` 表示干净,`1` 表示在 `--fail-on`(默认为 HIGH)级别及以上发现检测结果,`2` 表示用法错误 —— 开箱即可作为流水线的门禁。 - **基线:** `jsecpy src/ --write-baseline .jsecpy-baseline.json` 会对当前的检测结果进行快照;以后使用 `--baseline` 运行时只会报告新增项。在遗留代码库中引入 JSecPy 时,可以避免被首日产生的海量噪音淹没。 - **内联抑制:** 在检测行使用 `// jsecpy:ignore` 或 `// jsecpy:ignore[JSEC-SQLI]`,便于 grep 和审查。 - **配置文件:** 使用 `.jsecpy.yml` 配置严重性阈值、排除项、禁用的规则以及自定义规则路径。详见 [.jsecpy.example.yml](.jsecpy.example.yml)。 ## 置信度与诚实度 当污点被证实从源流向汇聚点时,检测结果为 HIGH(高)置信度;当值是动态构建的但污点无法被证实时,则为 MEDIUM(中)置信度。JSecPy 是过程内的,不会跨构建图解析类型;它是一个高信号的首轮筛查和 CI 门禁,**而非**正确性证明。请阅读 [docs/THREAT_MODEL.md](docs/THREAT_MODEL.md) 以获取完整的能力和局限性说明。 **对抗性测试。** 该引擎由 [tests/test_redteam_corpus.py](tests/test_redteam_corpus.py) 验证:包含来自红队测试的 43 个 Java 案例,分为必须触发的检测项、必须保持静默的安全代码(反误报契约),以及编码为 `xfail` 的已知文档缺口。CI 强制要求在该语料库中做到零漏报和零误报,并且每一个已知的局限性都是一个可见的、在发生回归当天即失败的测试,而不是在脚注中一笔带过。 ## 贡献 最有价值的贡献是指出**检测缺口**:即 JSecPy 遗漏的易受攻击 Java 代码片段,或被其错误标记的安全代码。请带上代码片段提交一个 Issue。新规则需要提供一个漏洞示例和一个安全示例。扫描器本身的安全问题请通过 [SECURITY.md](SECURITY.md) 处理。 ## 许可证 MIT —— 详见 [LICENSE](LICENSE)。
source to sink] B --> D[Config / crypto rules] C --> E[Findings: CWE + OWASP] D --> E E --> F[CLI] E --> G[JSON] E --> H[SARIF to GitHub code scanning] ``` ## 为什么不直接用 grep? 关键字扫描器会在 `MessageDigest`、`Statement` 或 `exec` 出现的任何地方进行标记,并让你陷入误报的泥潭。JSecPy 则不同: ``` // FLAGGED (JSEC-SQLI, HIGH): user input flows into the query String name = req.getParameter("name"); stmt.executeQuery("SELECT * FROM users WHERE name = '" + name + "'"); // NOT FLAGGED: parameterized query, input is bound safely PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE name = ?"); ps.setString(1, req.getParameter("name")); ps.executeQuery(); ``` 两行代码都提到了 SQL。只有第一行是漏洞,并且只有第一行会被报告。 ## 安装 ``` pip install "jsecpy @ git+https://github.com/lohith80/JSecPy@v2.1.0" # 或从源码: git clone https://github.com/lohith80/JSecPy && cd JSecPy && pip install -e ".[dev]" ``` ## 用法 ``` jsecpy src/main/java # scan a directory jsecpy App.java --min-severity MEDIUM # single file, raise the floor jsecpy src/ --format sarif -o out.sarif # SARIF for code scanning jsecpy src/ --format json -o report.json # machine-readable jsecpy --list-rules # show the rule catalog ``` 示例检测结果: ``` [CRITICAL] SQL Injection (JSEC-SQLI, high confidence) src/UserDao.java:42 > ResultSet rs = st.executeQuery(query); SQL Injection: attacker-controlled input reaches st.executeQuery(). CWE: CWE-89 OWASP: A03:2021-Injection flow: line 39 source: req.getParameter flow: line 42 sink: st.executeQuery Fix: Use PreparedStatement with parameterized queries... ``` ## 检测项 跨 OWASP Top 10 的 14 条内置规则。运行 `jsecpy --list-rules` 获取实时列表;完整目录见 [docs/RULES.md](docs/RULES.md)。 | 规则 | 检测内容 | CWE | OWASP | |------|---------|-----|-------| | JSEC-SQLI | SQL 注入(污点流入 JDBC/JPA 查询) | CWE-89 | A03 | | JSEC-CMDI | OS 命令注入 | CWE-78 | A03 | | JSEC-PATH | 路径遍历 | CWE-22 | A01 | | JSEC-SSRF | 服务端请求伪造 | CWE-918 | A10 | | JSEC-LDAP | LDAP 注入 | CWE-90 | A03 | | JSEC-XPATH | XPath 注入 | CWE-643 | A03 | | JSEC-REDIR | 开放重定向 | CWE-601 | A01 | | JSEC-HASH | 弱哈希(MD5、SHA-1) | CWE-328 | A02 | | JSEC-CIPHER | 弱加密算法 / ECB 模式 | CWE-327 | A02 | | JSEC-RANDOM | 不安全的随机性 | CWE-330 | A02 | | JSEC-XXE | XML 外部实体暴露 | CWE-611 | A05 | | JSEC-DESER | 不安全的反序列化 | CWE-502 | A08 | | JSEC-TLS | 禁用 TLS 校验 | CWE-295 | A07 | | JSEC-COOKIE | 不安全的 Cookie 标志 | CWE-614 | A05 | | JSEC-SECRET | 硬编码密钥 | CWE-798 | A07 | 此外还提供了一个 **YAML 规则引擎**,让团队无需编写代码即可添加自己的汇聚点,并支持使用 Python 编写任何结构化的规则。详见 [docs/WRITING_RULES.md](docs/WRITING_RULES.md)。 ## GitHub Action 为任何 Java 仓库添加 SAST,并以 PR 批注的形式获取检测结果: ``` # .github/workflows/security.yml name: JSecPy on: [pull_request] permissions: contents: read security-events: write # required to upload SARIF jobs: sast: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: lohith80/JSecPy@v2.1.0 with: paths: src/main/java fail-on: HIGH ``` ## CI 易用性 - **退出码:** `0` 表示干净,`1` 表示在 `--fail-on`(默认为 HIGH)级别及以上发现检测结果,`2` 表示用法错误 —— 开箱即可作为流水线的门禁。 - **基线:** `jsecpy src/ --write-baseline .jsecpy-baseline.json` 会对当前的检测结果进行快照;以后使用 `--baseline` 运行时只会报告新增项。在遗留代码库中引入 JSecPy 时,可以避免被首日产生的海量噪音淹没。 - **内联抑制:** 在检测行使用 `// jsecpy:ignore` 或 `// jsecpy:ignore[JSEC-SQLI]`,便于 grep 和审查。 - **配置文件:** 使用 `.jsecpy.yml` 配置严重性阈值、排除项、禁用的规则以及自定义规则路径。详见 [.jsecpy.example.yml](.jsecpy.example.yml)。 ## 置信度与诚实度 当污点被证实从源流向汇聚点时,检测结果为 HIGH(高)置信度;当值是动态构建的但污点无法被证实时,则为 MEDIUM(中)置信度。JSecPy 是过程内的,不会跨构建图解析类型;它是一个高信号的首轮筛查和 CI 门禁,**而非**正确性证明。请阅读 [docs/THREAT_MODEL.md](docs/THREAT_MODEL.md) 以获取完整的能力和局限性说明。 **对抗性测试。** 该引擎由 [tests/test_redteam_corpus.py](tests/test_redteam_corpus.py) 验证:包含来自红队测试的 43 个 Java 案例,分为必须触发的检测项、必须保持静默的安全代码(反误报契约),以及编码为 `xfail` 的已知文档缺口。CI 强制要求在该语料库中做到零漏报和零误报,并且每一个已知的局限性都是一个可见的、在发生回归当天即失败的测试,而不是在脚注中一笔带过。 ## 贡献 最有价值的贡献是指出**检测缺口**:即 JSecPy 遗漏的易受攻击 Java 代码片段,或被其错误标记的安全代码。请带上代码片段提交一个 Issue。新规则需要提供一个漏洞示例和一个安全示例。扫描器本身的安全问题请通过 [SECURITY.md](SECURITY.md) 处理。 ## 许可证 MIT —— 详见 [LICENSE](LICENSE)。
标签:CISA项目, JS文件枚举, SAST, 代码安全审计, 盲注攻击, 逆向工具, 错误基检测, 静态代码分析