mcpField
D
detecting-typosquatting-packages

detecting-typosquatting-packages

github.com/mukul975安全35.2k41 次安装8 周前更新
代码仓库

关于 detecting-typosquatting-packages

用于软件供应链防御的技能,指导安全团队在安装前筛查疑似仿冒包,并将检查纳入 CI/CD。内容涵盖名称变体检测、风险核查和结果分级。

主要功能

  1. 01对照热门包名筛查近似名称
  2. 02生成常见拼写变体
  3. 03结合注册表元数据评估风险
  4. 04将检查纳入 CI/CD 门禁
  5. 05参考已知仿冒包数据集

适用场景

  1. 01添加依赖前检查包名
  2. 02审查 AI 生成或教程提供的依赖
  3. 03在拉取请求中拦截新依赖风险
  4. 04排查锁文件中的可疑包名

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill detecting-typosquatting-packages

安装后在 Claude Code 中输入/detecting-typosquatting-packages确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
references/
api-reference.md
standards.md
scripts/
agent.py

详细介绍

检测域名仿冒包

仅限授权使用: 本技能用于防御性软件供应链安全、包筛查和授权研究。仅针对你有权大规模查询的注册表以及你打算为自己组织评估的包,使用本文中的语料库匹配和注册表查询技术。大规模自动抓取注册表可能违反注册表的服务条款。

概述

域名仿冒(Typosquatting)是一种软件供应链攻击(MITRE ATT&CK T1195.002 — 供应链妥协:破坏软件供应链),其中攻击者发布一个恶意包,其名称与流行的合法包极为相似——用 reqeusts 冒充 requests,用 python-sqlite 冒充 sqlite3,用 crossenv 冒充 cross-env。开发者如果打错名称、从被投毒的教程中复制名称,或信任 AI 生成的依赖列表(即 "slopsquatting" 变体,模型幻觉出包名,攻击者随后注册这些名称),就会安装这个仿冒包。由于大多数生态系统会执行安装时脚本(npm 中的 postinstall,PyPI 中的 setup.py/构建钩子),恶意载荷会立即以开发者的权限运行。

本技能涵盖主动的、安装前检测:使用攻击者所用的相同名称变异原语,将候选包名与流行/已知良好名称的语料库进行筛查,然后对高风险匹配进行分诊。典型的开源检测器是 typomania(Rust Foundation),它是学术工具 typogard("Defending Against Package Typosquatting",堪萨斯大学)的 Rust 移植版;typomania 为 crates.io 的实时域名仿冒检查提供支持。跨生态系统的覆盖来自 Microsoft OSSGadget 的 oss-find-squats,对于 PyPI 则来自 IQTLabs pypi-scan。ecosyste-ms 的 typosquatting-dataset 提供了已知仿冒包映射到其合法目标的精选地面真值语料库。

来源:Rust Foundation typomania(https://github.com/rustfoundation/typomania)、Microsoft OSSGadget、ecosyste-ms typosquatting-dataset,以及 OWASP CI/CD / SLSA 供应链指南。

何时使用

  • 在向 package.json、requirements.txt、pyproject.toml 或 Cargo.toml 添加新依赖之前
  • 作为 CI/CD 门禁,筛查拉取请求中每个新引入的依赖名称
  • 在分诊 AI 生成或来自教程的依赖列表时("slopsquatting" 审查)
  • 在安全审查锁文件差异时,以捕获被替换或新固定的仿冒包
  • 在构建注册表侧或代理侧的防护栏以阻止安装可疑仿冒包时

前置条件

  • Rust 工具链(cargo)用于构建/使用 typomania,或使用预构建的 OSSGadget 发行版
  • Python 3.8+ 用于 pypi-scan 和本技能中的辅助脚本
  • 对目标注册表公共 API(npmjs.org、pypi.org、crates.io)的网络访问
  • 用于该生态系统的"流行"包名语料库(下载量或 top-N 列表)

安装工具:

# typomania (library + example harness) — Rust Foundation
git clone https://github.com/rustfoundation/typomania
cd typomania
cargo build --release
cargo run --example registry   # demonstrates the Harness against a fake registry

# OSSGadget (Microsoft) — cross-ecosystem squat finder
# Download a release binary, then:
oss-find-squats pkg:npm/requests          # purl syntax
oss-find-squats pkg:pypi/reqeusts

# pypi-scan (IQTLabs) — PyPI typosquat enumerator
git clone https://github.com/IQTLabs/pypi-scan
cd pypi-scan
pip install -r requirements.txt

# ecosyste-ms ground-truth dataset of known squats
git clone https://github.com/ecosyste-ms/typosquatting-dataset

目标

  • 使用标准变异原语为给定的合法名称生成候选仿冒包集合
  • 将候选包名与流行名称语料库进行筛查并标记近似匹配
  • 为每个可疑仿冒包补充注册表元数据(年龄、下载量、维护者、安装脚本)
  • 对发现结果进行评分和分诊,以抑制误报(合法分支、作用域包)
  • 将检查接入 CI/CD,作为新依赖的阻断门禁

MITRE ATT&CK 映射

技术 ID名称战术
T1195.002供应链妥协:破坏软件供应链初始访问

域名仿冒的依赖是 T1195.002 的投递载体:攻击者不是通过入侵真实包来破坏受害者的供应链,而是让恶意仿冒包被安装在其位置。相关的下游行为通常包括通过安装钩子执行的 T1059(命令和脚本解释器)以及令牌和环境变量的 T1041/T1567(数据渗出)。

工作流

第 1 步:构建热门名称语料库

检测器需要一组合法名称作为参照集来进行比对。拉取生态系统中按下载量排名靠前的包。

# PyPI: top packages dataset (Hugo van Kemenade's top-pypi-packages)
curl -s https://hugovk.github.io/top-pypi-packages/top-pypi-packages.min.json \
  -o top-pypi-packages.json

# npm: query the registry's most-depended-upon search
curl -s 'https://registry.npmjs.org/-/v1/search?text=not:unstable&popularity=1.0&size=250' \
  -o npm-top.json

# crates.io: top crates by downloads
curl -s 'https://crates.io/api/v1/crates?sort=downloads&per_page=100' \
  -H 'User-Agent: typosquat-screen ([email protected])' -o crates-top.json
第 2 步:使用标准变异原语生成候选抢注名称

typomania/typogard 应用一组固定的名称变换,这些变换反映了攻击者的真实行为。复现它们,以理解筛查机制必须拦截什么:

1. Repeated characters     requests  -> reqquests
2. Omitted characters      requests  -> requsts
3. Swapped/transposed      requests  -> reqeusts
4. Swapped words           python-dateutil -> dateutil-python
5. Common typos (1-edit)   requests  -> rewuests   (keyboard adjacency)
6. Homophones / vowel swap requests  -> requeasts
7. Version / suffix tricks lodash    -> lodashs, lodash-js
8. Delimiter swaps         cross-env -> crossenv, cross_env
9. Scope confusion (npm)   @types/node -> types-node

运行 typomania 的测试框架,它将这些实现为 Corpus 和 Harness trait 背后的可复用原语:

# In the typomania checkout: feed your popular corpus, then check a name.
# The Harness::check method (parallelized via rayon) compares the candidate
# against every corpus entry using the squatting primitives.
cargo run --example registry -- --corpus top-pypi-packages.json --name reqeusts
第 3 步:使用 OSSGadget oss-find-squats 进行筛查

OSSGadget 查询实时注册表,对所提供包生成变异,并报告哪些变异名称实际上作为已发布包存在。

# Find names that squat on a legitimate package, checking which exist in the registry
oss-find-squats pkg:npm/lodash
oss-find-squats pkg:pypi/requests

# Reverse direction: given a SUSPECT name, find the legitimate package it mimics
oss-find-squats --quiet pkg:npm/loadsh
第 4 步:使用 pypi-scan 枚举 PyPI 抢注名称
cd pypi-scan
# Find candidate typosquats of a specific package
python pypi_scan.py -p requests

# Scan the top-N most-downloaded PyPI packages for existing squats
python pypi_scan.py -n 50
第 5 步:用注册表元数据丰富疑似抢注名称

一个近似名称只有在同时年轻、低下载量或附带安装脚本时才是可疑的。拉取元数据以进行分诊:

# npm package metadata: creation time, maintainers, scripts
curl -s https://registry.npmjs.org/loadsh | \
  python -c 'import sys,json;d=json.load(sys.stdin);v=d["dist-tags"]["latest"];print("created:",d["time"]["created"]);print("scripts:",d["versions"][v].get("scripts",{}))'

# npm download counts (last week)
curl -s https://api.npmjs.org/downloads/point/last-week/loadsh

# PyPI JSON API: release history and author
curl -s https://pypi.org/pypi/reqeusts/json | \
  python -c 'import sys,json;d=json.load(sys.stdin);i=d["info"];print(i["name"],i["author"],i["home_page"]);print("releases:",list(d["releases"].keys()))'
第 6 步:评分、分诊与确认

将信号组合成风险评分。高风险 = 与热门名称的编辑距离小,且(包年龄 < 90 天或下载量 < 1000 或存在 postinstall/preinstall/安装时网络调用)。与 ecosyste-ms 已知抢注数据集交叉核对:

# Is this name a documented squat?
grep -i 'loadsh' typosquatting-dataset/data/*.csv

通过检查安装脚本和源码 tarball(仅在沙箱/虚拟机中)来确认恶意意图——绝不要在工作站上对可疑包执行 npm install 或 pip install。

第 7 步:在 CI/CD 中强制执行

添加一个阻断性门禁,对 PR 引入的每一个新依赖名称进行筛查:

# .github/workflows/typosquat-gate.yml
name: typosquat-gate
on: [pull_request]
jobs:
  screen:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Screen new dependencies
        run: |
          git diff origin/${{ github.base_ref }}...HEAD -- package.json requirements.txt \
            | grep '^+' | python scripts/agent.py screen --ecosystem npm --corpus top.json --stdin

工具与资源

工具用途来源
typomaniaRust 抢注检测库(为 crates.io 提供支持)https://github.com/rustfoundation/typomania
OSSGadget oss-find-squats跨生态系统抢注查找器(purl)https://github.com/microsoft/OSSGadget
pypi-scanPyPI 抢注枚举器https://github.com/IQTLabs/pypi-scan
ecosyste-ms typosquatting-dataset精选的已知抢注真值https://github.com/ecosyste-ms/typosquatting-dataset
top-pypi-packagesPyPI 热门名称语料库https://hugovk.github.io/top-pypi-packages/
OWASP CI/CD Security Top 10供应链控制指南https://owasp.org/www-project-top-10-ci-cd-security-risks/

变异原语参考

原语合法抢注为何有效
换位requestsreqeusts常见打字失误
遗漏requestsrequsts漏掉字符
重复requestsreqquests按键卡住
分隔符替换cross-envcrossenv连字符与无连字符的歧义
词序python-dateutildateutil-python复合名称顺序颠倒
同形字/元音requestsrequeasts视觉/语音相似
后缀/作用域lodashlodash-js, loadsh看似合理的"官方"变体

验证标准

  • 为每个范围内的生态系统下载热门名称语料库
  • 复现变异原语,并正确标记出一个已知抢注(例如 loadsh)
  • 对至少一个真实包运行 typomania / OSSGadget / pypi-scan
  • 用年龄、下载量和安装脚本元数据丰富疑似抢注
  • 将发现结果与 ecosyste-ms 已知抢注数据集交叉核对
  • 风险评分抑制明显的误报(合法的带作用域/分叉包)
  • CI/CD 门禁在每个拉取请求上筛查新依赖名称
  • 未在一次性沙箱之外安装任何可疑包

评论

支持 Markdown