GitlabのSAST（Semgrep）を動かす時のメモ

# はじめに

Gitlabの機能としてセキュリティツールがいくつかあるので、試したときのメモ

# やること

Gitlab.com環境で[SAST](https://docs.gitlab.com/ee/user/application_security/sast/index.html)のうちSemgrepを[WebGoat](https://owasp.org/www-project-webgoat/)に対してかけてみます。

# 環境
- Gitlab.com: 14.5.0-pre (2021年10月25日現在)
- [Semgrep analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep): v2.13.3
- WebGoat: https://github.com/WebGoat/WebGoat

# やったこと

## Gitlabのセットアップ

1. [Gitlab.com](https://gitlab.com/) にアクセス
1. グループを作成（手順は省略）
1. 「Settings」⇨ 「Billing」でGitlab Ultimateの無料トライアルへ切り替え（あとでSASTの結果をGitlab上で確認するため）。
1. [WebGoat](https://github.com/WebGoat/WebGoat)からプロジェクトをインポートする形で新規プロジェクト作成（手順は省略）

## gitlab-ci.ymlを作成

結果的に以下のコードで実行を確認。

```yaml

stages:
  - build
  - build-docker
  - test

variables:
  DOCKER_IMAGE: ${CI_REGISTRY}/dyamaguc-testgroup-03/webgoat:${CI_COMMIT_SHORT_SHA}
  SECURE_LOG_LEVEL: "debug"

build:
  stage: build
  image: 'maven:3.8.1-openjdk-15'
  variables:
    DOCKER_TLS_CERTDIR: ''
  services:
    - name: 'docker:20.10.6-dind'
  script:
    - mvn clean install -DskipTests=true -Dmaven.repo.local=./.m2/repository
  artifacts:
    paths:
      - docker/target
      - webgoat-server/target
      - .m2/

build-docker:
  stage: build-docker
  image: 'docker:19.03.0'
  variables:
    DOCKER_DRIVER: overlay
    DOCKER_TLS_CERTDIR: ""
  services:
    - name: 'docker:20.10.6-dind'
  dependencies:
    - build
  before_script:
    - docker info
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - cd docker
    - docker build -t ${DOCKER_IMAGE} .
    - docker push ${DOCKER_IMAGE}


include:
  - template: Security/SAST.gitlab-ci.yml

（中略）

semgrep-sast:
  dependencies:
    - build
  before_script:
    - touch trigger.py
  artifacts:
    reports:
      sast: gl-sast-report.json
    paths:
      - gl-sast-report.json

```

## パイプライン実行

### パイプラインの実行結果
![スクリーンショット 2021-10-26 17.18.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329888/bdda73b2-4db5-281d-dd14-0c55b728ce5b.png)

### semgrep-sastジョブの実行結果
ちゃんとスキャンして、Job succeededとなっています。
![スクリーンショット 2021-10-26 17.20.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329888/7aa66bad-62ac-52d6-c450-bfddb5bb7c77.png)

### gl-sast-report.jsonの内容（抜粋）
スキャンの結果がjson形式で出力されるので、試しに確認。それっぽいものが検知されていそうです。

```json
{
  "version": "14.0.0",
  "vulnerabilities": [
    {
      "id": "4cd83477f9e3439c6fd7a52bac52b66adfb039278a371bec91bae1dc6e82547f",
      "category": "sast",
      "message": "Improper Control of Generation of Code ('Code Injection')",
      "description": "Bracket object notation with user input is present, this might allow an attacker to access all properties of the object and even it's prototype, leading to possible code execution.",
      "cve": "",
      "severity": "Medium",
      "scanner": {
        "id": "semgrep",
        "name": "Semgrep"
      },
      "location": {
        "file": "webgoat-container/src/main/resources/static/js/goatApp/controller/LessonController.js",
        "start_line": 127,
        "end_line": 127
      },
      "identifiers": [
        {
          "type": "semgrep_id",
          "name": "eslint.detect-object-injection",
          "value": "eslint.detect-object-injection",
          "url": "https://semgrep.dev/r/gitlab.eslint.detect-object-injection"
        },
        {
          "type": "cwe",
          "name": "CWE-94",
          "value": "94",
          "url": "https://cwe.mitre.org/data/definitions/94.html"
        },
        {
          "type": "eslint_rule_id",
          "name": "ESLint rule ID security/detect-object-injection",
          "value": "security/detect-object-injection"
        }
      ]
    },
    ...（省略）

```

### Vulnerability Report
こんな感じでGitlab上で結果を確認できます。
![スクリーンショット 2021-10-26 17.32.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329888/2505aa68-d4c1-98cc-79b9-8062c4ed6286.png)

試しに1つクリックすると、jsonのレポートの中身がブラウザで確認できます。
レポートに対してIssueを切れるのはいいなーと思いました。
![スクリーンショット 2021-10-26 17.32.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329888/d06ffcba-d16b-1e8f-dc08-3c0c30c2996a.png)


## 実行する上での注意点

上記```gitlab-ci.yml```の中で、```before_script```の```touch trigger.py```がポイントです。
Gitlabが提供している[Semgrepのanalyzer](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep)の```main.go```の中で以下のようにコマンドが定義されています。

```main.go
	app.Commands = command.NewCommands(command.Config{
		Match:        plugin.Match,
		Analyze:      analyze,
		AnalyzeFlags: analyzeFlags(),
		AnalyzeAll:   true,
		Convert:      convert,
		Scanner:      metadata.ReportScanner,
		ScanType:     metadata.Type,
	})
```

このうち、```plugin.Match```の中身が

```plugin.go 
// Match checks if the file extension is .py
func Match(path string, info os.FileInfo) (bool, error) {
	ext := filepath.Ext(info.Name())
	if ext == ".py" || ext == ".js" || ext == ".ts" ||
		ext == ".jsx" || ext == ".tsx" || ext == ".c" || ext == ".go" {
		return true, nil
	}
	return false, nil
}
```

このように定義されていて、現時点ではリポジトリ直下にスキャン対象の拡張子を持つファイルがないと、semgrepが実行されないようです。
試しに```gitlab-ci.yml```の```before_script```を無くしてパイプラインを回した時のジョブのログが下になります。

![スクリーンショット 2021-10-28 23.18.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329888/2c1de60f-744a-041b-999b-1581cb76c755.png)

ジョブ自体はJob succeededとなるのですが、

```
[WARN] [Semgrep] [2021-10-26T08:09:02Z] ▶ No match in /builds/dyamaguc-testgroup-03/WebGoat
```

と表示されていて、実際にはSemgrepが実行されておらず、結果的にレポートの```gl-sast-report.json```が出力されていない旨のERRORが表示されています。
ジョブがSucceedになるので、まぎらわしいです...


# まとめ

Gitlab.com上でGitlabが提供するSASTのテンプレートを使用してSemgrepを実行してみました。