🐍 🔍 GuardDog是一个命令行工具,用于识别恶意的PyPI和npm软件包。
作者:Sec-Labs | 发布时间:
项目地址
https://github.com/DataDog/guarddog
项目介绍

GuardDog是一个命令行工具,可用于识别恶意的PyPI和npm软件包。它通过Semgrep规则对软件包源代码和元数据运行一系列启发式算法。
GuardDog可以使用任何可用的启发式算法来扫描本地或远程的PyPI和npm软件包。

入门指南
安装
pip install guarddog
或者使用Docker镜像:
docker pull ghcr.io/datadog/guarddog
alias guarddog='docker run --rm ghcr.io/datadog/guarddog'
注意:在Windows上,唯一支持的安装方法是使用Docker。
示例用法
# 扫描最新版本的'requests'包
guarddog pypi scan requests
# 扫描特定版本的'requests'包
guarddog pypi scan requests --version 2.28.1
# 使用2个特定的启发式算法扫描'requests'包
guarddog pypi scan requests --rules exec-base64 --rules code-execution
# 使用除了一个之外的所有规则扫描'requests'包
guarddog pypi scan requests --exclude-rules exec-base64
# 扫描本地软件包
guarddog pypi scan /tmp/triage.tar.gz
# 扫描本地文件夹的requirements.txt文件中引用的每个软件包
guarddog pypi verify workspace/guarddog/requirements.txt
# 扫描requirements.txt文件中引用的每个软件包,并输出为sarif文件 - 仅适用于verify命令
guarddog pypi verify --output-format=sarif workspace/guarddog/requirements.txt
# 将JSON输出到标准输出 - 适用于所有命令
guarddog pypi scan requests --output-format=json
# 所有命令也适用于npm
guarddog npm scan express
# 以调试模式运行
guarddog --log-level debug npm scan express
启发式算法
GuardDog提供了两种类型的启发式算法:
-
源代码启发式算法:对软件包源代码运行的Semgrep规则。
-
软件包元数据启发式算法:针对PyPI或npm上的软件包元数据运行的Python或JavaScript启发式算法。
PyPI
源代码启发式算法:
| 启发式算法 | 描述 |
|---|---|
| shady-links | 识别包含指向具有可疑扩展名的域名的URL的软件包 |
| obfuscation | 识别使用常见混淆方法(通常由恶意软件使用)的软件包 |
| exfiltrate-sensitive-data | 识别从本地系统读取和泄露敏感数据的软件包 |
| download-executable | 识别下载并使远程二进制文件可执行的软件包 |
| exec-base64 | 识别动态执行base64编码的代码的软件包 |
| silent-process-execution | 识别静默执行可执行文件的软件包 |
| steganography | 识别从图像中提取隐藏数据并执行的软件包 |
| code-execution | 识别在setup.py文件中执行操作系统命令的软件包 |
| cmd-overwrite | 识别在setup.py中覆盖'install'命令的软件包,表明在安装软件包时自动运行一段代码 |
元数据启发式算法:
| 启发式算法 | 描述 |
|---|---|
| empty_information | 识别描述字段为空的软件包 |
| release_zero | 识别发布版本为0.0或0.0.0的软件包 |
| typosquatting | 识别名称与高度流行软件包相似的软件包 |
| potentially_compromised_email_domain | 识别软件包维护者电子邮件域名(因此软件包管理器帐户)可能已被入侵 |
| repository_integrity_mismatch | 识别链接到GitHub存储库的软件包,其中软件包包含额外的意外文件 |
| single_python_file | 识别只有一个Python文件的软件包 |
npm
源代码启发式算法:
| 启发式算法 | 描述 |
|---|---|
| npm-serialize-environment | 识别将'process.env'序列化以泄露环境变量的软件包 |
| npm-silent-process-execution | 识别静默执行可执行文件的软件包 |
| shady-links | 识别包含指向具有可疑扩展名的域名的URL的软件包 |
| npm-exec-base64 | 识别通过'eval'动态执行代码的软件包 |
| npm-install-script | 识别具有预先或后置安装脚本自动运行命令的软件包 |
元数据启发式算法:
| 启发式算法 | 描述 |
|---|---|
| empty_information | 识别描述字段为空的软件包 |
| release_zero | 识别发布版本为0.0或0.0.0的软件包 |
| potentially_compromised_email_domain | 识别软件包维护者电子邮件域名(因此软件包管理器帐户)可能已被入侵 |
| typosquatting | 识别名称与高度流行软件包相似的软件包 |
在GitHub Action中运行GuardDog
将GuardDog集成到CI流程中最简单的方法是利用SARIF输出格式,并将其上传到GitHub的代码扫描功能中。
通过这种方式,您可以获得以下功能:
- 基于GuardDog扫描输出的自动评论到您的拉取请求中
- 在GitHub UI中内置的误报管理功能
示例使用GuardDog的GitHub Action:
name: GuardDog
on:
push:
branches:
- main
pull_request:
branches:
- main
permissions:
contents: read
jobs:
guarddog:
permissions:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
name: Scan dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Install GuardDog
run: pip install guarddog
- run: guarddog pypi verify requirements.txt --output-format sarif --exclude-rules repository_integrity_mismatch > guarddog.sarif
- name: Upload SARIF file to GitHub
uses: github/codeql-action/upload-sarif@v2
with:
category: guarddog-builtin
sarif_file: guarddog.sarif
开发
运行本地版本的GuardDog
使用pip
- 确保安装了
>=python3.10 - 克隆仓库
- 创建虚拟环境:
python3 -m venv venv && source venv/bin/activate - 安装依赖:
pip install -r requirements.txt - 使用
python -m guarddog运行GuardDog
使用poetry
- 确保poetry具有
python >=3.10的环境:poetry env use 3.10.0 - 安装依赖:
poetry install - 运行guarddog:
poetry run guarddog或者poetry shell然后运行guarddog
单元测试
运行所有单元测试:make test
针对Semgrep规则运行单元测试:make test-semgrep-rules(测试位于此处)。这些测试使用了测试Semgrep规则的标准方法。
针对包元数据启发式规则运行单元测试:make test-metadata-rules(测试位于此处)。
代码质量检查
运行类型检查器:
mypy --install-types --non-interactive guarddog
运行代码风格检查器:
flake8 guarddog --count --select=E9,F63,F7,F82 --show-source --statistics --exclude tests/analyzer/sourcecode,tests/analyzer/metadata/resources,evaluator/data
flake8 guarddog --count --max-line-length=120 --statistics --exclude tests/analyzer/sourcecode,tests/analyzer/metadata/resources,evaluator/data --ignore=E203,W503
致谢
作者:
灵感来源:
- Backstabber’s Knife Collection: A Review of Open Source Software Supply Chain Attacks
- What are Weak Links in the npm Supply Chain?
- A Survey on Common Threats in npm and PyPi Registries
- A Benchmark Comparison of Python Malware Detection Approaches
- Towards Measuring Supply Chain Attacks on Package Managers for Interpreted Languages
标签:工具分享, 扫描工具