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

# はじめに

Gitlabの機能としてセキュリティツールがいくつかあるので、試したときのメモ。
[GitlabのSAST（Semgrep）を動かす時のメモ](https://qiita.com/dyamaguc/items/b61186acc2344b917309)の続きです。


# やること

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

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

# やったこと

## Gitlabのセットアップ

[こちら](https://qiita.com/dyamaguc/items/b61186acc2344b917309)を参照ください。

## 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

（中略）

spotbugs-sast:
  dependencies:
    - build
  variables:
    COMPILE: "false"
    MAVEN_REPO_PATH: ./.m2/repository
  artifacts:
    reports:
      sast: gl-sast-report.json
    paths:
      - gl-sast-report.json
  before_script:
    - rm -rf config docker webwolf webgoat-container webgoat-lessons webgoat-integration-tests
    - mkdir -p webgoat-server/.m2/
    - ln -s ./.m2/repository webgoat-server/.m2/repository

```

## パイプライン実行

### パイプラインの実行結果
![スクリーンショット 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-11-07 13.25.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329888/ceeebace-22f2-9da5-3f06-3927923e3775.png)



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

```json
{
  "version": "14.0.0",
  "vulnerabilities": [
    {
      "id": "b51bb3acbbdf07d85eb938ba4fff95cb01c4d206518b97fe5be799d1bc5cd9e3",
      "category": "sast",
      "name": "Potential CRLF Injection for logs",
      "message": "Potential CRLF Injection for logs",
      "description": "This use of org/slf4j/Logger.info(Ljava/lang/String;Ljava/lang/Object;)V might be used to include CRLF characters into log messages",
      "cve": "53fd84be709418d3e248b61776a705e2:CRLF_INJECTION_LOGS:webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java:51",
      "severity": "Low",
      "confidence": "Low",
      "scanner": {
        "id": "find_sec_bugs",
        "name": "Find Security Bugs"
      },
      "location": {
        "file": "webgoat-server/src/main/java/org/owasp/webgoat/StartWebGoat.java",
        "start_line": 51,
        "end_line": 51,
        "class": "org.owasp.webgoat.StartWebGoat",
        "method": "main"
      },
      "identifiers": [
        {
          "type": "find_sec_bugs_type",
          "name": "Find Security Bugs-CRLF_INJECTION_LOGS",
          "value": "CRLF_INJECTION_LOGS",
          "url": "https://find-sec-bugs.github.io/bugs.htm#CRLF_INJECTION_LOGS"
        },
        {
          "type": "cwe",
          "name": "CWE-117",
          "value": "117",
          "url": "https://cwe.mitre.org/data/definitions/117.html"
        }
      ]
    },
...（省略）

```


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

### 1. 変数の設定

```yaml
  variables:
    COMPILE: "false"
```

上記のように```COMPILE```を```false```に設定しています。
Spotbugsではソースコードをコンパイルするのですが、GitlabのSpotbugsだとサポートしているJavaのバージョンが8か11です（2021年10月25日現在）。
一方で、WebGoatで必要なJavaのバージョンは16（上記yamlでは15を使っていますが動作しました）となっていて、サポートされていません。
そこで、```spotbugs```のジョブではコンパイルせず、```build```ジョブの中でコンパイルした結果のファイルを使用するような設定をここでしています。

### 2.Maven local repositoryの設定

```build``` ジョブの中で ```.m2```のフォルダを```artifacts```に設定し、
そのフォルダを```MAVEN_REPO_PATH```という環境変数に設定しています。


```yaml

build:
# （中略）
  artifacts:
    paths:
      - .m2/

spotbugs-sast:
# （中略）
  variables:
    MAVEN_REPO_PATH: ./.m2/repository
```

### 3.スキャン対象外の処理

Gitlabではスキャン対象外のコードに対するレポートのフィルター機能として、```SAST_EXCLUDED_PATHS```という変数が用意されています。
これに対象外のパスを登録しておけば、スキャン結果に対してフィルターされるのですが、あくまでスキャン後のフィルターなので、スキャンさせないためには各ツールごとに処理や設定が必要になります。

例えば、リポジトリにある```docker```というフォルダに対してSpotbugsを走らせても仕方がないので、
スキャン対象外にするために、不要なフォルダは```before_script```でスキャン前に削除してしまっています（他にも方法はあると思います）。

```yaml
spotbugs-sast:
# （中略）
  before_script:
    - rm -rf config docker webwolf webgoat-container webgoat-lessons webgoat-integration-tests
    - mkdir -p webgoat-server/.m2/
    - ln -s ./.m2/repository webgoat-server/.m2/repository
```

```before_script```の１行目で削除すると、Spotbugsで探し出すスキャン対象は```WebGoat```と```webgoat-server```になります。
Spotbugsでは、```webgoat-server```フォルダの中に```.m2```フォルダを探しに行って、存在しない場合は下のようなエラーになってしまうので、
それを防ぐために、２行目、３行目でシンボリックリンクを貼っています。

```shell
[FATA] [Find Security Bugs] [2021-11-07T05:15:25Z] ▶ lstat /builds/dyamaguc-testgroup-03/WebGoat/webgoat-server/.m2/repository: no such file or directory
```


# まとめ

Gitlab.com上でGitlabが提供するSASTのテンプレートを使用してSpotbugsを実行してみました。
Semgprepに続き、Gitlabのテンプレートってちょっとクセがありました...（クセっていうほどのクセではないかもしれないですが）