raghu-py/securedev-action
GitHub: raghu-py/securedev-action
SecureDev Action 是一个GitHub Action,用于在CI/CD中自动扫描代码安全风险并生成报告,帮助开发者早期发现漏洞。
Stars: 0 | Forks: 0
# SecureDev 行动
**一个独立的 Docker GitHub Action,用于扫描代码和配置文件的安全风险。**
由 **Raghu Soni** 构建
   
[概述](#overview) · [使用方法](#usage) · [输入参数](#inputs) · [输出参数](#outputs) · [规则](#security-rules) · [本地开发](#local-development) · [常见问题](#faq)
## 概述
**SecureDev Action** 是一个轻量级、独立的 GitHub Actions 安全扫描器。
它扫描源代码、脚本、Docker 文件、基础设施文件、配置文件以及基于文本的项目文件,检测常见安全问题,例如:
- 硬编码密钥
- 危险的命令执行
- SQL 注入模式
- 不安全的反序列化
- 弱加密
- 不安全的 Docker 配置
- 高风险的 Kubernetes 设置
- 不安全的 GitHub Actions 用法
- 调试和不安全的配置值
## 主要特性
| 特性 | 描述 |
|---|---|
| Docker Action | 在 Docker 容器内运行 |
| 独立 | 不依赖外部扫描服务 |
| 多语言扫描 | 支持 Python, JavaScript, PHP, Ruby, Java, Go, shell, 配置, Docker, Kubernetes, IaC 等 |
| 默认仅严重级别失败 | 仅当检测到严重发现时,CI 才会失败 |
| JSON 输出 | 生成机器可读报告 |
| SARIF 输出 | 生成供安全工具使用的 SARIF 报告 |
| Markdown 输出 | 生成可读的安全摘要 |
| GitHub 注解 | 在 GitHub Actions 日志中显示发现 |
| 无 PR 评论 | 不在拉取请求上发布评论 |
| 可配置扫描 | 支持包含、排除、文件大小、输出格式和严重性阈值等选项 |
## 使用方法
创建工作流文件:
```
name: SecureDev Scan
on:
push:
branches:
- main
pull_request:
permissions:
contents: read
jobs:
securedev:
name: SecureDev Security Scan
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Run SecureDev Action
uses: raghu-py/securedev-action@v1
with:
path: "."
fail-on: "critical"
output-format: "all"
output-dir: "securedev-results"
```
在创建发布标签之前进行测试,可以使用:
```
uses: raghu-py/securedev-action@main
```
对于稳定使用,创建一个发布标签如 `v1` 并使用:
```
uses: raghu-py/securedev-action@v1
```
## 输入参数
| 输入参数 | 必需 | 默认值 | 描述 |
|---|---:|---|---|
| `path` | 否 | `.` | 要扫描的路径。使用 `.` 表示检出的仓库根目录。 |
| `fail-on` | 否 | `critical` | 导致操作失败的最低严重性。允许的值:`critical`, `high`, `medium`, `low`, `none`。 |
| `output-dir` | 否 | `securedev-results` | 写入 JSON, SARIF 和 Markdown 报告的目录。 |
| `output-format` | 否 | `all` | 要生成的报告格式。允许的值:`all`, `json`, `sarif`, `markdown`, `md`,或用逗号分隔的值如 `json,sarif`。 |
| `include` | 否 | 空 | 要包含的逗号分隔的 glob 模式。空表示 `path` 下的所有文件。 |
| `exclude` | 否 | 空 | 除了内置默认值外,要排除的逗号分隔的 glob 模式。 |
| `max-file-size-kb` | 否 | `1024` | 要扫描的最大文件大小,单位为 KB。 |
| `show-snippets` | 否 | `true` | 在报告中包含匹配的源代码片段。允许的值:`true`, `false`。 |
| `annotations` | 否 | `true` | 为发现创建 GitHub 工作流注解。这不会发布 PR 评论。 |
## 输出参数
| 输出参数 | 描述 |
|---|---|
| `result` | 最终结果:`pass` 或 `fail`。 |
| `findings_count` | 发现总数。 |
| `critical_count` | 严重发现数量。 |
| `high_count` | 高危发现数量。 |
| `medium_count` | 中危发现数量。 |
| `low_count` | 低危发现数量。 |
| `report_json` | JSON 报告路径(生成时)。 |
| `report_sarif` | SARIF 报告路径(生成时)。 |
| `report_markdown` | Markdown 报告路径(生成时)。 |
输出使用示例:
```
- name: Run SecureDev Action
id: securedev
uses: raghu-py/securedev-action@v1
with:
path: "."
fail-on: "critical"
- name: Print result
if: always()
run: |
echo "Result: ${{ steps.securedev.outputs.result }}"
echo "Findings: ${{ steps.securedev.outputs.findings_count }}"
echo "Critical: ${{ steps.securedev.outputs.critical_count }}"
```
## 生成报告
默认情况下,报告写入到:
```
securedev-results/
```
生成的报告文件:
| 文件 | 格式 | 用途 |
|---|---|---|
| `securedev-report.json` | JSON | 完整的机器可读安全报告 |
| `securedev-report.sarif` | SARIF | 供安全工具使用的静态分析报告 |
| `securedev-summary.md` | Markdown | 人类可读的扫描摘要 |
示例:
```
securedev-results/
├── securedev-report.json
├── securedev-report.sarif
└── securedev-summary.md
```
## 上传报告作为工件
```
name: SecureDev Scan
on:
push:
pull_request:
permissions:
contents: read
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run SecureDev Action
uses: raghu-py/securedev-action@v1
with:
path: "."
fail-on: "critical"
output-format: "all"
output-dir: "securedev-results"
- name: Upload SecureDev reports
if: always()
uses: actions/upload-artifact@v4
with:
name: securedev-results
path: securedev-results/
```
## 上传 SARIF 到 GitHub Code Scanning
SecureDev Action 生成 SARIF 报告。要将其上传到 GitHub Code Scanning,请添加一个 SARIF 上传步骤。
```
name: SecureDev Code Scanning
on:
push:
branches:
- main
pull_request:
permissions:
contents: read
security-events: write
jobs:
securedev:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run SecureDev Action
uses: raghu-py/securedev-action@v1
with:
path: "."
fail-on: "critical"
output-format: "sarif"
output-dir: "securedev-results"
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: securedev-results/securedev-report.sarif
```
## 严重性级别
| 严重性 | 含义 | 默认是否导致 CI 失败 |
|---|---|---:|
| `critical` | 高度危险的问题,应立即修复 | 是 |
| `high` | 严重的安全问题 | 否 |
| `medium` | 需要审查的风险模式 | 否 |
| `low` | 弱点或加固建议 | 否 |
| `info` | 信息性发现 | 否 |
默认行为:
```
fail-on = critical
```
这意味着仅当检测到至少一个严重发现时,操作才会失败。
## 失败模式
| `fail-on` 值 | 工作流在何时失败 |
|---|---|
| `critical` | 严重发现 |
| `high` | 严重和高危发现 |
| `medium` | 严重、高危和中危发现 |
| `low` | 严重、高危、中危和低危发现 |
| `none` | 永不因发现而失败 |
示例:
```
with:
fail-on: "none"
```
## 安全规则
SecureDev Action 包含多个类别的规则。
| 规则 ID | 名称 | 严重性 | 类别 |
|---|---|---|---|
| `SEC001` | AWS 访问密钥暴露 | `critical` | 密钥 |
| `SEC002` | GitHub 令牌暴露 | `critical` | 密钥 |
| `SEC003` | 私钥材料被提交 | `critical` | 密钥 |
| `SEC004` | Google API 密钥暴露 | `critical` | 密钥 |
| `SEC005` | Stripe 生产环境密钥暴露 | `critical` | 密钥 |
| `SEC006` | Slack 令牌暴露 | `critical` | 密钥 |
| `SEC007` | 通用硬编码密钥 | `high` | 密钥 |
| `PY001` | 使用 Python `eval` | `high` | 注入 |
| `PY002` | 使用 Python `exec` | `high` | 注入 |
| `PY003` | Shell 命令执行 | `high` | 命令注入 |
| `PY004` | `subprocess` 配合 `shell=True` | `critical` | 命令注入 |
| `PY005` | 不安全的 pickle 反序列化 | `high` | 反序列化 |
| `PY006` | 不安全的 YAML 加载 | `high` | 反序列化 |
| `PY007` | TLS 证书验证被禁用 | `high` | 传输安全 |
| `PY008` | 启用调试模式 | `high` | 配置 |
| `PY009` | SQL 查询使用字符串格式化构建 | `critical` | SQL 注入 |
| `PY010` | 弱哈希算法 | `medium` | 加密 |
| `PY011` | 弱或高风险的加密模式 | `high` | 加密 |
| `PY012` | JWT 签名验证被禁用 | `critical` | 认证 |
| `JS001` | 使用 JavaScript `eval` | `high` | 注入 |
| `JS002` | HTML 注入点 | `high` | XSS |
| `JS003` | 使用 React `dangerouslySetInnerHTML` | `high` | XSS |
| `JS004` | Node 命令执行 | `high` | 命令注入 |
| `JS005` | Node 中 TLS 证书验证被禁用 | `high` | 传输安全 |
| `WEB001` | 检测到内联脚本 | `low` | XSS 加固 |
| `PHP001` | 使用 PHP `eval` | `critical` | 注入 |
| `PHP002` | PHP 不安全反序列化 | `high` | 反序列化 |
| `PHP003` | 可能的 PHP SQL 注入 | `critical` | SQL 注入 |
| `RB001` | Ruby 不安全 YAML 加载 | `high` | 反序列化 |
| `RB002` | Ruby 命令执行 | `high` | 命令注入 |
| `JAVA001` | Java 命令执行 | `high` | 命令注入 |
| `GO001` | Go 命令执行 | `high` | 命令注入 |
| `CFG001` | CORS 通配符来源 | `high` | 配置 |
| `CFG002` | 不安全的调试配置 | `high` | 配置 |
| `CFG003` | SSH root 登录已启用 | `high` | 配置 |
| `CFG004` | SSH 密码认证已启用 | `medium` | 配置 |
| `DOCKER001` | Docker 镜像使用 latest 标签 | `medium` | 供应链 |
| `DOCKER002` | Docker `ADD` 从远程 URL 获取 | `medium` | 供应链 |
| `DOCKER003` | 配置了特权容器 | `critical` | 容器安全 |
| `K8S001` | Kubernetes 特权容器 | `critical` | 容器安全 |
| `K8S002` | Kubernetes 启用了主机网络 | `high` | 容器安全 |
| `K8S003` | Kubernetes 启用了特权提升 | `high` | 容器安全 |
| `IAC001` | 公开的 SSH 入口 | `critical` | 云安全 |
| `IAC002` | 公开的对象存储 ACL | `critical` | 云安全 |
| `GHA001` | GitHub Action 固定到可变 ref | `medium` | 供应链 |
| `GEN001` | 过于宽松的文件权限 | `high` | 配置 |
| `JWT001` | 接受 JWT none 算法 | `critical` | 认证 |
| `SQL001` | 可能的 SQL 注入模式 | `critical` | SQL 注入 |
## 扫描流程
```
flowchart TD
A[GitHub workflow starts] --> B[Checkout repository]
B --> C[Run SecureDev Docker Action]
C --> D[Resolve scan path]
D --> E[Walk files]
E --> F[Skip binary, large, generated, and excluded files]
F --> G[Apply security rules]
G --> H[Create findings]
H --> I[Generate JSON, SARIF, and Markdown reports]
I --> J[Emit GitHub annotations]
J --> K{Findings meet fail-on threshold?}
K -->|Yes| L[Fail workflow]
K -->|No| M[Pass workflow]
```
## 项目结构
```
securedev-action/
├── action.yml
├── Dockerfile
├── entrypoint.sh
├── .gitignore
├── .dockerignore
├── securedev_action/
│ ├── __init__.py
│ ├── __main__.py
│ ├── cli.py
│ ├── config.py
│ ├── filewalker.py
│ ├── models.py
│ ├── reporters.py
│ ├── rules.py
│ └── scanner.py
└── tests/
└── test_scanner.py
```
## 文件和文件夹排除
扫描器会跳过常见的生成文件、依赖项、缓存、二进制文件、存档、媒体和锁文件。
### 内置排除的文件夹
```
.git/
.hg/
.svn/
.idea/
.vscode/
.tox/
.nox/
.venv/
venv/
env/
node_modules/
bower_components/
vendor/
dist/
build/
target/
out/
coverage/
htmlcov/
__pycache__/
.pytest_cache/
.mypy_cache/
.ruff_cache/
.next/
.nuxt/
.turbo/
.cache/
tmp/
temp/
logs/
```
### 内置排除的文件模式
```
*.png
*.jpg
*.jpeg
*.gif
*.webp
*.ico
*.pdf
*.zip
*.tar
*.tar.gz
*.tgz
*.rar
*.7z
*.gz
*.bz2
*.xz
*.mp4
*.mov
*.mp3
*.wav
*.woff
*.woff2
*.ttf
*.otf
*.eot
*.lock
package-lock.json
pnpm-lock.yaml
yarn.lock
poetry.lock
Pipfile.lock
Cargo.lock
Gemfile.lock
composer.lock
```
## 包含和排除示例
仅扫描 Python 文件:
```
with:
path: "."
include: "**/*.py"
```
扫描 Python 和 JavaScript 文件:
```
with:
path: "."
include: "**/*.py,**/*.js,**/*.ts"
```
排除测试和文档文件夹:
```
with:
path: "."
exclude: "tests/**,docs/**"
```
将最大文件大小增加到 2 MB:
```
with:
max-file-size-kb: "2048"
```
禁用报告中的代码片段:
```
with:
show-snippets: "false"
```
禁用 GitHub 注解:
```
with:
annotations: "false"
```
## GitHub 注解
当启用 `annotations` 时,SecureDev Action 会打印与 GitHub 兼容的工作流注解。
示例:
```
::error file=app/main.py,line=20,col=1,title=PY004: subprocess with shell=True::subprocess is called with shell=True, which can allow command injection.
```
这些注解会出现在 GitHub Actions 日志中。
重要提示:
## 本地开发
克隆仓库:
```
git clone https://github.com/raghu-py/securedev-action.git
cd securedev-action
```
本地运行扫描器:
```
python -m securedev_action.cli --path . --fail-on critical --output-format all
```
也可以通过包入口点运行:
```
python -m securedev_action --path . --fail-on critical --output-format all
```
运行测试:
```
python -m pytest tests
```
构建 Docker 镜像:
```
docker build -t securedev-action .
```
本地运行 Docker 镜像:
```
docker run --rm -v "$PWD:/workspace" securedev-action --path /workspace --fail-on critical
```
检查版本:
```
python -m securedev_action --version
```
## 发现示例
### 硬编码的 GitHub 令牌
```
GITHUB_TOKEN = "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```
预期发现:
```
SEC002: GitHub token exposed
Severity: critical
```
### 危险的 Python subprocess 用法
```
import subprocess
subprocess.run(user_input, shell=True)
```
预期发现:
```
PY004: subprocess with shell=True
Severity: critical
```
### SQL 注入模式
```
query = "SELECT * FROM users WHERE id = " + user_id
```
预期发现:
```
SQL001: Possible SQL injection pattern
Severity: critical
```
### 弱哈希算法
```
import hashlib
password_hash = hashlib.md5(password.encode()).hexdigest()
```
预期发现:
```
PY010: Weak hash algorithm
Severity: medium
```
## 抑制发现
扫描器识别常见的抑制标记。
仅当您手动审查了发现并确认其安全时,才使用抑制。
支持的标记包括:
```
securedev: ignore
securedev-ignore
pragma: allowlist secret
nosec
```
示例:
```
example_token = "not-a-real-token" # securedev: ignore
```
## 推荐工作流
```
name: Security
on:
pull_request:
push:
branches:
- main
permissions:
contents: read
jobs:
securedev:
name: SecureDev
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Scan repository
uses: raghu-py/securedev-action@v1
with:
path: "."
fail-on: "critical"
output-format: "all"
output-dir: "securedev-results"
- name: Upload reports
if: always()
uses: actions/upload-artifact@v4
with:
name: securedev-results
path: securedev-results/
```
## 高级工作流
此工作流扫描源文件、生成报告、将其作为工件上传,并将 SARIF 上传到 GitHub Code Scanning。
```
name: Advanced SecureDev Scan
on:
push:
branches:
- main
pull_request:
permissions:
contents: read
security-events: write
jobs:
securedev:
name: SecureDev Advanced Scan
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run SecureDev Action
uses: raghu-py/securedev-action@v1
with:
path: "."
fail-on: "critical"
output-format: "all"
output-dir: "securedev-results"
exclude: "tests/fixtures/**,docs/examples/**"
max-file-size-kb: "1024"
show-snippets: "true"
annotations: "true"
- name: Upload SecureDev reports
if: always()
uses: actions/upload-artifact@v4
with:
name: securedev-results
path: securedev-results/
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: securedev-results/securedev-report.sarif
```
## JSON 报告示例
```
{
"tool": {
"name": "SecureDev Action",
"version": "1.0.0",
"author": "Raghu Soni"
},
"summary": {
"scanned_files": 25,
"skipped_files": 4,
"findings_count": 2,
"counts_by_severity": {
"critical": 1,
"high": 1,
"medium": 0,
"low": 0,
"info": 0
}
},
"findings": [
{
"rule_id": "PY004",
"title": "subprocess with shell=True",
"severity": "critical",
"file_path": "app/runner.py",
"line": 14
}
]
}
```
## Markdown 报告示例
```
# SecureDev 安全扫描
**Status:** FAIL
## 摘要
| Metric | Value |
|---|---:|
| Scanned files | 25 |
| Skipped files | 4 |
| Total findings | 2 |
| Critical | 1 |
| High | 1 |
| Medium | 0 |
| Low | 0 |
| Info | 0 |
```
## 何时使用此 Action
SecureDev Action 适用于:
- 开源仓库
- Python 项目
- JavaScript 和 TypeScript 项目
- 基于 Docker 的应用程序
- DevSecOps 学习
- CI 中的安全检查
- 拉取请求安全检查
- 轻量级静态分析
## 此 Action 不是什么
SecureDev Action 不能完全替代:
- 手动安全审查
- 专业的 SAST 平台
- 依赖项漏洞扫描器
- 运行时安全测试
- 渗透测试
- 支持完整 Git 历史记录的密钥扫描
它旨在早期捕获常见的风险模式。
## 安全理念
1. 保持安全检查易于理解。
2. 避免将有用信息隐藏在复杂的工具背后。
3. 使报告对开发者可读。
4. 默认仅在严重发现时才使 CI 失败。
5. 偏好实际检测而非嘈杂的输出。
## 维护者检查清单
在创建新版本之前:
- [ ] 本地运行测试
- [ ] 本地构建 Docker 镜像
- [ ] 在示例仓库上测试 Action
- [ ] 验证 JSON 报告生成
- [ ] 验证 SARIF 报告生成
- [ ] 验证 Markdown 报告生成
- [ ] 确认 `fail-on: critical` 行为
- [ ] 创建版本标签如 `v1.0.0`
- [ ] 移动或更新主要标签如 `v1`
## 发布标签
推荐的标签:
| 标签 | 用途 |
|---|---|
| `v1.0.0` | 确切的发布版本 |
| `v1` | 稳定的主要版本 |
| `main` | 开发版本 |
创建发布标签:
```
git tag v1.0.0
git push origin v1.0.0
```
创建或更新主要标签:
```
git tag -f v1 v1.0.0
git push origin v1 --force
```
推荐的用户语法:
```
uses: raghu-py/securedev-action@v1
```
## 详细说明
   
[概述](#overview) · [使用方法](#usage) · [输入参数](#inputs) · [输出参数](#outputs) · [规则](#security-rules) · [本地开发](#local-development) · [常见问题](#faq)
SecureDev Action 如何决定是否失败?
SecureDev Action 将所有发现与配置的 `fail-on` 严重性进行比较。 例如: ``` with: fail-on: "critical" ``` 这仅在存在至少一个严重发现时失败。 如果扫描发现高危、中危或低危发现但没有严重发现,则工作流通过。SecureDev Action 是否发布 PR 评论?
否。 此 Action 不发布拉取请求评论。 它通过以下方式报告发现: - GitHub Actions 日志 - GitHub 工作流注解 - JSON 报告 - SARIF 报告 - Markdown 摘要我可以禁用工作流注解吗?
可以。 ``` with: annotations: "false" ```我能否阻止 Action 使 CI 失败?
可以。 ``` with: fail-on: "none" ``` 这仍然会生成报告,但发现不会使工作流失败。这是否扫描二进制文件?
否。 二进制文件会自动跳过。扫描器专注于可能包含代码、配置、密钥或基础设施定义的文本文件。
Raghu Soni Python Developer and Cybersecurity Learner |
**SecureDev Action**
使用 Python, Docker, 和 GitHub Actions 构建。
[^sarif]: SARIF 表示静态分析结果交换格式 (Static Analysis Results Interchange Format)。
[^sast]: SAST 表示静态应用程序安全测试 (Static Application Security Testing)。
[^ci]: CI 表示持续集成 (Continuous Integration)。标签:Chrome Headless, CI/CD安全, DevSecOps, Docker Action, GitHub Actions, IaC安全, IPv6支持, Kubernetes安全, Llama, SARIF报告, SQL注入检测, Web截图, 上游代理, 代码安全分析, 多语言支持, 安全扫描, 安全测试框架, 安全风险评估, 容器安全, 密钥泄露检测, 开源框架, 弱加密检测, 持续集成, 时序注入, 脚本安全, 自动笔记, 请求拦截, 逆向工具, 配置文件安全