4
1

More than 1 year has passed since last update.

GitlabのSAST(Semgrep)を動かす時のメモ

Last updated at Posted at 2021-10-28

はじめに

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

やること

Gitlab.com環境でSASTのうちSemgrepをWebGoatに対してかけてみます。

環境

やったこと

Gitlabのセットアップ

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

gitlab-ci.ymlを作成

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


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

semgrep-sastジョブの実行結果

ちゃんとスキャンして、Job succeededとなっています。
スクリーンショット 2021-10-26 17.20.30.png

gl-sast-report.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

試しに1つクリックすると、jsonのレポートの中身がブラウザで確認できます。
レポートに対してIssueを切れるのはいいなーと思いました。
スクリーンショット 2021-10-26 17.32.33.png

実行する上での注意点

上記gitlab-ci.ymlの中で、before_scripttouch trigger.pyがポイントです。
Gitlabが提供しているSemgrepのanalyzermain.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.ymlbefore_scriptを無くしてパイプラインを回した時のジョブのログが下になります。

スクリーンショット 2021-10-28 23.18.54.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を実行してみました。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1