SAST(Static Application Security Testing,静态应用程序安全测试)具是一种在软件工程中使用的安全解决方案,它主要用于在程序员编写好源代码后,无需经过编译器编译,直接对源代码进行扫描,以找出其中存在的语义缺陷和安全漏洞。
SAST通过扫描源代码发现潜在的安全问题,它的有点是覆盖率高,扫描速度快,可以有效地提高代码的安全质量。同时它的缺点也很明显,那就是误报率有点高,虽然有些工具支持自定义规则,通过对项目指定针对性的规则,可以降低误报率,但是,还是要花很大的代价去定制规则和维护规则。
目前市场上有些产品提出创新的功能就是自动修复,核心功能就是发现有问题的代码,然后自动修复,或者半自动修复。这个功能听起来很美好,工具扫描发现了问题,然后不需要开发人员的干预,自动修复检测到的问题。有的工具甚至还号称“100%的扫描准确度,自动化代码修复”。本文章就是尝试通过对几种号称可以自动修复的工具的调查,看看他们实际的自动修复是什么?是否可以达到预期的宣传的那样。
第一、Semgrep.dev
semgrep是通过定义规则来实现自动修复功能的,通过在规则里添加一个fix关键字,根据定义的目标代码的模式实现替换。例如:下面这个规则:
rules:
- id: use-sys-exit
languages:
- python
message: |
Use `sys.exit` over the python shell `exit` built-in. `exit` is a helper
for the interactive shell and is not be available on all Python implementations.
https://stackoverflow.com/a/6501134
pattern: exit($X)
fix: sys.exit($X)
severity: WARNING
通过指定pattern和fix的值,就会semgrep就会自动使用fix的值替换符合pattern的字符串的内容,而不需要懂得它具体的含义或者功能。如果系统里所有的exit调用都是统一的,这么替换是没有问题的。如果有部分是直接调用exit,有部分已经调用了sys.exit了,可能会带来麻烦。
Semgrep的修复也支持正则表达式,通过fix-regex来制定规则,如下:
rules:
- id: python.requests.best-practice.use-timeout.use-timeout
patterns:
- pattern-not: requests.$W(..., timeout=$N, ...)
- pattern-not: requests.$W(..., **$KWARGS)
- pattern-either:
- pattern: requests.request(...)
- pattern: requests.get(...)
- pattern: requests.post(...)
- pattern: requests.put(...)
- pattern: requests.delete(...)
- pattern: requests.head(...)
- pattern: requests.patch(...)
fix-regex:
regex: '(.*)\)'
replacement: '\1, timeout=30)'
message: |
'requests' calls default to waiting until the connection is closed.
This means a 'requests' call without a timeout will hang the program
if a response is never received. Consider setting a timeout for all
'requests'.
languages: [python]
severity: WARNING
这里通过指定fix-regex的regex和需要替换的replacement的值,就可以实现自动替换。 例子中,的主要目的就是在所有的函数中添加一个参数timeout=30。
通过以上两个示例可以看出,semgrep所谓的自动修复只能修复符合统一规则的代码,然后,通过指定替换的值,实现字符串级别的替换。如果代码不统一的话,例如requests.request的某个调用已经含有timeout了,还是用这种方式替换就会导致问题了。对于一些需要跨函数或者通过数据流来分析来修复的漏洞,使用semgrep几乎是不可能完成的。
第二、Checkmarx
Checkmarx也号称支持autofix,不过是通过收购mobb.ai来继承实现的,他们起的名字AI Guide Remidiation。通过Checkmarx网站对autofix的介绍如下:
通过关于auto-remediation的介绍,可以了解到,Mobb AI是需要一些手工的Click来实现修复。这虽然和实际宣传的自动修复还有些差距,不过,如果开发者能够通过点击几下就可以修复安全问题,也算是一个巨大的进步。具体功能的实现结果,还有待进一步确认。功能展示下图:
安装插件之后,在IDE的右侧会有问题的描述和修复的Guide,通过指导性的Click,可以修复一些问题。
Checkmarx比较有用的一个功能是帮助修复的Guide是可以定制的,这样如果企业内部针对某一类型有自己的一套解决方案,可以通过定制来实现解决方案的推广。
第三、Moderne.io
根据moderne网站的介绍如下:
从上面介绍,可以了解到moderne号称可以100%准确地自动修复1000多个repo,提高产品的安全和质量。
根据产品介绍的文档举的例子如下:
从举的例子中的代码可以看出,moderne所说的自动修复也是基本的编码的质量的问题为主。对于跨数据流的多个函数中发现的问题,没有看到具体的示例,不敢随意下结论。根据moderne发表的关于自动修复的文章:https://assets-global.website-files.com/61d3580e463b56822388e038/6542ea2a4ff28c2be25472cd_Automated%20Code%20Remediation-Moderne-OReilly.pdf, 可以了解到自动修复目前还是有一定缺陷的,目前也只是针对一些简单的类型实现自动修复。针对稍微复杂一些的可以结合AI的提示,实现半自动化的修复。距离全自动地修复还有很长的路要走。
第四、Deepsource
工具的主页可以参考:DeepSource: The Code Health Platform 。根据主页的介绍,DeepSource的autofix也只是能够修复代码质量的问题,而且还不是全自动的,需要手工Click才可以。没有介绍关于安全相关问题是否可以自动修复。其实代码质量问题的自动修复SonarQube也提供。
第五、CodeQL
Github宣称实现了自动修复的功能,可以参考https://docs.github.com/en/code-security/code-scanning/managing-code-scanning-alerts/about-autofix-for-codeql-code-scanning,Github的静态扫描是通过CodeQL实现的,所以它的自动修复功能也就是利用了CodeQL的自动修复功能。
根据CodeQL的介绍如下:
Code scanning autofix lowers the barrier of entry to developers by combining information
on best practices with details of the codebase and alert to suggest a potential fix to the
developer. Instead of starting with a search for information about the vulnerability, the
developer starts with a code suggestion that demonstrates a potential solution for their
codebase. The developer evaluates the potential fix to determine whether it is the best
solution for their codebase and to ensure that it maintains the intended behavior.
可以知道,它是通过检测发现问题,并且给出修复的提示,开发者可以根据修复的提示评估是否是最好的解决方案,然后决定是否使用该方案。从这一点来看,它和Checkmarx有点像,通过提供解决方案的提示和示例代码,最终修复的还是开发者自己。所以,这里说的auto-fix叫“Fix Solution Tips”是否更合适呢?而且在CodeQL介绍Autofix的时候,有以下:
When one or more of these checks failed, our manual triage showed that in many cases the
proposed fix was nearly correct but needed some minor modifications that a user could
identify and manually perform.
有时提示的修复方案也不一定是完全正确,还需要手工去修复。
目前,CodeQL对于autofix的支持不是针对所有支持的问题类型的,也只是所有问题类型的一个子集。支持的语言目前也仅限于JavaScript和TypeScript。
在CodeQL分析之后,GitHub无缝地查询高级LLM以修复任何新警报。这些人工智能生成的修复建议作为代码建议发布在拉取请求的“Conversation”和“Files Changed”选项卡上。然后,您可以查看并接受这些建议的更改,甚至可以在将建议的修复合并到您的代码库之前编辑它们。CodeQL的自动修复功能最大的好处就是可以和Github无缝衔接、及时发现和快速修复。
Github支持交互式地创建自动修复的规则,这一点可以使用比较方便地创建定制的自动修复规则。
CodeQL是通过OpenAI GPT-4来实现的,不知道在国内,是否可以使用?
Auto-fix的一些想法
Autofix是一个很美好的想法,但是实现起来还是有一定的挑战。对于一些简单的编码质量的问题或者习惯,可以通过autofix实现快速修复所有类似的问题,提高开发代码重构的效率。
在实现autofix的工具里也难免会犯错误,导致autofix的结果不理想,或者修复是部分修复,需要开发人员根据已有的安全知识来完善修复方案。因此,即使使用autofix了,还是需要人工去再审查一遍,以防,有错误的autofix。即使这样,它也可以提高开发人员修复安全问题的效率,对于一些简单的规则性的问题,还可以统一模式去修复,效果更好。总之,无论宣传的多么美好,它依然只是一个工具,最终还是需要人的审查才可以放心。
参考:
Autofix | Semgrep
Checkmarx Expands Auto-Remediation with New Mobb Integration for SAST | Checkmarx.com
Checkmarx One and Mobb.ai
https://assets-global.website-files.com/61d3580e463b56822388e038/6542ea2a4ff28c2be25472cd_Automated%20Code%20Remediation-Moderne-OReilly.pdf
Autofix™️ | DeepSource
https://assets-global.website-files.com/61d3580e463b56822388e038/65a7109f192611c1ccb0d29d_Moderne%20Product%20Brief-Jan2024-v3.pdf
About autofix for CodeQL code scanning - GitHub Docs