elementsinteractive/twyn
GitHub: elementsinteractive/twyn
一款针对依赖名称的 typosquatting 攻击防护安全工具。
Stars: 55 | Forks: 5
# Twyn

[](https://pypi.org/project/twyn/)
[](https://hub.docker.com/r/elementsinteractive/twyn)
[](https://pypi.org/project/twyn/)
[](https://github.com/astral-sh/ruff)
[](LICENSE)
## 目录
- [概述](#overview)
- [快速开始](#quickstart)
- [将 `Twyn` 作为 CLI 工具使用](#using-twyn-as-a-cli-tool)
- [安装](#installation)
- [Docker](#docker)
- [CLI 选项参考](#cli-options-reference)
- [运行](#run)
- [JSON 格式](#json-format)
- [将 `Twyn` 作为库使用](#using-twyn-as-a-library)
- [日志级别](#logging-level)
- [配置](#configuration)
- [白名单](#allowlist)
- [依赖文件](#dependency-files)
- [检查通过 CLI 引入的依赖](#check-dependencies-introduced-through-the-cli)
- [选择器方法](#selector-method)
- [配置文件](#configuration-file)
- [缓存](#cache)
## 概述
`Twyn` 是一款安全工具,它会将您的依赖项名称与一组最受欢迎的依赖项进行比对,
以此来判断它们之间是否存在相似性,从而防止您使用可能非法的依赖项。
简而言之,`Twyn` 可以保护您免受 [typosquatting 攻击](https://en.wikipedia.org/wiki/Typosquatting)。
它的工作原理如下:
1. 您可以选择扫描指定依赖文件中的依赖项(`--dependency-file`),或是扫描通过 CLI 引入的依赖项(`--dependency`)。如果未提供任何选项,它将尝试在您的工作路径中查找依赖文件,并会尝试解析它找到的所有受支持的依赖文件。要了解支持哪些文件,请前往 [依赖文件](#dependency-files) 章节。
2. 如果您的包名与某个最知名的包名相匹配,则接受该包。
3. 如果您的包名与某个最常用的包名非常相似,`Twyn` 将提示错误。
4. 如果您的包名不在最知名的包列表中,并且与其他包的相似度不足以被判定为拼写错误,则接受该包。`Twyn` 会假定您正在使用的要么是一个不太流行的包(因此它无法验证其合法性),要么是您自己创建的包,因此对其他人来说是未知的。
## 快速开始
### 将 twyn 作为 CLI 工具使用
#### 安装
`Twyn` 可在 PyPi 仓库中找到,您可以通过运行以下命令来安装它:
```
pip install twyn[cli]
```
#### Docker
`Twyn` 提供了一个 Docker 镜像,可以在 [这里](https://hub.docker.com/r/elementsinteractive/twyn) 找到。
像这样使用它:
```
docker pull elementsinteractive/twyn:latest
docker run elementsinteractive/twyn --help
```
##### CLI 选项参考
| 选项 / 参数 | 类型 / 取值 | 描述 |
|--------------------------|----------------------------------------------------|-----------------------------------------------------------------------------------------------|
| `--config` | `str` (路径) | 配置文件的路径(默认为 `twyn.toml` 或 `pyproject.toml`)。 |
| `--dependency-file` | `str` (路径) | 要分析的依赖文件。支持:`requirements.txt`、`poetry.lock`、`uv.lock` 等。 |
| `--dependency` | `str` (允许多个) | 直接分析指定的依赖项。可以多次指定。 |
| `--selector-method` | `all`, `first-letter`, `nearby-letter` | 选择可能的 typosquat 的方法。 |
| `--package-ecosystem` | `pypi`, `npm`, `dockerhub` | 用于分析的包生态系统。 |
| `-v` | flag | 启用 info 级别的日志记录。 |
| `-vv` | flag | 启用 debug 级别的日志记录。 |
| `--no-cache` | flag | 禁用受信任包的缓存。始终从源获取。 |
| `--no-track` | flag | 在处理包时不显示进度条。 |
| `--json` | flag | 以 JSON 格式显示结果。隐含 `--no-track`。 |
| `-r`, `--recursive` | flag | 递归扫描目录以查找依赖文件。 |
#### 运行
**使用示例:**
```
twyn run
```
或通过以下命令获取帮助:
```
twyn run --help
```
#### JSON 格式
如果您希望输出为 JSON 格式,可以在运行 `Twyn` 时加上以下 flag:
```
twyn run --json
```
这将输出:
```
{"results":[{"errors":[{"dependency":"my-package","similars":["mypackage"]}],"source":"manual_input"}]}
```
如果 `Twyn` 是通过手动指定依赖项(使用 `--dependency`)运行的,则 source 将会是 `manual_input`。
在任何其他情况下(从文件解析依赖项时),source 将会是依赖文件的路径。每个 source 都会创建一个对应的条目。
### 将 Twyn 作为库使用
#### 安装
`Twyn` 也支持作为第三方库在您的项目中使用。要安装它,请运行:
```
pip install twyn
```
在您的代码中的使用示例:
```
from twyn import check_dependencies
typos = check_dependencies()
for typo in typos.errors:
print(f"Dependency:{typo.dependency}")
print(f"Did you mean any of [{','.join(typo.similars)}]")
```
#### 日志级别
默认情况下,作为第三方库运行时日志记录是禁用的。要覆盖此行为,您可以:
```
logging.basicConfig(level=logging.INFO)
logging.getLogger("twyn").setLevel(logging.INFO)
```
## 配置
### 白名单
有时,用户已知的合法包可能会因为与某个最受信任的包过于相似而引发错误。假设您在内部使用了一个由您开发、名为 `reqests` 的包。您可以随后将此包添加到 `allowlist` 中,这样它就不会被报告为拼写错误:
```
twyn allowlist add
```
要移除它只需:
```
twyn allowlist remove
```
### 依赖文件
要通过命令行指定依赖文件,请运行:
```
twyn run --dependency-file
```
支持以下依赖文件格式:
- `requirements.txt`
- `poetry.lock` (<1.5, >=1.5)
- `uv.lock`
- `package-lock.json` (v1, v2, v3)
- `yarn.lock` (v1, v2)
- `pnpm-lock.yaml` (v9)
- `Dockerfile`
- `docker-compose.yml`, `docker-compose.yaml`, `compose.yml`, `compose.yaml` (v1, v2, v3)
### 检查通过 CLI 引入的依赖
您也可以通过在命令行中输入来检查依赖项:
```
twyn run --dependency
```
它一次接受多个依赖项:
```
twyn run --dependency --dependency
```
当选择此选项时,不会检查任何依赖文件。
### 选择器方法
您可以在不同的操作模式之间进行选择。这将决定受信任集合中的哪些依赖项可能会是被分析依赖项的 typosquat。
- `all`:默认选项。这是最详尽的模式。它会在不进行任何假设的情况下,将您的包名与所有受信任的包名进行比对。
- `nearby-letter`:它会假定依赖项的首字母可能出现拼写错误,但如果字母在键盘上相距较远,则可能性较小。具体来说,它会将被分析的依赖项与首字母在 `ANSI` 键盘布局上仅相差一步的依赖项进行比对。
- `first-letter`:它会假定首字母出现拼写错误的可能性极低,并且不会将被分析的依赖项与具有不同首字母的依赖项进行比对。
要通过 CLI 选择特定的操作模式,请使用以下命令:
```
twyn run --selector-method
```
### 配置文件
您可以将配置保存在 `.toml` 文件中,这样您就不必每次在终端中运行 `Twyn` 时都重新指定它们。
默认情况下,当它尝试加载您的配置时,会在您的工作目录中尝试查找 `twyn.toml` 文件。如果找不到,它将回退到 `pyproject.toml`。
但是,您可以按如下方式指定配置文件:
```
twyn run --config
```
通过命令行可用的所有配置在配置文件中也都受支持。
```
[tool.twyn]
dependency_file="/my/path/requirements.txt" # it can be either a string or a list of strings
selector_method="first_letter"
logging_level="debug"
allowlist=["my_package"]
pypi_source="https://mirror-with-trusted-dependencies.com/file-pypi.json"
npm_source="https://mirror-with-trusted-dependencies.com/file-npm.json"
dockerhub_source="https://mirror-with-trusted-dependencies.com/file-dh.json"
```
每个引用的文件格式如下:
```
{
"date": "string (ISO 8601 format, e.g. 2025-09-10T14:23:00+00)",
"packages": [
{ "name": "string" }
]
}
```
### 缓存
默认情况下,`Twyn` 会将受信任包的列表缓存到一个缓存文件中,该文件位于将自动创建的 `.twyn` 目录内。
您可以通过添加以下 flag 来禁用缓存:
```
twyn run --no-cache
```
在这种情况下,它会重新下载受信任包的列表,而不将它们保存到缓存文件中。
缓存文件的有效期为 30 天,超过该期限后将重新下载受信任包列表。
要清除缓存,请运行:
```
twyn cache clear
```
标签:CLI, Python, WiFi技术, 供应链安全, 依赖安全, 域名收集, 安全工具, 拼写抢注防护, 无后门, 配置审计