はじめに
みなさん、こんにちは。今回は KICS というオープンソースを利用した IaC コードの静的解析 (SAST、Static Application Security Testing) についてのお話です。
前回の記事で、オープンソースの静的解析ツールの Checkov の紹介をしたときに背景なども書いたので、本記事ではこまかい前置きは抜きにしてさっそく紹介をしていきたいと思います。
KICSとは
KICS とは、Checkmarx Ltd. が開発する GO 言語ベースの静的解析ツールです。本ツールを活用することによって、Infrastructure as Code(IaC) コードの開発サイクルの早い段階で、セキュリティの脆弱性、コンプライアンスの問題、インフラストラクチャの構成ミスを検出することができるようになります。
対応ツールも豊富でTerraform、CloudFormation、AWS CDK や Kubernetes マニフェストに Helm チャート、Ansibleなど主要なツールにはおおよそ対応しており、GitLab CI/CD の IaC 用パイプラインテンプレートでも本ツールがテストステージに組み込まれていたりします。
なお、KICS という名前は Keeping Infrastructure as Code Secure の略語となっているようです。
KICSを使ってみよう
今回はローカルに KICS を実行できる環境を作るところからはじめて、簡素な Terraform コードのサンプルを用いた静的解析の手動実行、静的解析を組み込んだシンプルなパイプラインの実装まで紹介していきたいと思います。
まずは開発環境の構築から
今回は AWS CloudShell 上に開発環境を作っていきたいと思います。KICS のインストール方法としてはいろいろ用意されていますが AWS CloudShell では Docker が利用できないため、今回は Homebrew を使ってインストールしていきたいと思います。それでは、事前準備として Homebrew をインストールしてきます。
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
$ export PATH=/home/linuxbrew/.linuxbrew/bin:$PATH
$ brew --version
Homebrew 4.1.25
次に、KICS公式ドキュメントを参考に KICS をインストールします。なお、gcc
パッケージが入っていないとbrew install
でエラーになったため先にインストールしています。
$ sudo yum install -y gcc
$ brew install Checkmarx/tap/kics
$ kics version
Keeping Infrastructure as Code Secure 1.5.1
さらに、Terraform公式ドキュメント を参考に Terraform をインストールします。
$ sudo yum install -y yum-utils
$ sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo
$ sudo yum -y install terraform
$ terraform --version
Terraform v1.6.5
on linux_amd64
最後に、AWS CLI の設定をして開発環境の構築は完了です。
$ aws configure
手動でテストを実行してみよう
では簡単なサンプルを用いて を使ったテストを行っていきましょう。
Step1. テスト対象のIaCコード作成
今回は AWS上に簡単なネットワークリソースを作るだけのシンプルなコードを用意しました。
terraform {
required_version = "~> 1.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.29"
}
}
}
provider "aws" {
region = "ap-northeast-1"
default_tags {
tags = {
Project = "matt"
Environment = "dev"
Terraform = "true"
}
}
}
locals {
prefix = "matt-dev-"
}
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.2"
name = "${local.prefix}vpc"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-1c", "ap-northeast-1d"]
public_subnets = ["10.0.0.0/24", "10.0.4.0/24"]
private_subnets = ["10.0.128.0/24", "10.0.132.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
one_nat_gateway_per_az = false
}
resource "aws_security_group" "ssh" {
name = "${local.prefix}sg-ssh"
description = "Allow SSH inbound traffic"
vpc_id = module.vpc.vpc_id
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
Step2. テストの手動実行
それでは手動で KICS を実行していきましょう。v1.5.1 だと最初に assets/queries ディレクトリを作成しておかないと kics scan
コマンドがエラーになるためご留意ください。また、-p
オプションでIaCコード格納パスの指定も必須なので、こちらも指定を忘れないようにしましょう。
$ mkdir -p assets/queries
$ kics scan -p .
.0MO.
OMMMx
;NMX;
... ... ....
WMMMd cWMMM0. KMMMO ;xKWMMMMNOc. ,xXMMMMMWXkc.
WMMMd .0MMMN: KMMMO :XMMMMMMMMMMMWl xMMMMMWMMMMMMl
WMMMd lWMMMO. KMMMO xMMMMKc...'lXMk ,MMMMx .;dXx
WMMMd.0MMMX; KMMMO cMMMMd ' 'MMMMNl'
WMMMNWMMMMl KMMMO 0MMMN oMMMMMMMXkl.
WMMMMMMMMMMo KMMMO 0MMMX .ckKWMMMMMM0.
WMMMMWokMMMMk KMMMO oMMMMc . .:OMMMM0
WMMMK. dMMMM0. KMMMO KMMMMx' ,kNc :WOc. .NMMMX
WMMMd cWMMMX. KMMMO kMMMMMWXNMMMMMd .WMMMMWKO0NMMMMl
WMMMd ,NMMMN, KMMMO 'xNMMMMMMMNx, .l0WMMMMMMMWk,
xkkk: ,kkkkx okkkl ;xKXKx; ;dOKKkc
Scanning with Keeping Infrastructure as Code Secure 1.5.1
Preparing Scan Assets: Done
Executing queries: [---------------------------------------------------] 100.00%
Files scanned: 417
Parsed files: 417
Queries loaded: 0
Queries failed to execute: 0
------------------------------------
Results Summary:
HIGH: 0
MEDIUM: 0
LOW: 0
INFO: 0
TOTAL: 0
Scan duration: 5m51.785647777s
A new version 'v1.7.11' of KICS is available, please consider updating
、、、本当は「セキュリティグループで不特定多数からの SSH を許可しないで!」と結果が返ってくることが期待だったのですがどうも機嫌がよくなかったようですね^^;
次のパイプライン経由での実行がメインなので一旦ローカルでの実行はあきらめて次に行ってみましょう。以上、ローカル環境で KICS の静的解析を実行する方法のご紹介でした。
CI/CDパイプラインに組み込んでみよう
次はもう一歩進んで、ソースコードの更新をトリガーに自動でテストを実行する CI/CD パイプラインを構築し、実際に動かすところまで行ってみたいと思います。今回の例では CI/CD パイプラインとして GitLab CI/CD を使っていきます。
Step1. パイプライン定義の作成
まずは GitLab CI/CD パイプラインの定義ファイル .gitlab-ci.yml
を作成していきましょう。今回の例では簡略化のためにテストステージだけを定義し、GitLab の画面からテスト結果を確認しやすいように JUnit 形式で出力しています。
stages:
- test
kics:
stage: test
allow_failure: true
image:
name: checkmarx/kics:latest
entrypoint: [""]
rules:
- if: $SAST_DISABLED
when: never
- if: $CI_COMMIT_BRANCH
exists:
- '**/*.yml'
- '**/*.yaml'
- '**/*.json'
- '**/*.template'
- '**/*.tf'
- '**/serverless.yml'
- '**/serverless.yaml'
script:
- kics scan --no-progress -p ${PWD} -o ${PWD} --report-formats junit --output-name kics-results
artifacts:
reports:
junit: "junit-kics-results.xml"
paths:
- junit-kics-results.xml
Step2. パイプラインの動作確認
先ほど作成したパイプライン定義 .gitlab-ci.yml
をリモートリポジトリへ push すると自動的にパイプラインが実行されますので、GitLabの画面からテスト結果を確認してみましょう。
出力例のように Build > Pipelines > 対象パイプライン > Testタブ と遷移させることでテスト結果のサマリーを確認することができます。
また、テストのサマリー画面にてジョブ名(例ではkics)をクリックすることで、テスト結果の一覧を表示させることができます。
また、この一覧画面で「View detauls」をクリックすることでより詳細な情報を得ることもできます。出力例では、セキュリティグループの定義に対する指摘で「SSH は公開するべきではないよ」と期待通りの指摘を得ることができました。
ちなみに、本来はパイプラインにビルドステージやデプロイステージを持たせたりすると思いますが、ひとまずこれでソースコードのプッシュを契機にテストを走らせる、という最低限の流れを自動化することができました。
終わりに
ということで、KICS はいかがだったでしょうか?検出された問題の重大度が出力結果一覧からパッとわからない点は正直やや微妙かもしれませんが、とても簡単に静的解析を導入することができたかと思います。
IaC はしているけど静的解析は何もしてないよ、という方はデプロイ前に致命的なセキュリティ上の問題が含まれていることに気づくことができるように、ぜひ今回紹介する KICS のような静的解析ツールの活用を検討いただくといいのかなと思います。
以上、IaC コードの静的解析を実現する「KICS」のご紹介でした。
AWS は、米国その他の諸国における Amazon.com, Inc. またはその関連会社の商標です。
Terraform は、HashiCorp, Inc. の米国およびその他の国における商標または登録商標です。
その他、記載されている会社名および商品・製品・サービス名は、各社の商標または登録商標です。