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-fn
Avoid using 'scanf()'. This function, when used improperly, does not consider buffer boundaries and
can 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-integer
patterns:
- pattern-regex: return\s+\d+;
message: "Found a return statement with an integer: "
languages:
- c
severity: WARNING
recommended: true
metadata:
description: "Detects return statements with integers in the code."
category: "Code Quality"
- id: detect-chinese-characters
patterns:
- pattern-regex: \p{Script=Han}+
message: "Detected Chinese character in the code"
severity: WARNING
languages:
- c
metadata:
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 RULES
Scanning 1 file with 2 c rules.
SUPPLY CHAIN RULES
No rules to run.
PROGRESS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00
┌──────────────────┐
│ 10 Code Findings │
└──────────────────┘
prime.c
❯❱ return-integer
Found a return statement with an integer:
7┆ return 1; // 不是素数
❯❱ detect-chinese-characters
Detected Chinese character in the code
7┆ return 1; // 不是素数
❯❱ return-integer
Found a return statement with an integer:
12┆ return 1; // 不是素数
❯❱ detect-chinese-characters
Detected Chinese character in the code
12┆ return 1; // 不是素数
❯❱ return-integer
Found a return statement with an integer:
16┆ return 0; // 是素数
❯❱ detect-chinese-characters
Detected Chinese character in the code
16┆ return 0; // 是素数
⋮┆----------------------------------------
22┆ printf("请输入一个整数:");
⋮┆----------------------------------------
26┆ printf("%d 是素数。\n", number);
⋮┆----------------------------------------
28┆ printf("%d 不是素数。\n", number);
❯❱ return-integer
Found 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}