30条新Semgrep规则:Ansible、Java、Kotlin、Shell脚本等安全检测指南

本文介绍了30条针对Ansible剧本、Java/Kotlin代码、Shell脚本和Docker Compose配置文件的定制Semgrep规则,重点解析了通用模式和YAML支持两大高级功能,帮助开发者检测常见安全漏洞。

30 new Semgrep rules: Ansible, Java, Kotlin, shell scripts, and more

Matt Schwager, Sam Alws
January 17, 2024
containers, open-source, semgrep

我们发布了一套包含30条定制Semgrep规则的集合,涵盖Ansible剧本、Java/Kotlin代码、Shell脚本和Docker Compose配置文件。这些规则创建并用于审计所列技术中的常见安全漏洞。这次新发布的Semgrep规则加入了我们的公共CodeQL查询和测试手册,旨在与安全社区分享我们的技术专长。本文将简要介绍新的Semgrep规则,然后深入探讨用于创建这些规则的两个较少人知的Semgrep功能:通用模式和YAML支持。

对于我们内部Semgrep规则的这次发布,我们专注于诸如未加密的网络传输(HTTP、FTP等)、禁用的SSL证书验证、常见命令行工具的不安全标志、无限制的IP地址绑定、杂项Java/Kotlin问题等。以下是我们新的规则:

Mode Rule ID Rule description
Generic container-privileged 发现具有扩展权限的容器命令
Generic container-user-root 发现以root身份运行的容器命令
Generic curl-insecure 发现禁用SSL验证的curl命令
Generic curl-unencrypted-url 发现使用未加密URL(如HTTP、FTP等)的curl命令
Generic gpg-insecure-flags 发现使用不安全标志的gpg命令
Generic installer-allow-untrusted 发现允许不受信任安装的安装程序命令
Generic openssl-insecure-flags 发现使用不安全标志的openssl命令
Generic ssh-disable-host-key-checking 发现禁用主机密钥检查的ssh命令
Generic tar-insecure-flags 发现使用不安全标志的tar命令
Generic wget-no-check-certificate 发现禁用SSL验证的wget命令
Generic wget-unencrypted-url 发现使用未加密URL(如HTTP、FTP等)的wget命令
Java, Kotlin gc-call 调用gc建议JVM运行垃圾收集器并回收内存。这只是一个建议,不能保证会发生任何事情。依赖此行为进行正确性或内存管理是一种反模式。
Java, Kotlin mongo-hostname-verification-disabled 发现禁用SSL主机名验证的MongoDB客户端
YAML (Ansible) apt-key-unencrypted-url 发现使用未加密URL(如HTTP、FTP等)的apt密钥下载
YAML (Ansible) apt-key-validate-certs-disabled 发现禁用SSL验证的apt密钥
YAML (Ansible) apt-unencrypted-url 发现使用未加密URL(如HTTP、FTP等)的apt deb
YAML (Ansible) dnf-unencrypted-url 发现使用未加密URL(如HTTP、FTP等)的dnf下载
YAML (Ansible) dnf-validate-certs-disabled 发现禁用SSL验证的dnf
YAML (Ansible) get-url-unencrypted-url 发现使用未加密URL(如HTTP、FTP等)的文件下载
YAML (Ansible) get-url-validate-certs-disabled 发现禁用SSL验证的文件下载
YAML (Ansible) rpm-key-unencrypted-url 发现使用未加密URL(如HTTP、FTP等)的RPM密钥下载
YAML (Ansible) rpm-key-validate-certs-disabled 发现禁用SSL验证的RPM密钥
YAML (Ansible) unarchive-unencrypted-url 发现使用未加密URL(如HTTP、FTP等)的解压下载
YAML (Ansible) unarchive-validate-certs-disabled 发现禁用SSL验证的解压下载
YAML (Ansible) wrm-cert-validation-ignore 发现禁用证书验证的Windows远程管理连接
YAML (Ansible) yum-unencrypted-url 发现使用未加密URL(如HTTP、FTP等)的yum下载
YAML (Ansible) yum-validate-certs-disabled 发现禁用SSL验证的yum
YAML (Ansible) zypper-repository-unencrypted-url 发现使用未加密URL(如HTTP、FTP等)的Zypper仓库
YAML (Ansible) zypper-unencrypted-url 发现使用未加密URL(如HTTP、FTP等)的Zypper包
YAML (Docker Compose) port-all-interfaces 服务端口在所有接口上暴露

Semgrep 201: 中级功能

Semgrep是一个用于查找代码模式的静态分析工具。这包括安全漏洞、错误变体、秘密检测、性能和正确性问题等。虽然Semgrep包括专有的云服务和更高级的规则,但Semgrep CLI可以免费安装并在本地运行。您可以使用以下命令运行Trail of Bits的规则,包括上述规则:

1
semgrep scan --config p/trailofbits /path/to/code

本文不会详细介绍上面提出的每个规则。Semgrep的基础知识已经被Trail of Bits和更广泛的安全社区广泛讨论,因此本文将更深入地讨论两个较少人知的Semgrep功能:通用模式和YAML支持。

通用模式

Semgrep的通用模式提供了一种搜索任意文本的简单方法。与Semgrep对Java和Python等编程语言的语法支持不同,通用模式是经过美化的文本搜索。自然,这既有利也有弊:通用模式倾向于产生更多的误报,但也产生更少的漏报。换句话说,它会产生更多的发现,但您可能需要对它们进行筛选。限制规则路径是避免误报的一种方法。然而,使用通用模式的主要原因是它可以搜索的数据广度。

通用模式大致可以看作是正则表达式的符合人体工程学的替代品。它们都执行任意文本搜索,但通用模式提供了改进的换行符和其他空格处理。它还提供了Semgrep熟悉的省略号运算符、元变量,并与Semgrep生态系统的其余部分紧密集成以管理发现。任何文本文件或基于文本的数据都可以在通用模式下进行分析,因此当您想要分析不太常用的格式(如Jinja模板、NGINX配置文件、HAML模板、TOML文件、HTML内容或任何其他基于文本的格式)时,这是一个很好的选择。

通用模式的主要缺点是它对其解析的文本没有语义理解。这意味着,例如,模式可能会在注释代码或其他意外位置被错误检测——换句话说,就是误报。例如,如果我们在以下代码中同时使用通用模式和python模式搜索os.system(...),我们将得到不同的结果:

1
2
3
4
5
6
import os

# Uncomment when debugging
# os.system("debugger")

os.system("run_production")

图1:带注释行的Python代码

1
2
3
4
5
6
$ semgrep scan --lang python --pattern "os.system(...)" test.py 
...                       
    test.py 
            6┆ os.system("run_production")
...
Ran 1 rule on 1 file: 1 finding.

图2:python模式语义理解注释。

1
2
3
4
5
6
7
8
$ semgrep scan --lang generic --pattern "os.system(...)" test.py 
...                       
    test.py 
            4┆ # os.system("debugger")
            ⋮┆----------------------------------------
            6┆ os.system("run_production")
...
Ran 1 rule on 1 file: 2 findings.

图3:通用模式不语义理解注释。

通用模式的另一个缺点是它错过了Semgrep的广泛等价列表。尽管如此,我们仍然认为在搜索这些特定模式时,它是正确的工具。如果这意味着我们不会错过关键的安全错误,筛选一些误报是可以的。

考虑到通用模式的缺点,为什么在本文发布的许多规则中使用它?毕竟,Semgrep对Bash和Dockerfiles都有官方语言支持。但考虑一下ssh-disable-host-key-checking规则。使用通用模式将在Bash脚本、Dockerfiles、CI配置、文档文件、各种编程语言的系统调用或其他我们甚至没有考虑的地方找到禁用StrictHostKeyChecking的SSH命令。使用官方的Bash或Dockerfile支持将仅覆盖单个用例。换句话说,使用通用模式为我们提供了适用于许多不同场景的相对简单的启发式方法的最广泛覆盖。

有关更多信息,请参阅Semgrep关于通用模式匹配的官方文档。

YAML支持

除了通用模式,YAML支持帮助Semgrep成为在文件系统中搜索基本上任何基于文本的文件中的代码或文本的一站式商店。而YAML正在吞噬世界:Kubernetes配置、AWS CloudFormation、Docker Compose、GitHub Actions、GitLab CI、Argo CD、Ansible、OpenAPI规范,是的,甚至Semgrep规则本身都是用YAML编写的。事实上,Semgrep有最佳实践规则,用Semgrep规则为Semgrep规则编写。Sem-ception。

当然,您可以在您选择的编程语言中编写一个基本实用程序,使用主流YAML库解析YAML并搜索基本启发式方法,但那样您就会错过Semgrep生态系统的其余部分。您可以在一个地方管理所有这些不同类型的文件和文件格式,这是Semgrep的杀手级功能。YAML规则与Python规则相邻,Python规则与Java规则相邻,Java规则与通用规则相邻。它们都在CI中一起运行,并且可以在同一地方管理发现。不再需要十个工具来处理十种类型的文件。

我们最近参与了一个包含大型Ansible实现的审计。考虑到这一点,我们着手覆盖Ansible.Builtin命名空间中可能预期的许多基本安全问题。使用Semgrep的YAML规则格式搜索YAML模式往往会让人头晕,但一旦习惯了,它就变得相对公式化。像JSON和YAML这样的高度结构化格式使得搜索模式变得简单明了。本文顶部提出的Ansible规则相对明确,因此让我们考虑port-all-interfaces规则模式,它更明显地突出了YAML功能:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
patterns:
  - pattern-inside: |
      services:
        ...
  - pattern: |
      ports:
        - ...
        - "$PORT"
        - ...
  - focus-metavariable: $PORT
  - metavariable-regex:
      metavariable: $PORT
      regex: '^(?!127.\d{1,3}.\d{1,3}.\d{1,3}:).+'

图4:搜索在所有接口上监听的端口的模式

pattern-insidepattern运算符中使用的| YAML块样式指示符表示下面的文本是纯文本字符串,而不是额外的Semgrep规则语法。Semgrep然后将此纯文本字符串解释为YAML。同样,这是YAML中的YAML,起初需要一些眯眼,但规则的其余部分是相对直接的Semgrep语法。

规则本身是寻找绑定到所有接口的服务。Docker Compose文档指出,默认情况下,在指定端口时,服务将监听0.0.0.0。此规则查找不以环回地址(如127.0.0.1)开头的端口,这表明它们在所有接口上监听。这并不总是一个问题,但在某些情况下可能导致诸如防火墙绕过等问题。

用Semgrep扩展您的覆盖范围

Semgrep是一个用于在许多不同技术中查找错误的伟大工具。本文介绍了30条新的Semgrep规则,并讨论了两个较少人知的功能:通用模式和YAML支持。将YAML和通用搜索添加到Semgrep广泛支持的编程语言列表中,使其成为一个更通用的工具。有问题代码或基础设施的启发式方法及其相应的发现可以在一个位置管理。

如果您想阅读更多关于我们在Semgrep上的工作,我们以多种方式使用了其功能,例如保护机器学习管道、发现goroutine泄漏和保护Apollo GraphQL服务器。

如果您对为您的项目定制Semgrep规则感兴趣,请联系我们。

如果您喜欢这篇文章,请分享: Twitter LinkedIn GitHub Mastodon Hacker News

页面内容 Semgrep 201: 中级功能 通用模式 YAML支持 用Semgrep扩展您的覆盖范围 最近的帖子 Trail of Bits的Buttercup在AIxCC挑战赛中获得第二名 Buttercup现已开源! AIxCC决赛:记录表 攻击者的提示注入工程:利用GitHub Copilot 作为新员工发现NVIDIA Triton中的内存损坏 © 2025 Trail of Bits. 使用Hugo和Mainroad主题生成。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计