OPS

Google Cloud環境のWebアプリに、WAFを導入する方法とは?

Google Cloud環境のWebアプリに、WAFを導入する方法とは?

2021.12.03

本記事のポイント

Webアプリケーションのセキュリティ対策の一つとして、Webアプリケーションの脆弱性を狙ったサイバー攻撃を防ぐためのWAF(Web Application Firewall)があります。

本記事では、Google Cloud環境で運用するWebアプリケーションに対し、Google Cloud Platformが提供するCloud Armorを使用して簡単にWAFを導入する方法をご紹介します。

 

はじめに

Google Cloud Platform環境でWebアプリケーションを開発・運用している皆様の中には、アプリケーションやWebサイトのセキュリティ対策をどのように取り組んでいけばよいかお悩みの方も多くいらっしゃるのではないのでしょうか。 そこで今回は、Google Cloud PlatformのGoogle Cloud Armor (以下、Cloud Armor)のご紹介と、Cloud Armorを導入する2つのメリットを解説します! 記事前半ではCloud Armorの概要を、後半ではCloud Armorの設定方法と攻撃の検知例をお伝えしますので、ぜひご覧ください。 > Google Cloud が6%OFFで使える!請求代行サービス > Google Cloud の監視・運用代行サービス 詳細はこちら

Webサイトとアプリを保護!Google Cloud Armorとは

Cloud Armorとは、Google CloudのHTTP (S) 負荷分散サービスであるCloud Load Balancingのバックエンドサービスとして稼働するWebアプリケーションを対象に、そのWebアプリケーションを様々なタイプの脅威から保護するセキュリティサービスです。 主な機能として以下のものが挙げられます。
  • 機械学習を使用したDDoS対策
  • IP制限(ブラックリスト、ホワイトリスト)
  • 事前構成されているWAFルール
参考サイト ・ Google Cloud Armor の概要

Cloud Armorを導入する2つのメリット

続いて、Google Cloud PlatformユーザがCloud Armorを導入するメリットについてご紹介します。

1. 導入の容易さ

Cloud ArmorのWAF機能のルールでは、OWASP のModSecurityと呼ばれるWebアプリケーション・セキュリティに関する一般的なリスクをまとめたルールセットを基に事前構成されたセキュリティルールが使用できます。 そのため、ルールを適用するだけで、頭を悩ませることなく主要攻撃に対するセキュリティ構成を実現することが可能です。

2. Google Cloudの組織単位でセキュリティ管理が可能

Cloud ArmorはGoogle Cloud にて提供されている組織単位でのリスク管理サービス Secuity Command Centerと自動的に検知データが統合されます。 このSecuity Command Centerを利用することで、攻撃検知にとどまらず、攻撃に対するアクセス拒否率の増減などの統計データも確認できます。 参考サイト ・ Security Command Center の検出結果 > Google Cloud が6%OFFで使える!請求代行サービス > Google Cloud の監視・運用代行サービス 詳細はこちら

実際にCloud ArmorでWAFを導入してみる

では実際にCloud ArmorのWAF機能を利用し、攻撃からアプリケーションを保護する方法をご紹介します。

事前準備

先述したように、Cloud Armorの保護対象とするのはGoogle Cloud Platform環境でCloud Load Balancing経由で公開されているWebサイトとなります。そのため、検証用にWebアプリケーションとロードバランサを用意します。
Webアプリケーション
本検証では攻撃としてXSS (クロスサイトスクリプティング) とSQLインジェクションを例にするため、後述するサイトを参考に3つのページを用意します。環境は以下の通りです。
Google Cloudサービス Google Computer Engine
OS CentOS Stream 8
Apache 2.4.37
PHP 7.2.24
MariaDB 10.3.28
XSS検証用Webページ
入力された値をそのままページに表示します。そのため、悪質なサイトに誘導するようなスクリプトが入力される危険性があります。
# /var/www/html/xss.php
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>XSS確認</title>
</head>
<body>
   <form action="" method="get" accept-charset="utf-8">
   <label class="label" for="name">入力値:</label>
       <input type="text" size="70" name="xss_text" value="">
       <p><input type="submit" value="送信"></p>
   </form>
   入力値はこちら: <?php echo $_GET['xss_text']; ?>
</body>
</html>

試しに以下のような入力をしてみましょう。 Google CloudのWAF - XSS検証用Webページ すると、表示された部分がリンクとなっており、クリックすると意図しないポップアップが表示されます。 Google CloudのWAF - ポップアップ 上記では単純なポップアップ表示のみに止めましたが、実際にはアプリケーション側が意図しない、悪意ある別のサイトへのリンクが埋め込まれる可能性があり、脆弱性がある状態です。
SQLインジェクション検証用Webページ
データベースには以下のようなデータを用意します。
MariaDB [testdb]> select * from users;
+----+-----------------+
| id | name            |
+----+-----------------+
|  1 | 田中太郎        |
|  2 | 山田花子        |
|  3 | 鈴木一郎        |
|  4 | 佐藤亜美        |
|  5 | 高橋浩史        |
|  6 | 山本真衣        |
|  7 | 吉田大輔        |
|  8 | 中村さくら      |
+----+-----------------+
上記のデータベースから、ユーザIDを1つ指定して名前を取得するWebページを用意します。
データ入力ページ
# /var/www/html/sqli.php
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>インジェクションテスト</title>
    <!-- jQueryの読み込み -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
    <!-- フォーム作成 -->
    <form method="get" action="result.php">
    <p><label>ID:<br>
    <input type="text" maxlength="255" name="id">
    </label></p>
 
    <p><input type="submit" value="送信"></p>
    </form>
</body>
</html>
結果出力ページ
実行するSQL文「$sql = ‘SELECT * FROM users WHERE id = ‘. $id. ‘;’;」は、入力された値とSQL文の一部をそのまま結合して作成しており、意図しないSQL文が実行される可能性が高いです。
# /var/www/html/result.php
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>インジェクションテスト結果確認</title>
</head>
<body>
<table border="1">
    <tr>
        <th>id</th><th>ユーザ名</th>
    </tr>
 
    <!-- DBに接続しデータ取得 -->
    <?php
    // リクエストした値を取得
    $id = $_GET['id'];
 
    // DB接続用データ
    $host = 'localhost';
    $dbname = 'testdb';
    $dbuser = '〓任意のデータベースユーザ〓';
    $dbpass = '〓dbuserのパスワード〓';
 
    // データベース接続クラスPDOのインスタンス作成
    try {
        $dbh = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8mb4", $dbuser, $dbpass);
        // PDOExceptionクラスのインスタンス$eからエラーメッセージを取得
    } catch (PDOException $e) {
        var_dump($e->getMessage());
        exit;
    }
 
    // SQL実行
    $sql = 'SELECT * FROM users WHERE id = '. $id. ';';
    $stmt = $dbh->prepare($sql);
    $stmt->execute();
    ?>
 
    <!-- 結果表示 -->
    <?php while($row = $stmt->fetch(PDO::FETCH_ASSOC)): ?>
    <tr>
        <td><?php echo $row['id']; ?></td>
        <td><?php echo $row['name']; ?></td>
    </tr>
    <?php endwhile; ?>
</table>
</body>
想定する挙動は以下のような形です。 Google CloudのWAF - SQLインジェクション検証用Webページ しかし、以下の値を入力してみると、 Google CloudのWAF - SQLインジェクション検証用Webページ なんと本来1ユーザのみの情報が表示されるはずが、全てのユーザの情報が表示されています。 上記では全レコードが表示されるだけに止めましたが、実際にはレコードを全件削除するなどの操作も可能となっており、こちらも脆弱性がある状態です。
ロードバランサ
Cloud Load Balancingサービスから、バックエンドの構成を持つHTTP(S)負荷分散ロードバランサを用意します。 Google CloudのWAF - ロードバランサ Google CloudのWAF - ロードバランサ

WAFポリシー設定

それではここから、Cloud ArmorにてWAFを設定していきます。サイドバーから「ネットワークセキュリティ」 >> 「Cloud Armor」を選択します。 Cloud ArmorにてWAFを設定 新しいポリシーを作成します。 Cloud ArmorにてWAF - ポリシー設定 「ポリシーの設定」項目にて、任意のポリシー名を入力、ポリシータイプを「バックエンドセキュリティポリシー」、「デフォルトのルールアクションを「拒否」、拒否ステータスを403にしたら、「次のステップ」をクリックします。 Cloud Armor WAF - ポリシー設定 「ルールの追加」項目にて、新しいルールを2つ追加します。 1つ目は、攻撃を拒否するルールです。詳細モードを選択し、「一致」の欄に以下のルール条件を設定、アクションを「拒否」とし、優先度を「1000」とします。
evaluatePreconfiguredExpr('xss-canary') || evaluatePreconfiguredExpr('sqli-canary')
ここで「一致」の欄に入力した条件は、XSSとSQLインジェクション のどちらかの攻撃が発生した場合、そのアクセスを403エラーで拒否するという内容となります。 XSSとSQLインジェクションで攻撃が発生した場合、403エラー 2つ目は、正常なアクセスを許可するルールです。 ポリシーを作成すると、すべてのIPアドレスのアクセスを拒否するというデフォルトのルールが設定されています。そのため、このデフォルトルールを上書きする形でIPアドレスによるアクセス許可のルールを作成する必要があります。 基本モードを選択し、「一致」の欄に「*」を入力、アクションを「許可」とし、優先度を「1001」とします。ここでは優先度を「1001」としていますが、1つ目のルールの優先度の値とデフォルトルールの値の間、つまり今回でいえば1001~ 2,147,483,646 の間の値であれば、どの値でも問題ありません。 Cloud Armor - 正常なアクセスを許可するルール 2つのルールを作成後、「ターゲットへのポリシーの適用」項目と「高度な設定 (Adaptive Protection)」項目はスキップし「ポリシーを作成」をクリックします。 ターゲットへのポリシーの適用、高度な設定 (Adaptive Protection)、ポリシーを作成 次に作成したポリシーをロードバランサのバックエンドサービスに紐づけます。 サイドバーから「ネットワークサービス」 >> 「Cloud Load Balancing」を選択します。 ネットワークサービス > Cloud Load Balancing 「バックエンド」タブを選択し、事前に用意したロードバランサに紐づくバックエンドサービスを編集します。 編集画面内「Cloud Armor セキュリティポリシー」にて、作成したポリシーを選択し、「保存」をクリックします。 Cloud Armor セキュリティポリシー 再度Cloud Armorの画面から対象ポリシーの詳細画面に遷移、「ターゲット」タブをクリックし、用意したロードバランサとバックエンドサービスにポリシーが適用されていることを確認します。 ロードバランサとバックエンドサービスにポリシーが適用 これで設定完了です!

攻撃からの保護検証、確認

それでは、WAF機能を設定した状態で、準備工程で入力した値を再度入力し攻撃がブロックされるか確認してみましょう。
1)XSS
設定どおり、403エラーが発生し、不正な操作が拒否されています。 XSS - 403エラーが発生し、不正な操作が拒否 またロードバランサのログからも、設定したポリシーでアクセスが拒否されていることが確認できます。 ロードバランサのログからも、設定したポリシーでアクセスが拒否
2)SQLインジェクション
こちらも同様に、403エラーが発生し、攻撃がブロックされていることが確認できます。 SQLインジェクション - 403エラーが発生し、攻撃がブロック 結果として、脆弱性を狙う攻撃からWebアプリケーションを保護するセキュリティ構成を実現することができました。 参考サイト

まとめ

今回は、Cloud Armorを利用したGoogle Cloud Platform環境のWebアプリケーションに対するWAFの導入方法をご紹介しました。標準で用意されているルールを使用することで、脆弱性を狙う攻撃に対するセキュリティを簡単に実現することができました。 本記事では省略しましたが、Cloud Loggingサービスにて設定したポリシーで拒否したアクセスのログに対するアラートを設定することで、いつどんな攻撃を受けていたかなどの検知内容を自動的に認知することも可能です。 皆様もお使いのGoogle Cloud Platform環境にCloud Armorの導入を検討してみてはいかがでしょうか? > Google Cloud が6%OFFで使える!請求代行サービス > Google Cloud の監視・運用代行サービス 詳細はこちら