Snyk脆弱性スキャンツールの使用

紹介

Snykは、開発者向けセキュリティプラットフォームとして設計され、柔軟性を考慮しています。その主な目標は、アプリケーションのソースコード、サードパーティの依存関係、コンテナイメージ、およびインフラストラクチャの構成ファイル(例:Kubernetes、Terraformなど)における脆弱性を検出して修正することです。

Snykは、次の4つのコンポーネントに分かれています:

  1. Snyk Code – アプリケーションのソースコードにある脆弱性を見つけて修正するのに役立ちます。
  2. Snyk Open Source – アプリケーションが依存している任意のサードパーティライブラリや依存関係の脆弱性を見つけて修正するのに役立ちます。
  3. Snyk Container – クラスターで使用されているコンテナイメージやKubernetesワークロードにある脆弱性を見つけて修正するのに役立ちます。
  4. Snyk Infrastructure as Code – Kubernetesマニフェストのミス構成を見つけて修正するのに役立ちます(Terraform、CloudFormation、およびAzureもサポートされています)。

Snykはさまざまな方法で実行できます:

  • コマンドラインインターフェースを使用してSnyk CLIを介して。これはスクリプトやCI/CDパイプラインを含むさまざまな自動化内で実行するための推奨方法です。
  • ブラウザーでSnyk Web UIを使用します。 Snykはクラウドベースのプラットフォームも提供しており、スキャンレポートを調査したり、ヒントを受け取ったり、報告された問題を修正するための必要なアクションを取ったりすることができます。また、GitHubリポジトリを接続して、Webインターフェースからスキャン/監査を実行することもできます。
  • IDEプラグインを介して。これにより、お気に入りのIDE(例:Visual Studio Code)を使用して開発中に問題を早期に見つけることができます。
  • プログラムを使用して、Snyk API経由で。 Snyk APIは有料プランの顧客に利用可能であり、Snykとプログラム的に統合することができます。

Snykは無料ですか?

はい、ツールは無料ですが、Snyk APIやWeb UIの一部の高度な機能(高度なレポーティングなど)は除外されます。また、月あたりのテスト回数に制限もあります。

詳細については、価格プランを参照してください。

Snykはオープンソースですか?

はい、ツールとSnyk CLIは確かにオープンソースです。各コンポーネントの実装の詳細については、Snyk GitHubホームページを訪問してください。クラウドポータルやREST APIの実装など、すべての有料機能はオープンソースではありません。

Snykが使用しているもう一つの重要な概念はTargets(ターゲット)Projects(プロジェクト)です。

Targetsは、Snykが統合、CLI、UI、またはAPIを介してスキャンした外部リソースを表します。例えば、SCMリポジトリ、Kubernetesワークロードなどがあります。

一方、Projectsは、特定のTargetでSnykがスキャンする項目を定義します。プロジェクトには以下が含まれます:

  • A scannable item external to Snyk.
  • スキャンを実行する方法を定義する構成。

Snykのコアコンセプトについてはこちらをご覧ください。

このガイドでは、Snyk CLIを使用して、Kubernetesアプリケーションのサプライチェーン(コンテナイメージ、Kubernetes YAMLマニフェスト)のリスク分析を行います。その後、適切な対応策を学びます。最後に、開発の初期段階で脆弱性をスキャンするために、SnykをCI/CDパイプラインに統合する方法を学びます。

目次

前提条件

このガイドのすべてのステップを完了するには、次のものが必要です:

  1. A working DOKS cluster running Kubernetes version >=1.21 that you have access to. For additional instructions on configuring a DigitalOcean Kubernetes cluster, see: How to Set Up a DigitalOcean Managed Kubernetes Cluster (DOKS).
  2. A DigitalOcean Docker Registry. A free plan is enough to complete this tutorial. Also, make sure it is integrated with your DOKS cluster as explained here.
  3. Kubernetesとの対話のためのkubectl CLI。次の手順に従って、kubectldoctlでクラスタに接続します。
  4. Snykの脆弱性スキャナーとの対話のためのSnyk CLI。
  5. A free Snyk cloud account account used to periodically publish scan results for your Kubernetes cluster to a nice dashboard. Also, the Snyk web interface helps you with investigations and risk analysis. Please follow How to Create a Snyk Account documentation page.
  6. A Slack workspace you own, and a dedicated Slack app to get notified of vulnerability scan issues reported by Snyk.

ステップ1 – Snyk CLIの理解

手動で脆弱性をスキャンするには、snykコマンドラインインターフェースを使用できます。 Snyk CLIは、さまざまなスクリプトや自動化で使用するように設計されています。実用例としては、Tekton、Jenkins、GitHub Workflowsなどのさまざまなツールを使用して実装されたCI/CDパイプラインがあります。

Snyk CLIが呼び出されると、すぐにスキャンプロセスが開始され、特定の形式で問題が報告されます。デフォルトでは、標準出力またはコンソールを使用して要約表が出力されます。 Snykは、JSON、HTML、SARIFなどの他の形式でもレポートを生成できます。

スキャン結果を後で格納して可視化するために、--reportフラグを使用してSnyk Cloud Portal(またはWeb UI)に結果をプッシュすることもできます。

注意:
スキャン結果をSnykクラウドポータルに送信する必要はありません。 Snykポータルを使用する大きな利点は、可視性です。Kubernetesサプライチェーンがどれだけ影響を受けているかを確認できる素敵なダッシュボードにアクセスできます。また、調査や修復のヒントを提供することで、長期的に役立ちます。

Snyk CLIは、いくつかのサブコマンドに分かれています。各サブコマンドは特定の機能に専用です。

次に進む前に、SnykのウェブUIを使用して無料アカウントを作成してください。また、いくつかのコマンド/サブコマンドが機能するためには、Snyk CLIがクラウドアカウントで認証されている必要があります(例:snyk code test)。

A few examples to try with Snyk CLI:

  1. オープンソーススキャン:
# 現在のディレクトリからプロジェクトコードをスキャンします
snyk test
# プロジェクトディレクトリから特定のパスをスキャンします(`<>`プレースホルダーを適切に置き換えてください)
snyk test <path/to/dir>
  1. コードスキャン:
# 現在のディレクトリからプロジェクトコードをスキャンします
snyk code test

# プロジェクトディレクトリから特定のパスをスキャンします(`<>` のプレースホルダーを適切に置き換えてください)
snyk code test <path/to/dir>
  1. イメージのスキャン:
# まずdebian Dockerイメージを引っ張ってからスキャンします
snyk container debian

# Dockerfileを提供してスキャナーにさらなるコンテキストを提供します(`<>` のプレースホルダーを適切に置き換えてください)
snyk container debian --file=<path/to/dockerfile>
  1. インフラストラクチャーのコードスキャン:
# 現在のディレクトリからプロジェクトコードをスキャンします
snyk iac test

# プロジェクトディレクトリから特定のパスをスキャンします(`<>` のプレースホルダーを適切に置き換えてください)
snyk iac test <path/to/dir>

# Kustomizeベースのプロジェクトをスキャンします(まず最終テンプレートをレンダリングし、次にスキャナーに渡します)
kustomize build > kubernetes.yaml
snyk iac test kubernetes.yaml

Snyk CLIは、利用可能なすべてのオプションに関するヘルプページを提供します。以下のコマンドを使用してメインのヘルプページを印刷できます:

snyk --help

出力は次のようになります:

Output
CLI commands help Snyk CLI scans and monitors your projects for security vulnerabilities and license issues. For more information visit the Snyk website https://snyk.io For details see the CLI documentation https://docs.snyk.io/features/snyk-cli How to get started 1. Authenticate by running snyk auth 2. Test your local project with snyk test 3. Get alerted for new vulnerabilities with snyk monitor Available commands To learn more about each Snyk CLI command, use the --help option, for example, snyk auth --help or snyk container --help snyk auth Authenticate Snyk CLI with a Snyk account. snyk test Test a project for open source vulnerabilities and license issues.

各Snyk CLIコマンド(またはサブコマンド)には、関連するヘルプページもあります。これは、snyk [command] --help を使用してアクセスできます。

さらに多くの例については、公式のsnyk CLIドキュメントページを参照してください。

ステップ2 – Snyk Web UIの理解

Snykアカウントにサインアップし、Snykに認証してログインした後、Web UIがダッシュボードで開き、セットアップ手順を案内するウィザードが表示されます:

  • Snykで監視したいコードの場所を特定します。
  • Snykがスキャンするコード内のプロジェクトを定義します。
  • 関連するプロジェクトをスキャンするためにSnykを接続します。
  • Snykスキャンの結果を確認します。

次の機能がWeb UIを介して利用できます:

公式のドキュメントページをご覧いただき、Snyk Web UIについて詳しくお知らせください。

Snyk深刻度レベルの理解

各スキャンで、snykは潜在的なセキュリティリスクを確認し、それぞれがシステムにどのように影響するかを検証します。脆弱性にはリスクを示す深刻度レベルが適用されます。

深刻度レベルには以下の値があります:

  • : アプリケーションが一部のデータを公開し、他の脆弱性と組み合わせてアプリケーションを攻撃するために使用できる可能性があります。
  • : 一部の条件下で、攻撃者がアプリケーションの機密データにアクセスすることができる可能性があります。
  • : 攻撃者がアプリケーションの機密データにアクセスする可能性があります。
  • 致命的: 攻撃者がアプリケーションの機密データにアクセスし、コードを実行する可能性があります。

Common Vulnerability Scoring System (CVSS) は、脆弱性の深刻度レベルを決定します。 Snyk は CVSS フレームワークバージョン 3.1 を使用して、脆弱性の特性と深刻度を伝えます。

以下の表は、各深刻度レベルのマッピングを示しています。

Severity level CVSS score
Low 0.0 – 3.9
Medium 4.0 – 6.9
High 7.0 – 8.9
Critical 9.0 – 10.10

このガイドでは、使用されている例の CI/CD パイプラインで medium レベルの閾値がデフォルト値として使用されています。通常、高およびクリティカルな問題を最初に評価したいと考える場合がありますが、中程度のレベルも注意が必要です。セキュリティと一般的なルールとして、通常は非常に厳格であることが望ましいです。

詳細については、公式ドキュメントページをご覧ください。

報告されたセキュリティの問題に対する支援された修復

Snyk ウェブ UI が提供する別の便利な機能は、セキュリティの問題の修復支援です。これは、snyk スキャナーによって見つかった各セキュリティの問題を修正する方法に関する推奨事項を受け取ることを意味します。これは非常に重要です。なぜなら、このプロセスを簡略化し、各報告されたセキュリティの問題を修正するために実行する必要がある各イテレーションに対してループを閉じるからです。

以下の画像は、このプロセスをよりよく説明しています。

各報告された問題ごとに、解決支援を受けるためのボタンがあります。

各報告された問題について、メインの手順は同じです。つまり、詳細を表示するボタンをクリックし、提案された手順に従って修正を適用します。

ステップ3 – CI/CD パイプラインで Kubernetes 構成の脆弱性をスキャンするための Snyk の使用

CI/CD パイプラインにセキュリティコンプライアンススキャンツールを埋め込むことで、どのようにして本番環境での不快な状況を回避し、利益を得ることができますか?

すべては、ソフトウェア開発が始まる基礎レベルで始まります。一般的に、各段階に専用の環境を使用することが望ましいです。したがって、開発の初期段階では、アプリケーションコードが非常に頻繁に変更されるため、専用の開発環境(通常は下位環境と呼ばれます)を使用する必要があります。次に、QA環境でアプリケーションがより洗練されていく中で、QAチームが手動および/または自動テストを実行します。次に、アプリケーションがQAチームの承認を受けると、ステージングなどの上位環境に昇格し、最終的に本番環境に移行します。アプリケーションが1つの環境から別の環境に昇格するプロセスでは、常に専用のパイプラインが実行され、アプリケーションアーティファクトを継続的にスキャンし、深刻度レベルをチェックします。深刻度レベルが特定の閾値を満たさない場合、パイプラインはすぐに失敗し、アプリケーションアーティファクトの本番環境への昇格が早い段階で停止します。

したがって、セキュリティスキャンツール(例:snyk)は、開発の初期段階から本番環境に不要なアーティファクトが入るのを防ぐゲートキーパーとして機能します。同様に、上位環境のパイプラインではsnykを使用して、最終的な本番段階へのアプリケーションアーティファクトの入出を許可または禁止します。

GitHubアクションCI/CDワークフローの実装

このステップでは、GitHubワークフローを使用した統合脆弱性スキャンを備えたサンプルCI/CDパイプラインの作成とテスト方法を学びます。GitHub ActionsをDigitalOcean Kubernetesと組み合わせて使用する基本を学ぶには、この tutorial を参照してください。

次のセクションで提供されるパイプラインは、DigitalOceanの kubernetes-sample-apps リポジトリから game-2048-example アプリケーションをビルドしてデプロイします。

大まかな概要では、kubernetes-sample-apps リポジトリで提供される game-2048 CI/CD ワークフロー は、次のステージで構成されています:

  1. アプリケーションのビルドおよびテストステージ – 主要なアプリケーションアーティファクトのビルドと自動テストを実行します。
  2. Snykアプリケーションイメージスキャンステージ – 既知の脆弱性を持つアプリケーションのDockerイメージをスキャンします。これはゲートとして機能し、最終的なパイプラインの状態(合格/不合格)はこのステップに依存します。失敗した場合、Slack通知が送信されます。
  3. アプリケーションイメージのビルドとプッシュステージ – 最新のgitコミットSHAを使用してアプリケーションイメージをビルドしてタグ付けします。次に、イメージをDOCRにプッシュします。
  4. Snykのインフラストラクチャー・アズ・コード(IAC)スキャンステージ – アプリケーションに関連するKubernetes YAMLマニフェスト内の既知の脆弱性をスキャンします。ゲートとして機能し、最終的なパイプラインの状態(合格/不合格)はこのステップに依存します。失敗した場合、Slack通知も送信されます。
  5. アプリケーションデプロイメントステージ – アプリケーションをKubernetes(DOKS)にデプロイします。

以下の図は、パイプラインの各ジョブとアクション付きの関連するステップを示しています(関連する構成のみ表示されます):

メモ:

  • kustomizeベースのプロジェクトの場合、すべてをキャプチャしてスキャンするために最終マニフェストをレンダリングするのが最適です(リモートリソースを含む)。一方で、どのKubernetesリソースをパッチする必要があるかを特定するのは難しい場合があります。これは、結果のマニフェストファイルが適用されるすべてのリソースで構成されているためです。これがkustomizeの動作方法です-それは、各オーバーレイからすべての構成フラグメントを収集し、それらをベースに適用して最終的な複合物を構築します。
  • Snykに、kustomize構成を保持しているフォルダ全体をスキャンするよう指示することもできます。この方法では、リポジトリ内の修正が必要なリソースを特定するのが簡単です。 kustomizeが使用するリモートリソースは、上流で修正する必要があります。また、kustomizeによって生成されたKubernetesのシークレットとConfigMapsはキャプチャされません。

特定のセキュリティコンプライアンスレベルが満たされない場合にパイプラインを失敗させる方法はありますか?

Snyk CLIは、この目的のために--severity-thresholdというフラグを提供します。このフラグは、各スキャン後に計算された全体の深刻度レベルと相関します。Snykの場合、深刻度レベルは次の値のいずれかを取ります:lowmediumhigh、またはcritical。深刻度レベルの値に基づいて、パイプラインを失敗または成功させ、条件が満たされていない場合はアプリケーションの展開を停止できます。

以下の図は、このガイドで使用される例のCI/CDパイプラインのフローを示しています:

このガイドで提供されるsnyk CI/CD GitHubワークフローを作成してテストする手順は次のとおりです:

  1. kubernetes-sample-apps GitHubリポジトリをフォークします。
  2. 以下は、GitHubの暗号化されたシークレットkubernetes-sample-appsのコピー用に作成してください(設定タブ -> シークレット -> アクション):
    • DIGITALOCEAN_ACCESS_TOKEN – DigitalOceanアカウントトークンを保持します。
    • DOCKER_REGISTRY – エンドポイントを含むDigitalOceanのDockerレジストリ名を保持します(例:registry.digitalocean.com/sample-apps)。
    • DOKS_CLUSTER – DOKSクラスター名を保持します。次のコマンドを実行してDOKSクラスター名を取得できます:doctl k8s cluster list --no-header --format Name
    • SNYK_TOKEN – SnykユーザーアカウントIDを保持します – 実行:snyk config get apiでIDを取得できます。それが機能しない場合は、ユーザーアカウント設定ページからトークンを取得できます。
    • SLACK_WEBHOOK_URL – Snykスキャン通知に使用されるSlackの着信Webhook URLを保持します。
  3. フォークされたリポジトリのアクションタブに移動し、Game 2048 Snyk CI/CD Exampleワークフローを選択します:
  4. ワークフローを実行ボタンをクリックし、デフォルトの値をそのままにします:

A new entry should appear in the below list after clicking the Run Workflow green button. Select the running workflow to observe the pipeline progress:

パイプラインはsnyk-container-security-checkジョブが実行されるときに失敗し、停止します。これは、ワークフローの入力で使用されるデフォルトの深刻度レベル値が期待に満たないためです。また、ワークフローの実行に関する詳細を含むSlack通知も受信するはずです:

次の手順では、snykスキャンレポートを調査して問題を修正し、深刻度レベルを下げてパイプラインを通過させる方法を学びます。

ステップ4 – Snykスキャンの結果を調査して報告された問題を修正する

深刻度の閾値が満たされない場合、game-2048 GitHubワークフローは失敗し、追加の詳細が含まれたSlack通知が送信されます。また、GitHubにセキュリティレポートが公開され、プロジェクトリポジトリのセキュリティタブからアクセスできます。

game-2048ワークフローは、2つのセキュリティチェックを実行します。

  1. コンテナイメージのセキュリティチェック – この目的には、snyk-container-security-checkジョブが使用されます。使用されている等価なsnykコマンドは次のとおりです – snyk container test <GAME-2048-IMAGE>:<TAG> --file=/path/to/game-2048/Dockerfile
  2. Kubernetesマニフェストのミス構成チェック – この目的には、snyk-iac-security-checkジョブが使用されます。使用されている等価なsnykコマンドは次のとおりです – snyk iac test /path/to/project/kubernetes/manifests

したがって、深刻度レベルを下げてワークフローをパスするには:

  1. snyk-container-security-checkジョブによって報告された問題を調査して修正すること。
  2. snyk-iac-security-checkジョブによって報告された問題を調査して修正すること。

次に、それぞれの対処方法を学びます。

コンテナイメージの脆弱性の調査と修正

このガイドで使用されるサンプルパイプラインは、game-2048コンテナイメージおよび関連するDockerfileに対してセキュリティチェックを実行します。snyk-container-security-checkジョブを介して行います。

snyk-container-security-checkジョブは、以下の手順を実行します。

  1. ローカルでgame-2048アプリケーションのDockerイメージをビルドします。この手順は、docker-build-push GitHubアクションを使用して実装されます。
  2. アプリケーションのコンテナイメージおよびDockerfileに対してSnykのセキュリティチェックを実行します。この手順は、snyk container testコマンドを使用して実装されます。スキャン結果はGitHub SARIF形式でエクスポートされます。セキュリティレベルのしきい値は、手動でワークフローがトリガーされた場合はsnyk_fail_threshold入力パラメータに設定され、ワークフローが自動的に実行された場合はSNYK_FAIL_THRESHOLD環境変数に設定されます。
  3. スキャン結果(SARIF形式)は、アプリケーションリポジトリのセキュリティタブに公開されます。このステップは、codeql GitHubアクションを使用して実装されています。

以下のスニペットは、snyk-container-security-checkジョブのメインロジックを示しています:

- name: Build App Image for Snyk container scanning
  uses: docker/build-push-action@v3
  with:
    context: ${{ env.PROJECT_DIR }}
    push: false
    tags: "${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}"

- name: Check application container vulnerabilities
  run: |
    snyk container test "${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}" \
      --file=Dockerfile \
      --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \
      --target-name=${{ env.PROJECT_NAME }} \
      --target-reference=${{ env.ENVIRONMENT }} \
      --sarif --sarif-file-output=snyk-container-scan.sarif
  env:
    SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
  working-directory: ${{ env.PROJECT_DIR }}

- name: Upload Snyk report SARIF file
  if: ${{ always() }}
  uses: github/codeql-action/upload-sarif@v2
  with:
    sarif_file: ${{ env.PROJECT_DIR }}/snyk-container-scan.sarif
    category: snyk-container-scan

–file=Dockerfile \

–severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \

–target-name=${{ env.PROJECT_NAME }} \

–target-reference=${{ env.ENVIRONMENT }} \

–sarif –sarif-file-output=snyk-container-scan.sarif

報告された問題を修正するには、まずkubernetes-sample-appsリポジトリのフォークのセキュリティタブを確認する必要があります:

FROM node:18.6.0-slim AS builder
WORKDIR /usr/src/app
COPY . .
RUN npm install --include=dev
この場合、ベースのDockerイメージに対する脆弱性の束が表示されます。各項目を展開して詳細を確認してください:
調査を完了し、Snykが提供する推奨事項を確認するには、メインワークフローからsnyk-container-security-checkジョブの出力を検査する必要があります:
注意:Snyk container testは結果をSARIF形式でエクスポートする機能を提供していますが、レポートをSnykクラウドポータルにアップロードする方法を知りません。一方、snyk container monitorは結果をSnykクラウドポータルにアップロードする機能を提供しますが、SARIFをエクスポートすることはできません。したがって、このガイドではSARIFエクスポート機能を備えたsnyk container testを使用しています。残念ながら、いくつかの推奨事項はSARIF出力には含まれていません。そのため、推奨事項を確認するにはジョブコンソールの出力も確認する必要があります。
snyk-container-security-check ジョブの出力によると、Snyk はベースイメージのバージョンを node:16-slim から node:18.6.0-slim に更新することを推奨しています。この変更により、高リスクの問題が解消され、その他の報告された脆弱性の数も 70 から 44 に減少します。これはほぼ 50% の大幅な削減です!
ENV NODE_ENV=development
RUN npm run build

FROM node:18.6.0-slim
RUN npm install http-server -g
RUN mkdir /public
WORKDIR /public
COPY --from=builder /usr/src/app/dist/ ./
EXPOSE 8080
USER 1000
CMD ["http-server"]

これで、フォークした game-2048 アプリケーションの Dockerfile を開き、FROM ディレクティブを新しいバージョン (node:18.6.0-slim) を指すように変更します:

#

# ビルドモードは NODE_ENV 環境変数(development または production)を使用して設定できます

# プロジェクトの package.json と webpack.config.js を参照してください

#

最後に、変更を GitHub リポジトリにコミットし、再度ワークフローをトリガーします(デフォルト値のままで)。今度は snyk-container-security-check ジョブがパスするはずです:

プロジェクトのセキュリティタブに移動すると、報告された問題はありません。

将来、ベースイメージの脆弱性を削減するための方法は何ですか?

  1. 最良のアプローチは、最小のフットプリントを持つベースイメージを使用することです – ベースイメージに含まれるバイナリや依存関係が少ないほど良いです。もう一つの良い実践は、このガイドの定期的にプロジェクトを監視するセクションで説明されているように、プロジェクトを継続的に監視することです。
  2. パイプラインがまだ失敗していることに気付くでしょうが、今回はsnyk-iac-security-checkフェーズで失敗しています。これは、アプリケーションをデプロイするために使用されるKubernetesマニフェストにセキュリティの問題があるためです。次のセクションでは、この状況を調査し、報告された問題を修正するためにSnykのセキュリティ推奨事項を適用する方法を学びます。

Kubernetesマニフェストの脆弱性の調査と修正

- name: Check for Kubernetes manifests vulnerabilities
  run: |
    snyk iac test \
      --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \
      --target-name=${{ env.PROJECT_NAME }} \
      --target-reference=${{ env.ENVIRONMENT }} \
      --sarif --sarif-file-output=snyk-iac-scan.sarif \
      --report
  env:
    SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
  working-directory: ${{ env.PROJECT_DIR }}

- name: Upload Snyk IAC SARIF file
  if: ${{ always() }}
  uses: github/codeql-action/upload-sarif@v2
  with:
    sarif_file: ${{ env.PROJECT_DIR }}/snyk-iac-scan.sarif
    category: snyk-iac-scan

パイプラインはまだ失敗し、snyk-iac-security-checkジョブで停止しています。これは、ワークフローの入力で使用されるデフォルトの深刻度レベル値であるmediumが、プロジェクトのセキュリティ要件を満たさないためです。

  1. snyk-iac-security-checkジョブは、Kubernetesマニフェストの脆弱性(または誤構成)をチェックし、次の手順を実行します:
  2. Snykセキュリティチェックは、game-2048-exampleプロジェクトディレクトリからKubernetesマニフェストをチェックします。このステップは、snyk iac testコマンドを使用して実装されます。スキャン結果は、GitHub SARIF形式でエクスポートされます。セキュリティレベルの閾値は、–severity-threshold引数で制御されます。これは、ワークフローが手動でトリガーされる場合はsnyk_fail_threshold入力パラメータに設定され、ワークフローが自動的に実行される場合はSNYK_FAIL_THRESHOLD環境変数に設定されます。最後に、–report引数も使用され、スキャン結果をSnykクラウドポータルに送信します。

スキャン結果(SARIF形式)は、アプリケーションリポジトリのセキュリティタブに公開されます。このステップは、codeqlGitHubアクションを使用して実装されます。

snyk-iac-security-checkジョブの各ステップの実際の実装を以下に示します:

–severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \

–target-name=${{ env.PROJECT_NAME }} \

–target-reference=${{ env.ENVIRONMENT }} \

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: game-2048
spec:
  replicas: 1
  selector:
    matchLabels:
      app: game-2048
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: game-2048
    spec:
      containers:
        - name: backend
          --sarif --sarif-file-output=snyk-iac-scan.sarif \
          image: registry.digitalocean.com/sample-apps/2048-game:latest
          ports:
            - name: http
              containerPort: 8080
          resources:
            requests:
              cpu: 100m
              memory: 50Mi
            limits:
              cpu: 200m
              memory: 100Mi
          securityContext:
            readOnlyRootFilesystem: true
            runAsNonRoot: true
            allowPrivilegeEscalation: false
            capabilities:
              drop:
                - all

報告された問題を修正するには、2つのオプションがあります:

  • Snykクラウドポータルを使用し、詳細を確認するためにgame-2048プロジェクトにアクセスします:
  • ゲーム2048アプリのリポジトリのセキュリティタブを使用して詳細を確認します:
  • いずれの場合も、報告された問題を修正する方法に関する推奨事項を受け取ります。
  • このガイドでは、報告されたセキュリティの問題を調査するためにSnykクラウドポータルを使用します。まず、プロジェクトリストからgame-2048-exampleエントリをクリックし、次にkustomize/resources/deployment.yamlファイルを選択します:

次に、左側のSeverityサブメニューでmediumレベルの問題のみを表示するために、Mediumチェックボックスをオンにします:

その後、各報告された問題カードを検査し、詳細を確認できます。 Container is running without root user controlカードのShow more detailsボタンをクリックして、現在の問題に関する詳細情報と修正方法に関する重要なヒントを受け取ります:

A few final checks can be performed as well on the Kubernetes side to verify if the reported issues were fixed:

  1. 各カードからのすべての情報を収集した後、リポジトリのdeployment.yamlファイル(game-2048-example/kustomize/resourcesサブフォルダーにある)を編集できます。 修正はすでに適用されていますが、ファイルの最後の行をコメント解除する必要があります。 最終のdeployment.yamlファイルは以下のようになります:
  2. readOnlyRootFilesystem – コンテナイメージを読み取り専用で実行します(コンテナ内でkubectl execによるファイルの変更ができません)。

allowPrivilegeEscalationallowPrivilegeEscalationfalseに設定することで、コンテナの子プロセスが親よりも多くの特権を取得することを防ぎます。

capabilities.drop – コンテナをより安全にするために、実行に必要な最小限の特権を提供する必要があります。実際には、デフォルトですべてを削除し、必要な特権を段階的に追加します。こちらでコンテナの特権について詳しく学ぶことができます。

最後に、deployment.yamlファイルの変更をコミットし、メインブランチにプッシュします。手動でワークフローをトリガーした後、正常に完了するはずです。

また、snykスキャンジョブから緑色のSlack通知を受け取るはずです。Snykポータルリンクに移動し、最近修正した問題が解消されているかどうかを確認してください – 中程度のレベルの問題は報告されていないはずです。

ゲーム2048の展開が読み取り専用(不変)のファイルシステムを持っているかどうかを確認するには、ゲーム2048アプリケーションで使用されるindex.htmlファイルに書き込んでみてください:

kubectl exec -it deployment/game-2048 -n game-2048 -- /bin/bash -c "echo > /public/index.html"

出力は次のようになります:

出力
/bin/bash: /public/index.html: 読み取り専用 ファイル システム コマンド終了 コード 1 で終了しました

ゲーム2048の展開が読み取り専用(不変)のファイルシステムを持っているかどうかを確認するには、ゲーム2048アプリケーションで使用されるindex.htmlファイルに書き込んでみてください:

出力は次のようになります:

snyk-container-security-check:
    runs-on: ubuntu-latest
    needs: build-and-test-application

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      ...

      - name: Check application container vulnerabilities
        run: |
          snyk container test "${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}" \
            --file=${{ env.PROJECT_DIR }}/Dockerfile \
            --severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \
            --target-name=${{ env.PROJECT_NAME }} \
            --target-reference=${{ env.ENVIRONMENT }} \
            --sarif-file-output=snyk-container-scan.sarif
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

      - name: Monitor the application container using Snyk
        run: |
          snyk container monitor "${{ secrets.DOCKER_REGISTRY }}/${{ env.PROJECT_NAME }}:${{ github.sha }}" \
            --file=${{ env.PROJECT_DIR }}/Dockerfile
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
      
      ...

コンテナがルート以外のユーザーとして実行されているかを確認します(ゼロ以外の整数が出力されるはずです – 例:1000):

kubectl exec -it deployment/game-2048 -n game-2048 -- id -u

コンテナがルート以外のユーザーとして実行されているかを確認します(ゼロ以外の整数が出力されるはずです – 例:1000):

すべてのチェックがパスした場合、必要なセキュリティ推奨事項が正常に適用されています。

build-and-test-application:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: npm install, build, and test
        run: |
          npm install
          npm run build --if-present
          npm test
        working-directory: ${{ env.PROJECT_DIR }}

      - name: Snyk code test and monitoring
        run: |
          snyk test ${{ env.PROJECT_DIR }}
          snyk monitor ${{ env.PROJECT_DIR }}
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

定期的にプロジェクトをモニタリングします

これまでに実装した脆弱性スキャンの自動化は良い出発点ですが、完璧ではありません。なぜですか?

現在のアプローチの1つの問題は、すでに環境にデプロイしたアセットに新しい問題が報告されるたびに、そのことを知らないということです。言い換えると、セキュリティリスクを評価し、CI/CDの自動化が実行された特定の時点で問題を修正するための措置を講じました。

しかし、その間に新しい問題が報告され、アプリケーションが再び脆弱になった場合はどうなりますか? Snykはモニタリング機能を通じてこの状況を克服するのに役立ちます。 Snykのモニタリング機能は、絶えず開示される新しい脆弱性に対処するのに役立ちます。 Snyk Slack統合と組み合わせると(ステップ6 – Slack通知の有効化で説明)、本番環境に影響を与える可能性がある新たに開示された問題を即座に修正するための行動を取ることができます。

この機能を活用するには、CI/CDパイプラインの展開手順の前にsnyk monitorコマンドを使用するだけです。 構文はsnyk testコマンドと非常に似ています(snyk CLIの素晴らしい点の1つは、統一性を考慮して設計されていることです)。 snyk monitorコマンドは、スナップショットをSnykクラウドポータルに送信し、そこからプロジェクトの新たに開示された脆弱性について通知を受け取ります。

A more efficient approach is where you integrate vulnerability scan tools directly in your favorite IDE (or Integrated Development Environment). This way, you can detect and fix security issues ahead of time in the software development cycle.

GitHubワークフローの自動化に関して、脆弱性のテストの後にアプリケーションコンテナをsnyk-container-security-checkジョブで監視できます。 このガイドで使用されているパイプラインの実用的な実装を以下に示します(一部のステップは明確化のために省略されています)。

  1. –file=${{ env.PROJECT_DIR }}/Dockerfile \
  2. –severity-threshold=${{ github.event.inputs.snyk_fail_threshold || env.SNYK_FAIL_THRESHOLD }} \
  3. –target-name=${{ env.PROJECT_NAME }} \
  4. –target-reference=${{ env.ENVIRONMENT }} \

–sarif-file-output=snyk-container-scan.sarif

–file=${{ env.PROJECT_DIR }}/Dockerfile

上記のスニペットでは、Snykを使用してアプリケーションコンテナをモニタリングする追加のステップが示されており、実際のSnykコンテナモニターが実行されます。

Snykモニターコマンドが実行された後、Snyk Web UIにログインしてプロジェクトの最新のスナップショットと履歴を表示できます。

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

また、ビルドおよびテストアプリケーションジョブでもアプリケーションのソースコードをテストおよびモニタリングできます。以下のスニペットは、このガイドで使用されるGitHubワークフローの実装例を示しています。

次に、プロジェクトの新たに開示された脆弱性について定期的にSlack通知を受け取ります。

例外の処理

チームが安全と考えるいくつかの問題によって最終レポートが影響を受けたくない場合があります。Snykには、この状況を管理し、例外を処理するための組み込みの機能があります。

この機能について詳しくはこちらをご覧ください。

IDE向けSnyk

Snykは、次のようなさまざまなIDEをサポートしています:

Eclipseプラグイン

JetBrainsプラグイン

  • Visual Studio拡張機能
  • Visual Studio Code拡張機能
  • 上記のプラグインは、開発の初期段階で問題を検出して修正するのに役立ち、それによって本番システムでのフラストレーション、コスト、セキュリティの欠陥を排除します。また、長期的には反復と人的労力を削減します。例えば、CI/CDの自動化によって報告されたセキュリティの問題ごとに、問題を修正するためにコードを戻り、変更をコミットし、再度CI/CDの自動化を待ち、失敗した場合は繰り返す必要があります。
  • 公式のドキュメントから、これらの機能について詳しくはIDE向けSnykページをご覧ください。
  • ステップ5 – Snyk CI/CDワークフローを自動的にトリガーする
  • 次の行をgame-2048-snyk.yamlファイルの先頭からコメントアウト解除することで、ワークフローを各コミットまたはメインブランチへのPRごとに自動的にトリガーできます。
  • ファイルを編集した後、変更内容をメインブランチにコミットして準備が整います。
  • ステップ6 – Slack通知の有効化
  • Snykをセットアップして、プロジェクトで発見された新しい脆弱性や利用可能になった新しいアップグレードやパッチに関するSlackアラートを送信することができます。
  • セットアップするには、Slackウェブフックを生成する必要があります。Incoming WebHooksを介して行うか、独自のSlackアプリを作成して行うことができます。SlackウェブフックURLを生成したら、「組織を管理」の設定に移動し、URLを入力して接続ボタンをクリックします。

Source:
https://www.digitalocean.com/community/developer-center/using-the-snyk-vulnerability-scanning-tool