Semgrep
轻量级、开源的静态代码分析工具,专注于代码安全、质量检测和模式匹配分析。它通过简单直观的规则语言快速扫描代码,支持多种编程语言和框架。
https://zhuanlan.zhihu.com/p/371668441
1.元变量(Metavariables)
是用来表示代码中的动态部分的占位符。这些元变量允许 Semgrep 匹配灵活的代码结构,而不是仅仅匹配固定的字符串。
yaml
patterns:
- pattern: |
int $VAR = $VALUE;
- pattern: |
$RET_TYPE $FUNC_NAME($ARGS) { ... }
- pattern: |
if ($COND) {
$BODY
}
- pattern: |
class $CLASS extends $BASE { ... }
- pattern: |
$FUNC($ARGS)
- pattern: |
$FUNC($ARGS)
- pattern: |
$FUNC($ARGS...)匹配任何以 int 声明的变量。
int x = 42; // $VAR = x, $VALUE = 42
int y = 100; // $VAR = y, $VALUE = 100
//匹配任何函数的声明
public void myFunction(String arg) { ... } // $RET_TYPE = public void, $FUNC_NAME = myFunction, $ARGS = String arg
//匹配 if 语句,并提取条件和主体。
if (x > 0) { System.out.println("Positive"); } // $COND = x > 0, $BODY = System.out.println("Positive");
//匹配任何类的声明和继承。
class MyClass extends BaseClass { ... } // $CLASS = MyClass, $BASE = BaseClass
//匹配任何函数调用。
print("Hello, World!"); // $FUNC = print, $ARGS = "Hello, World!"
//匹配列表
myFunction(arg1, arg2, arg3); // $FUNC = myFunction, $ARGS = arg1, arg2, arg3普通元变量
- 格式:
$NAME - 用途: 表示代码中的通用部分(变量、函数名、类名等)。
元变量列表
- 格式:
$NAME... - 用途: 表示代码中的一个或多个部分(参数列表、语句块等)。
1.1元变量的约束
metavariable-regex 使用正则表达式约束元变量的值。
patterns:
- pattern: |
String $VAR = $VALUE;
metavariable-regex:
metavariable: "$VAR"
regex: "password|key|token"metavariable-pattern 使用另一个模式约束元变量的值
patterns:
- pattern: |
$FUNC($ARGS)
metavariable-pattern:
metavariable: "$FUNC"
pattern: "dangerousFunction"pattern-where*使用简单条件表达式约束元变量的取值
patterns:
- pattern: |
$VAR = $VALUE
pattern-where: |
$VAR == "password"pattern-where-python 使用 Python 脚本对元变量进行复杂约束
patterns:
- pattern: |
$VAR = $VALUE
pattern-where-python: |
$VAR.startswith("secret")1.2常见元变量的使用场景
| 元变量 | 用途 | 示例 |
|---|---|---|
$VAR | 表示变量名 | int $VAR = 42; |
$VALUE | 表示变量的值 | $VAR = $VALUE; |
$FUNC | 表示函数名 | $FUNC($ARGS); |
$ARGS | 表示函数的参数列表 | myFunction($ARGS); |
$CLASS | 表示类名 | class $CLASS extends $BASE { ... } |
$BASE | 表示基类名 | class MyClass extends $BASE { ... } |
$COND | 表示条件表达式 | if ($COND) { ... } |
$BODY | 表示代码块 | if ($COND) { $BODY } |
$RET_TYPE | 表示返回类型 | $RET_TYPE $FUNC_NAME($ARGS) { ... } |
$EXPR | 表示任意表达式 | $EXPR.methodCall(); |
2.rules(规则)
yaml
rules:
- id: csharp-method-entry-points
message: "C# 方法入口: ASP.NET/AzureFunctions/SignalR 属性方法"
severity: INFO
languages: [csharp]
patterns:
- pattern-either:
- pattern: |
[$ATTR(...)]
...
public $RET $METHOD(...) { ... }
- pattern: |
[$ATTR]
...
public $RET $METHOD(...) { ... }
- pattern: |
[$ATTR(...)]
...
public async $RET $METHOD(...) { ... }
- pattern: |
[$ATTR]
...
public async $RET $METHOD(...) { ... }
- metavariable-regex:
metavariable: "$ATTR"
regex: "(HttpGet|HttpPost|HttpPut|HttpDelete|HttpPatch|HttpHead|HttpOptions|AcceptVerbs|Route|Topic|Queue|FunctionName|HubMethodName|Scheduled.*)"
focus-metavariable: $METHODid
- 描述: 规则的唯一标识符,用于区分不同的规则。
- 用途: 在运行 Semgrep 或查看报告时,用于标识具体规则。
message
- 描述: 当规则匹配时,会显示的提示信息。
- 用途: 用于向用户提供上下文或修复建议。
severity
- 描述: 匹配结果的严重性级别。
- 用途: 标识问题的严重性,用于报告分类。
- 可能的值:
INFO: 提示信息。WARNING: 警告。ERROR: 严重问题。
languages
- 描述: 规则适用的编程语言列表。
- 用途: 限定规则适用于哪些语言。rules:
patterns
- 描述: 定义规则的核心部分,用于指定匹配模式。
- 用途: 描述代码中需要匹配的结构或内容。
- 子属性:
pattern: 单一代码模式。pattern-either: 多个模式中的任意一个。pattern-all: 多个模式需要同时匹配。pattern-not: 排除特定模式。
metavariable-regex
- 描述: 限制模式中元变量(
$VAR)的取值范围,使用正则表达式定义。 - 用途: 精确控制匹配内容,避免误报。
metavariable-pattern
- 描述: 限制元变量的匹配模式。
- 用途: 对元变量进行更复杂的约束。
fix
- 描述: 自动修复代码的建议。
- 用途: 提供匹配问题的修复方案。