semgrep 简介
semgrep 是一种静态代码分析工具,用于发现和修复软件代码中的安全漏洞、Bug 和编码风格问题。它可以帮助开发人员和安全团队在早期发现和解决潜在的代码问题,提高软件质量和安全性。
以下是 semgrep 的一些主要功能和特点:
静态代码分析:semgrep 使用静态分析技术,检查源代码文件中的问题,而无需运行代码。多种支持语言:semgrep 支持多种编程语言,包括但不限于 Python、JavaScript、Go、Java、C/C++、Ruby、Rust 和 PHP。可配置的规则集:semgrep 提供了丰富的规则集,用于检查各种代码问题,包括安全漏洞、常见编程错误、最佳实践、代码风格等。同时,你也可以根据自己的需求创建和定制规则。易于集成:semgrep 可以作为命令行工具使用,也可以通过插件集成到各种集成开发环境(IDE)和持续集成/持续交付(CI/CD)流程中。快速且可扩展:semgrep 的设计目标之一是快速分析大型代码库。它采用一些优化策略,使得分析速度较快,同时还支持多线程和分布式分析,以提高扩展性和效率。
总而言之,semgrep 是一个功能强大的静态代码分析工具,通过检查源代码中的问题,帮助开发人员和安全团队发现和修复潜在的安全漏洞、Bug 和编码问题。它可以提高软件的质量、安全性和可维护性。
准备工作
- 准备好C语言的源码
admin@hpc-1:~/test_semgrep$ cat prime.c
#include <stdio.h>int isPrime(int num) {int i;if (num <= 1) {return 1; // 不是素数}for (i = 2; i * i <= num; i++) {if (num % i == 0) {return 1; // 不是素数}}return 0; // 是素数
}int main() {int number;printf("请输入一个整数:");scanf("%d", &number);if (isPrime(number) == 0) {printf("%d 是素数。\n", number);} else {printf("%d 不是素数。\n", number);}return 0;
}
admin@hpc-1:~/test_semgrep$
安装semgrep
- pip3直接安装
admin@hpc-1:~/test_semgrep$ sudo apt install semgrep -y
- 不指定rule,就是用semgrep的默认规则进行扫描了
admin@hpc-1:~/test_semgrep$ semgrep ./*.c┌──── ○○○ ────┐
│ Semgrep CLI │
└─────────────┘ Scanning 1 file (only git-tracked) with:✔ Semgrep OSS✔ Basic security coverage for first-party code vulnerabilities.✘ Semgrep Code (SAST)✘ Find and fix vulnerabilities in the code you write with advanced scanning and expert security rules.✘ Semgrep Supply Chain (SCA)✘ Find and fix the reachable vulnerabilities in your OSS dependencies.💎 Get started with all Semgrep products via `semgrep login`.
✨ Learn more at https://sg.run/cloud. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 ┌────────────────┐
│ 1 Code Finding │
└────────────────┘prime.c❯❱ c.lang.security.insecure-use-scanf-fn.insecure-use-scanf-fnAvoid using 'scanf()'. This function, when used improperly, does not consider buffer boundaries andcan lead to buffer overflows. Use 'fgets()' instead for reading input. Details: https://sg.run/nd1g 23┆ scanf("%d", &number);┌──────────────┐
│ Scan Summary │
└──────────────┘Ran 41 rules on 1 file: 1 finding.
💎 Missed out on 852 pro rules since you aren't logged in!
⚡ Supercharge Semgrep OSS when you create a free account at https://sg.run/rules.
admin@hpc-1:~/test_semgrep$
- 看上去如果login了,会有更多预先写好的rule可供扫描
自定义semgrep rule
- 这个是学习的核心
- 关于写rule的教程,参考这里 https://semgrep.dev/learn
- 关于rule的书写规则,参考这里https://semgrep.dev/docs/writing-rules/rule-syntax
- 下面编写两条rule
(1)检测return后直接加空格加一个数字
(2)检测汉字 - rule的内容如下
admin@hpc-1:~/test_semgrep$ cat c_rules.yaml
rules:- id: return-integerpatterns:- pattern-regex: return\s+\d+;message: "Found a return statement with an integer: "languages:- cseverity: WARNINGrecommended: truemetadata:description: "Detects return statements with integers in the code."category: "Code Quality"- id: detect-chinese-characterspatterns:- pattern-regex: \p{Script=Han}+message: "Detected Chinese character in the code"severity: WARNINGlanguages:- cmetadata:description: "Detects the presence of Chinese characters in C code."category: "Code Quality"
admin@hpc-1:~/test_semgrep$
- 使用–config指定rule进行扫描
admin@hpc-1:~/test_semgrep$ semgrep --config c_rules.yaml ./*.c┌─────────────┐
│ Scan Status │
└─────────────┘Scanning 1 file (only git-tracked) with 2 Code rules:CODE RULESScanning 1 file with 2 c rules.SUPPLY CHAIN RULESNo rules to run.PROGRESS━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 ┌──────────────────┐
│ 10 Code Findings │
└──────────────────┘prime.c❯❱ return-integerFound a return statement with an integer:7┆ return 1; // 不是素数❯❱ detect-chinese-charactersDetected Chinese character in the code7┆ return 1; // 不是素数❯❱ return-integerFound a return statement with an integer:12┆ return 1; // 不是素数❯❱ detect-chinese-charactersDetected Chinese character in the code12┆ return 1; // 不是素数❯❱ return-integerFound a return statement with an integer:16┆ return 0; // 是素数❯❱ detect-chinese-charactersDetected Chinese character in the code16┆ return 0; // 是素数⋮┆----------------------------------------22┆ printf("请输入一个整数:");⋮┆----------------------------------------26┆ printf("%d 是素数。\n", number);⋮┆----------------------------------------28┆ printf("%d 不是素数。\n", number);❯❱ return-integerFound a return statement with an integer:31┆ return 0;┌──────────────┐
│ Scan Summary │
└──────────────┘Ran 2 rules on 1 file: 10 findings.
admin@hpc-1:~/test_semgrep$
关于semgrep的正则表达式匹配汉字
- semgrep的正则表达式使用的是PCRE2(Perl Compatible Regular Expressions 2)
- PCRE2可以用来匹配各种字符,包括汉字
- 在 PCRE2 中,可以使用 Unicode 转义序列来表示汉字的 Unicode 范围。
- 汉字的 Unicode 范围是 \x{4E00}-\x{9FFF}。在 PCRE2 中,可以使用 \p{Script=Han} 来匹配所有汉字,包括扩展汉字。具体地,可以使用以下正则表达式来匹配汉字:
匹配基本汉字:\x{4E00}-\x{9FFF}匹配所有汉字:\p{Script=Han}