Skip to content

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: $METHOD

id

  • 描述: 规则的唯一标识符,用于区分不同的规则。
  • 用途: 在运行 Semgrep 或查看报告时,用于标识具体规则。

message

  • 描述: 当规则匹配时,会显示的提示信息。
  • 用途: 用于向用户提供上下文或修复建议。

severity

  • 描述: 匹配结果的严重性级别。
  • 用途: 标识问题的严重性,用于报告分类。
  • 可能的值:
    • INFO: 提示信息。
    • WARNING: 警告。
    • ERROR: 严重问题。

languages

  • 描述: 规则适用的编程语言列表。
  • 用途: 限定规则适用于哪些语言。rules:

patterns

  • 描述: 定义规则的核心部分,用于指定匹配模式。
  • 用途: 描述代码中需要匹配的结构或内容。
  • 子属性:
    • pattern: 单一代码模式。
    • pattern-either: 多个模式中的任意一个。
    • pattern-all: 多个模式需要同时匹配。
    • pattern-not: 排除特定模式。

metavariable-regex

  • 描述: 限制模式中元变量($VAR)的取值范围,使用正则表达式定义。
  • 用途: 精确控制匹配内容,避免误报。

metavariable-pattern

  • 描述: 限制元变量的匹配模式。
  • 用途: 对元变量进行更复杂的约束。

fix

  • 描述: 自动修复代码的建议。
  • 用途: 提供匹配问题的修复方案。
最近更新