当一个坏的行为者发生Typosquatting时:
- 创建一个被恶意软件感染的开放源代码包。
- 将该软件包命名为与现有流行软件包相似的名称。
- 将其上传到一个公共资源库,希望开发者会错误地下载它而不是有效的软件包。
不幸的是,错别字归属是非常有效的,并且已经成为破坏组织的最流行的方式之一,通常以提取数据为目的。
例如,在2020年7月,Python "request "包(*注意错别字:*request,而不是有效的包名request )被下载了超过10000次。它包含的恶意软件在.bashrc中安装了一个守护程序,为攻击者提供了机器上的远程外壳。
比较一下像request这样的流行包的typosquat的有效性和pymafka的有效性,后者的名字不是基于一个流行包,但也被发现包含恶意软件。

来源:pypistats.org
显然,盗版在传播恶意软件方面要有效数千倍,最好是将其作为恶意软件感染的一个关键载体单独处理。
在本教程中,你将学会在Python生态系统中创建一个具有成本效益的方法来检测错别字的软件包,但该解决方案可以很容易地扩展到任何其他开源语言。该方法包括
- 从Python软件包索引(PyPI)中确定下载量最大的前10个软件包。
- 将它们的名字与PyPI上的其他软件包进行比较,以便找到仅有几个字符差异的例子。
- 创建一个Python例程来识别潜在的排版错误。
- 审查结果以确定需要进一步调查的软件包。
正如你所看到的,利用Python的灵活性和成熟的机器学习(ML)库来快速执行本来是一个非常劳动密集型的过程是相对容易的。
在你开始之前。安装Typosquatting Detector Python环境
为了跟上本文的代码,你可以下载并安装我们预先建立的 Typosquatting Detector环境,其中包括 :
为了下载这个随时可用的Python项目,你需要 创建一个免费的ActiveState Platform账户。只需使用你的GitHub凭证或你的电子邮件地址来注册。注册很简单,它可以解锁ActiveState平台的许多其他 依赖性管理的好处。
或者你也可以使用我们的State工具CLI来安装运行环境和项目代码。

对于Windows用户,在CMD提示下运行以下程序,自动下载并安装Typosquatting Detector运行环境和项目代码到一个虚拟环境中:
powershell -Command "& $([scriptblock]::Create((New-Object Net.WebClient).DownloadString('https://platform.activestate.com/dl/cli/2080745363.1499703358_pdli01/install.ps1'))) -c'state activate --default Pizza-Team/Typosquatting-Detector'"
对于Linux或Mac用户,运行以下程序,自动下载并安装Typosquatting Detector的运行环境和项目代码到虚拟环境中:
sh <(curl -q https://platform.activestate.com/dl/cli/2080745363.1499703358_pdli01/install.sh) -c'state activate --default Pizza-Team/Typosquatting-Detector'
步骤1-寻找数据
像Python这样一个强大而开放的生态系统的好处是,有人可能已经创建了与你所需要的类似的东西。在这种情况下, Hugo van Kemenade 每月都会生成一份 PyPI上下载量最大的5000个软件包的 列表 。 我将使用这个列表中的前10个条目进行比较。目前,该列表包括:
- boto3
- botocore
- urllib3
- setuptools
- 请求
- s3transfer
- 六
- python-dateutil
- 认证
- idna
为了找到潜在的盗版实例,我们将把这10个软件包与PyPI上的全部软件包列表进行比较,你可以在 pypi.org/simple/,找到HTML格式的 列表。为了方便我们的工作,我将使用这个 JSON格式的列表快照。
第2步-选择一个ML库
在现代计算中,有很多ML算法,它们中的大多数都可以作为Python中的库。对于我们的目的,我们将寻找与现有列表中的单词相似的单词。有多种方法来执行这种文本匹配,包括:
- 完全匹配
- 模糊逻辑(例如,用于发现双重字符)
- 语音相似性(例如,发现phish与fish)。
- 使用 列文斯坦距离等方法检查其他微小的字母/格式差异 。
Levenshtein距离是根据从原始字符串到你要比较的字符串的变化数量来计算指标的。例如,从 pythonlib 到 python_lib 的移动 算作一个变化,从 meat 到 meet的移动也是 如此。我们可以利用这一点来确定,当有人试图在一个流行的框架上打字时,通常会引入多种打字方式。为了我们的目的,我们将看一下与原名称有三个变化的包名。
在本教程中,我们将使用 jellyfish 库,它包括Levenshtein距离 和其他选项。
第3步--创建应用程序
这个项目的所有代码都可以 在GitHub上找到 。如果你已经安装了预置的Python 3.10 Typosquatting Detector运行时,你已经从GitHub下载了项目代码准备运行,但让我们先回顾一下这些代码。
步骤A-检索JSON文件并准备处理数据
从URL中交互和检索JSON是一个简单的过程,无论它是来自静态文件还是API。它只需要几个简单的命令。在我们开始之前,我们需要导入请求和JSON以启用该功能。然后,当我们从URL请求内容时,它将自动加载到一个我们可以使用的对象中。
首先,让我们得到最受欢迎的包的列表。代码中包括打印语句,以显示它的作用。
# List of top packages
接下来,将第二个JSON文件加载到可用软件包的完整列表中。
# List of all packages
步骤B-准备好逻辑
用水母库比较文件的最快方法是使用一个嵌套循环。这样,我们就可以控制检查多少个顶级软件包,并确保对照整个软件包列表来检查它们。
# How many times to loop (JSON starts counting at zero)
这就是我们的输出在这一点上的样子。请注意,它只显示精确匹配(没有其他潜在的错别字)。为了便于阅读,输出的格式为YAML:
(py-env) [root@f code]# python3 main.py
步骤C-使用Jellyfish库进行分析
现在,是介绍水母库的时候了。使用现有软件包的好处是,大部分的逻辑都在其中处理。在这种情况下,我们需要做的就是调整if语句,使其超越精确匹配,然后用一些特定的参数调用jellyfish。
# What Levenshtein distance are we looking for
第4步--审查Typosquatting检测结果
正如你所看到的,最终的结果确定了相当多的软件包,如果发现它们含有恶意软件,可以进一步调查并可能从PyPI中删除。较短的软件包名称有最多的匹配,因为只需要很少的改动就可以形成一个全新的词。有鉴于此,我只是提供了 idna 和 6的总回报 数。
boto3: ['2to3', 'Rot13', 'Toto', 'b2tob3', 'baton', 'batou', 'bits3', 'bobo', 'bobos3', 'bobot', 'bodo', 'bogo', 'boko', 'bolos', 'boo', 'book', 'boom', 'boon', 'boooo', 'boos', 'boot', 'boron', 'boson', 'bot', 'botco', 'botcom', 'botd', 'bote', 'both', 'botlog', 'botly', 'botm', 'botnoi', 'boto', 'boto3', 'boto342', 'boto3r', 'boto4', 'botok', 'botol2', 'botol4', 'botol6', 'botool', 'botor', 'botosc', 'botouk', 'botovh', 'botox', 'botoy', 'botpy', 'bots', 'botson', 'bottom', 'bottr', 'bottt', 'botty', 'botv', 'botx', 'botxy', 'boty', 'botz', 'bouto', 'bowtor', 'bozor', 'broto', 'bto', 'coto', 'dota3', 'doto', 'foto', 'foto2', 'foton', 'goto', 'gotoh', 'hotot', 'iboto', 'koto', 'loto', 'moto', 'motoo', 'motop', 'motor', 'oto', 'pyboto3', 'roto', 'rotor', 'toto9', 'xoto3', 'yoton']
结论--扩展Typosquatting检测程序
正如你所看到的,现在Python生态系统中的机器学习能力是相当强大的,并且可以提供一种简单的、具有成本效益的方法,在你将其导入到你的构建程序或CI/CD系统之前,识别潜在的拼写错误的软件包。
为了使事情更进一步,可以考虑以下额外的检查和平衡:
- 调查结果,以确定哪些包是真正有效的结果。
- 另外,你也可以把整个软件包列表视为可疑的,并检查它们是否在30天后仍然留在PyPI中。在大多数情况下,受影响的软件包会在短时间内从PyPI中删除。
- 将有效的软件包名称添加到一个例外文件中,你可以在下次运行该程序时参考,以便从结果中删除有效的软件包。
- 将该程序扩展到其他生态系统,如JavaScript、PHP、Rust等。
你也可以考虑在该例程中加入语音检查,或者利用jellyfish库中的一些其他算法。