Snykを使ってCats vs Dogsしてみた @snykjp #Qiitaアドカレ

Snyk Advent Calendar 2022 の記事です。犬対猫の投票アプリをコンテナで作ってみました。
2022.12.25

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは!AWS事業本部コンサルティング部のたかくに(@takakuni_)です。

この記事は Snyk を使って開発者セキュリティにまつわる記事を投稿しよう! by Snyk Advent Calendar 2022の24日目として投稿しています。

狙っている景品は、あなただけの専属自動シェフ賞です。

Snyk は、アプリケーションコードからインフラストラクチャのコードまで幅広く脆弱性を検知できるツールです。今回の記事で興味いただけましたらフリープランもあるため、ぜひトライアルしてみてください。

安全にCats vs Dogsしたい

みなさん、Cats vs Dogs してますでしょうか?

今回のプレゼント企画のタイトルに「 猫しか勝たん賞 」がある通り、猫派 vs 犬派 の好みの分かれは、古くから議論されてます。ちなみに私は犬派です。

今回はそんなタイトルをコンセプトに、より安全に Cats vs Dogs アプリを作った話ができればと思います。

元ネタ

今回の構成、およびソースは AWS Workshop Studio から提供されているワークショップを題材に作成しています。私なりにコードと構成を一部変更しております。

元ネタのワークショップは、ECS (Fargate) を初めて触る方向けに作成されているため、とてもオススメです。

コード置き場

今回作成したコードは以下に格納されています。

当初、Monorepo (GitHub Actions を利用した CI/CD パイプラインの実装) を目指していたのですが、時間の都合上かなわず、名残が残って Terraform と Docker のコードが一緒のレポジトリ構成になっています。

時間ができたら、加筆していこうと思います。

構成図

以下のような構成で、Cats vs Dogs の投票アプリを作成していきました。

投票アプリの開発にあたり、どの部分で Snyk が利用可能なのか、実際に利用したのかをご紹介できればと思います。

コード開発

今回、 Terraform コードの新規作成とアプリケーションコードの一部修正を行いました。

Snyk ではコーディングをしている最中でも OSS の脆弱性、コードの品質および脆弱性チェック、 インフラ ( IaC ) の脆弱性をリアルタイムにチェックできます。

私は普段、AWS を主に触っているため AWS の脆弱性に関しては少しわかるのですが、アプリケーションコードや OSS ライブラリに関してはあまり自信がありません。

今回、元ネタから持ってきたアプリケーションコードに対して2つの推奨事項が表示されていました。

jquery の脆弱性

Web コンテナで利用している jquery ライブラリが、脆弱性を含んだバージョン(3.4.1)であると検出されました。

動作確認後、バージョン 3.6.1 へのアップデートを行いました。

/web/index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
-    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.6.3/css/bootstrap.min.css">
    <link rel="shortcut icon" href="#">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <title>Welcome to Cats and Dogs</title>
</head>
<style media="screen">
  body {
          background-color: #4c724c;
          font-size: 50pt;
          color: white;
    }
</style>
<body>
    <div class="container-fluid">
      <div id="one" class="text-center">
        <span>"Whats my url?"</span>
      </div>
      <div class="row">
        <div class="col-md-6 text-center">
          <a href="../cats/"><img src="https://ecs-demogo-pictures.s3.ap-northeast-2.amazonaws.com/web/web/img/ilovecats.jpg" width="400" height="400" alt="..." class="img-rounded"></a>
        </div>
        <div class="col-md-6 text-center">
          <a href="../dogs/"><img src="https://ecs-demogo-pictures.s3.ap-northeast-2.amazonaws.com/web/web/img/ilovedogs.jpg" width="400" height="400" alt="..." class="img-rounded"></a>
        </div>
      </div>
    </div>
<script>
    $('#one span').text(window.location.href);
</script>
</body>
</html>

Array (非推奨)コンストラクター

Snyk は脆弱性以外にも、アプリケーションコードの品質もコーディング中にチェックできます。

Cats, Dogs コンテナのindex.htmlで利用している Array コンストラクターが非推奨であるため、配列リテラルの利用を勧められました。

今回の場合はとてもシンプルでしたが、「どこが悪いのか、どのように変えるのか」がとても綺麗に表示されているため、素早く対応できる製品となっています。

/dogs/index.html

<!DOCTYPE html>
<html>
<head>
<title>Welcome to Cats and Dogs DemoGo</title>
<style>
    body {
            font-family: Helvetica, Arial, sans-serif;
            font-weight: 600;
            font-size: 20pt;
            text-transform: uppercase;
            text-align: center;
            background: #4c724c;
            color: white;
    }
</style>
</head>
<h1>This is what love looks like</h1>
<script language = "javascript">
-        var imgArray = new Array();
+        var imgArray = [];
        var bucket = "https://ecs-demogo-pictures.s3.ap-northeast-2.amazonaws.com/cat/"
        var ext = ".jpeg"
        for(i=0;i<10;i++){
            imgArray[i] = (bucket+i+ext);
        }
        function showImage(){
            var imgNum = Math.round(Math.random()*9);
            var objImg = document.getElementById("introImg");
            objImg.src = imgArray[imgNum];
        }
    </script>
<body onload = "showImage()">
        <img id = "introImg" border="0">
    </body>
</html>

IaC の脆弱性

Terraform で記載した AWS 基盤についても Snyk は独自のルールで脆弱性を判定します。

詳しい使い方は、以下をご覧ください。

本格的に触って気がついたのですが、検出された脆弱性の重要度でマーキングされる色が異なりました。

SNYK-CC-TF-48: Load balancer is internet facing」は、重要度が low であるため青くマーキングされていました。

対して、「SNYK-CC-TF-47: Load balancer endpoint does not enforce HTTPS」は重要度が medium であるため、黄色く表示されていました。

重要度別で表示されているため「どこから始めていいのか」の判別が捗りますね。

CI/CD パイプライン

開発者が私一人であるため今回は採用しませんでしたが、複数人での開発は、デプロイ経路を自動化した方がいいと私は思います。

例えば、複数人環境で先程の Visual Studio Code を利用したローカルでの脆弱性検査を行う場合、「インストールできない要件がある」、「有効化を忘れて脆弱性検出できていなかった」などの、個々の環境に依存するケースが見込まれます。

CI/CD パイプラインの利用は、脆弱性診断の「漏れ」を無くす方法としてとても有効な手段です。

Terraform

Terraform の CI/CD パイプラインで Snyk IaC を実行する方法の1つに Terraform Cloud を利用した方法があります。

Snyk は Terraform Cloud は統合機能を提供しており、自前で実装する必要がないことが特徴です。

導入方法など詳しくは、以下のブログをご覧ください。

OSS の脆弱性

Snyk は CodePipeline と統合機能を提供しています。

CodePipeline 内のアクションでは、 OSS の脆弱性を検出する Snyk OSS が提供されています。

具体的な利用方法としては Docker イメージをビルドする前に、ソースに対してスキャンを行う使い方があります。

こちらも詳しい使い方などは、以下のブログを併せてご覧ください。

デプロイしてみる

Snyk はシフトレフトを進めている製品であるため、デプロイ前でもかなり導入できる機会をご紹介しました。

ここからは実際にリソースをデプロイしてみようと思います。

CodeStar 接続

今回 CodePipeline のソースは GitHub を利用しています。

接続の承認を行い AWS からのアクセス許可を行います。

GitHub へアプリのインストールが完了したら、「接続」をクリックします。

接続に完了したら、ステータスが「利用可能」になっていることを確認します。

CodePipeline の再試行

先ほどの接続が未完であったため、初回のパイプライン実行は失敗します。

「再試行」からパイプラインを実行し直します。

ALB (投票アプリ)へのアクセス

デプロイが完了すると ALB に付与された DNS 名から投票アプリにアクセスできます。

※ 検証のため ALB のセキュリティグループに terraform apply を実行した IP のみアクセスできるよう制限をかけております。アクセスできない場合はセキュリティグループをご覧ください。

「I love CATS」を選択すると、猫の画像が表示されていますね。

「I love DOGS」を選択すると、こちらも問題なく犬の画像が閲覧できました。

Docker イメージの脆弱性スキャン

Snyk は ECR と統合して、コンテナイメージの脆弱性スキャンを提供しています。

脆弱性スキャンを提供している製品のことを Snyk Container といいます。

AWS では Amazon Inspector や ECR 自体にも、コンテナイメージの脆弱性スキャンが提供されています。(脆弱性 DB は異なります)

Snyk Container の場合、脆弱性の対策方法に関するアドバイスがあったり、コンテナイメージで使っているライブラリの依存関係のリストアップなどが追加で利用できます。

「FIXABILITY」を確認すると今の所、対処可能な脆弱性は対応できていることがわかります。

まとめ

まとめると Snyk は次のようなケースで脆弱性を検出できます。

幅広い分野で脆弱性をスキャンできるため、ぜひフリープランからお試しいただけると嬉しいです。

  • OSS の脆弱性 (Snyk OSS) 1
    • Visual Studio Code (IDE) の利用
    • CodePipeline との統合
  • コードの品質管理 (Snyk Code) 1
    • Visual Studio Code (IDE) の利用
  • アプリケーションコードの脆弱性 (Snyk Code) 1
    • Visual Studio Code (IDE) の利用
  • コンテナイメージの脆弱性 (Snyk Container) 2
    • ECRへのイメージスキャン
  • IaC の脆弱性 (Snyk IaC) 1
    • Visual Studio Code (IDE) の利用
    • Terraform Cloud の利用

以上、AWS事業本部コンサルティング部のたかくに(@takakuni_)でした!

注釈


  1. GitHubと直接統合することで継続的に脆弱性を検出可能です。 
  2. GitHubと直接統合することで Dockerfile (ビルド前)に脆弱性を検出可能です。