WAF
Web Application Firewall。
CloudFrontやロードバランサーにファイヤーウォールを設定し、不正なアクセスをブロックできる。
SQLインジェクションなどに対応できる。
セキュリティグループとは特性の違う攻撃の対策になる。
ただしセキュリティグループとは違って若干お金はかかる。
AWS WAFでSQLインジェクションをブロックしてみた | Developers.IO
http://dev.classmethod.jp/cloud/aws/aws-waf-sqli/
AWS WAFがALB(Application Load Balancer)で利用出来るようになりました
http://dev.classmethod.jp/cloud/aws/aws-waf-alb-support/
AWS WAF を急に導入することになったときに参考にした資料まとめ | DevelopersIO
https://dev.classmethod.jp/articles/blog-links-for-aws-waf-configuration/
※以前はCloudFrontが必須だったが、現在はALBでも使えるようになっている。
ELBを導入済みの場合、ALBに変更することでWAFを使えるようになる。
WAFを設定することにより、ファイルアップロードの実装が難しくなるなどのデメリットがある。
詳細は後述の「誤検知対策」を参照。
以下にVer2の解説がある。
操作方法が大きく変わっているので注意。
AWS WAFを完全に理解する ~WAFの基礎からv2の変更点まで~ | Developers.IO
https://dev.classmethod.jp/cloud/aws/fully-understood-aws-waf-v2/
以下、Ver2で検証したもの。
■テストページ
index.php:
<html>
<meta charset="UTF-8">
<head>
<title>ログイン画面</title>
</head>
<body>
<form action="db.php" method="post">
<table>
<tr>
<td>ユーザID</td>
<td><input type="text" name="uid"></td>
</tr>
<tr>
<td>パスワード</td>
<td><input type="password" name="password"></td>
</tr>
</table>
<input type="submit" value="ログイン">
</form>
</body>
</html>
db.php:
<html>
<meta charset="UTF-8">
<head>
<title>ログイン処理</title>
</head>
<body>
<pre><?php
$uid = $_POST['uid'];
$pass = $_POST['password'];
print("SELECT email FROM users WHERE uid='$uid' AND passwd='{$pass}'");
?></pre>
</body>
</html>
ブラウザからindex.phpにアクセスし、
ユーザID: test
パスワード: test
で認証すれば通常通り処理されるが、
ユーザID: test
パスワード: ' OR 'A' = 'A
で認証すれば「403 Forbidden」と表示される。(WAFで入力を弾いている。)
…となるように以降で設定する。
■WAFを導入
SQLi と XSS を防ぐための AWS WAF ルール
https://aws.amazon.com/jp/premiumsupport/knowledge-center/waf-rule-prevent-sqli-xss/
WAF & Shield → Create web ACL
Step 1: Describe web ACL and associate it to AWS resources
Name: test
CloudWatch metric name: test(自動で入力される。)
Resource type: Regional resources(CloudFrontに対して設定したい場合、「CloudFront distributions」にする。)
Region: Asia Pacific (Tokyo)
Associated AWS resources: study(ここでは、テストで作成したALBを選択した。)
「Next」ボタンを押す。
Step 2: Add rules and rule groups
「Add rules → Add my own rules and rule groups」をクリック。
Rule type: Rule builder
Name: SQL-injection
Type: Regular rule
If a request: matchs the statement
Inspect: Body(HTMLフォームを検査する。)
Content type: Plain text
Match type: Contains SQL injection attacks
Text transformation: URL decode(URLデコードを行った後で検査する。)
Oversize handling: Continue
Sensitivity level: Low
Action: Block
「Add rule」をクリックし、ページ上部の「Rules」部分にルールが追加されたことを確認する。
Default action: Allow(デフォルトのまま。)
「Next」ボタンを押す。
Step 3: Set rule priority
そのまま「Next」ボタンを押す。
Step 4: Configure metrics
そのまま「Next」ボタンを押す。
Step 5: Review and create web ACL
内容を確認して「Create web ACL」ボタンを押す。
■動作確認
http://203.0.113.1/waf/ ... ALBを経由しないアクセスなのでWAFは無効になっている。
http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/ ... ALBに対して設定したのでWAFが有効になっている。
WAFは、なるべく後ろにある方が良さそう。
基本的にCloudFrontに対してよりも、ALBに対してWAFを設定すると良さそう。
(AWSへの直接アクセスを禁止するなら、CloudFrontへの設定でいい。)
WAFが機能しない場合、意図したAWSリソースが選択されているかなどを確認する。
■XSS対策
「WAFを導入」と基本的には同じ手順で導入できる。
その際、「Step 2」の操作内容は以下のようにする。
もし登録済みのWeb ACLがあれば、「Rules」タブからルールを追加することもできる。
Step 2: Add rules and rule groups
「Add rules → Add my own rules and rule groups」をクリック。
Rule type: Rule builder
Name: XSS-injection
Type: Regular rule
If a request: matchs the statement
Inspect: Body(HTMLフォームを検査する。)
Content type: Plain text
Match type: Contains XSS injection attacks
Text transformation: URL decode(URLデコードを行った後で検査する。)
Oversize handling: Continue
Action: Block
「Add rule」をクリックし、ルールが追加されたことを確認する。
これで
ユーザID: test
パスワード: <script>window.alert(1)</script>
で認証すれば「403 Forbidden」と表示される。(WAFで入力を弾いている。)
■IP制限
AWS WAFV2でIPアドレス制限してみた | DevelopersIO
https://dev.classmethod.jp/articles/how-to-use-aws-waf-v2-to-filter-incoming-traffic-based-ip-addres...
練習を兼ねて&即座にIP制限ができるように、IP制限の設定だけは最初にしておくといい。
以下は設定を試したときのメモ。
この場合、「192.0.2.1」からのアクセスが拒否される。
WAF & Shield → IP sets → Create IP set
IP set name: Black-List
Region: Asia Pacific (Tokyo)
IP version: IPv4
IP addresses: 192.0.2.1/32
以降は「WAFを導入」と基本的には同じ手順で導入できる。
その際、「Step 2」の操作内容は以下のようにする。
もし登録済みのWeb ACLがあれば、「Rules」タブからルールを追加することもできる。
Step 2: Add rules and rule groups
「Add rules → Add my own rules and rule groups」をクリック。
Rule type: IP set
Name: IP-Restriction
IP set: Black-List(上の手順で作成したものを選択。)
IP address to use as the originating address: Source IP address
Action: Block
「Add rule」をクリックし、ルールが追加されたことを確認する。
これで「Black-List」のIPアドレスを更新することで、IP制限を行うことができる。
(反映には、10〜20秒ほどのタイムラグがある。)
制限対象とするIPアドレスは、「WAF & Shield → IP sets → Black-List」の画面から追加削除できる。
■大量アクセスを自動的にIP制限
AWS WAF でアクセス数が一定回数を超えた IP アドレスを自動的にブラックリストに追加させる方法 | DevelopersIO
https://dev.classmethod.jp/articles/tsnote-aws-waf-autoblock/
「WAFを導入」と基本的には同じ手順で導入できる。
その際、「Step 2」の操作内容は以下のようにする。
もし登録済みのWeb ACLがあれば、「Rules」タブからルールを追加することもできる。
Step 2: Add rules and rule groups
「Add rules → Add my own rules and rule groups」をクリック。
Rule type: Rule builder
Name: DoS-Protection
Type: Rate-based rule
Rate limit: 100(最小値が100。)
IP address to use for rate limiting: Source IP address
Criteria to count request towards rate limit: Consider all requests(特定パス配下にのみ設定したければ「Only consider requests that match the criteria in a rule statement」を選択し、追加で必要な設定を行う。)
Action: Block
「Add rule」をクリックし、ルールが追加されたことを確認する。
これで大量アクセスすると自動でブロックされる。
Web ACLs「test」の「Overview」で「DoS-Protection BlockedRequests 200」を確認できる。200回ブロックされたということだと思われる。
$ curl -I http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/
HTTP/1.1 200 OK
Date: Thu, 12 Jan 2023 10:41:33 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Server: Apache/2.4.54 ()
X-Powered-By: PHP/8.1.12
Upgrade: h2,h2c
$ ab -n 10 -c 1 http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/
Complete requests: 10
Failed requests: 0
$ ab -n 100 -c 1 http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/
Complete requests: 100
Failed requests: 0
$ ab -n 200 -c 1 http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/
Complete requests: 200
Failed requests: 0
$ ab -n 300 -c 1 http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/
Complete requests: 300
Failed requests: 0
以下のように403エラーが返されるようになったが、上記のように「Failed requests」にはカウントされないみたい。
また、403エラーが返されるようになるまで数分のタイムラグがあった。
$ curl http://develop-123456789.ap-northeast-1.elb.amazonaws.com/waf/ --verbose
* Trying 203.0.113.1:80...
* Connected to develop-123456789.ap-northeast-1.elb.amazonaws.com (203.0.113.1) port 80 (#0)
> GET /test/ HTTP/1.1
> Host: develop-123456789.ap-northeast-1.elb.amazonaws.com
> User-Agent: curl/7.76.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 403 Forbidden
< Server: awselb/2.0
< Date: Fri, 13 Jan 2023 06:25:44 GMT
< Content-Type: text/html
< Content-Length: 118
< Connection: keep-alive
<
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
</body>
</html>
* Connection #0 to host develop-123456789.ap-northeast-1.elb.amazonaws.com left intact
ブロックされたリクエストは、Web ACLs「test」の「Overview」の「Sampled requests」で確認できるみたい。
IPアドレスや対象URLなどを確認できる。
(受信したリクエストから、AWS WAFがランダムに選択したものが表示されるみたい。
すべてのログを記録する場合、「Logging and metrics」タブから設定できるみたい。)
また、このIP制限は一定時間が経過すると自動で解除される。
30分ほどで自動解除されていることは確認できた。(大量アクセスが落ち着いたら時点で解除されるのかもしれない。)
■海外からのアクセスを制限
※未検証
AWS WAFで日本国外からのアクセスをブロックする - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/aws-waf-block-from-overseas-countries
AWS WAF で国外からのアクセスを禁止しつつ、例外許可IPアドレスを設定してみた #waf - Qiita
https://qiita.com/sugimount-a/items/20a8c643a01d08b802bf
AWS WAF v2 で特定の国からのアクセスをブロックしてみた | DevelopersIO
https://dev.classmethod.jp/articles/aws-wafv2-country-block/
■その他の制限
AWS WAFで日本国外からのアクセスをブロックする - サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/aws-waf-block-from-overseas-countries
AWS WAF で Bot からのアクセスを管理する Bot Control が利用可能になりました! | DevelopersIO
https://dev.classmethod.jp/articles/aws-bot-control/
[アップデート]AWS WAFのBot Controlルールグループに検査レベル「Targeted」が追加され、新たに4つのインテリジェントなルールが利用可能になりました | DevelopersIO
https://dev.classmethod.jp/articles/aws-waf-targeted-bot/
レートベースルールで検知したIPをIP Setに登録する | DevelopersIO
https://dev.classmethod.jp/articles/add-ratebase-rule-deny-ip/
■ブロック時の画面をカスタマイズする
WAFで制限されると、そのリクエストの画面には「403 Forbidden」とだけ表示される。
これだけだと何の影響でエラーになっているのか判りづらいので、問い合わせ対応のためにも独自のメッセージを表示させておくといい。
AWS WAFの機能だけでブロック時にカスタムエラーページを表示させてみた | DevelopersIO
https://dev.classmethod.jp/articles/aws-waf-custom-response_bodies_html/
WAFの設定画面でルールを追加する際、Actionで「Block」を選択してCustom response内で以下のように設定する。
Enable: (チェックを入れる。)
Response code: 403
Choose how you would like to specify the response body: Create a custom response body
すると「Create a custom response body」というダイアログが開くので、以下のように登録する。
Response body object name: 403
Content type: HTML
Response body: (任意のHTML。)
登録した内容は、次回からは「Choose how you would like to specify the response body」の選択肢に表示される。
「任意のHTML」は4KB以内で作成する。
また、ヘッダでUTF-8を宣言しておくといい。
以下は具体的なHTMLの例。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>403 Forbidden</title>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
</head>
<body>
<h1>403 Forbidden</h1>
<p>ウェブアプリケーションファイアウォールによりアクセスが遮断されました。</p>
<p><a href="/">トップページへ戻る</a></p>
</body>
</html>
■マネージドルール
ルールを追加する際、「Add my own rules and rule groups」ではなく「Add managed rule groups」を選択するとマネージドルールの選択画面になる。
あらかじめ定義されたルールを適用できるので、運用を楽にすることはできそうだが、利用料金がかかるので注意。
AWS WAF向けマネージドルールのおすすめは?種類別サービス7選|アスピック
https://www.aspicjapan.org/asu/article/11671
■誤検知対策
ロリポップのWAFは、有効にするとWordPressなどがまともに動かなくなるらしい。
記事投稿時にWAFをOFFにするか、常にWAFをOFFにするか…のように紹介されている。
WordPress403 Forbiddenの原因はWAF!対処し解決する方法!:ロリポップ、さくら、ヘテムルのサーバー
http://bibabosi-rizumu.com/403error-forbidden/
ロリポップ+WordPress+Contact Form 7でWAFが誤動作してForbiddenになるんだけどどういうことなの | texst.net
http://texst.net/lolipop-waf-wordpress-cf7-forbidden/
AWSのWAFも同じことになる可能性はあるが、
「AWS Black Belt Tech Webinar 2015 ‐ AWS WAF」レポート | Developers.IO
http://dev.classmethod.jp/cloud/aws/blackbelt2015-waf/
にて
「これまでのWAF: 誤検知 (false positive) が増えて悩むことになった」
「AWS WAFには、次のような特長がある: ルールを柔軟にカスタマイズできる」
のように紹介されている。柔軟にカスタマイズすることで、誤検知の対策はできるのかも。要勉強。
本番環境でWAFを導入する場合、テスト段階でも導入して動作確認しておかないと、
アプリケーションが正しく動作しない可能性がありそうなので注意。
…と思いつつ案件に本格導入しようとしたが、検収環境での検証時に「ファイルをアップロードできない」という問題が発生した。
AWS WAF について最初から知りたかったこと8選 - ISID テックブログ
https://tech.isid.co.jp/entry/8_things_i_wanted_to_know_about_aws_waf
AWS WAF によってブロックされたファイルのアップロード
https://aws.amazon.com/jp/premiumsupport/knowledge-center/waf-upload-blocked-files/
【AWS】特定のURIリクエストのみAWS WAFルールを適用させない方法 - Qiita
https://qiita.com/yokoo-an209/items/7037aed6fbe18fb4c659
WordPress + AWS WAF設定時の注意点 - Qiita
https://qiita.com/hirai-11/items/252705c33914dcab000c
AWS上のWebシステムへのファイルアップロード時にAWS WAFでブロックされる。
https://teratail.com/questions/heafxwwa3541vz
AWS WAFのマネージドルールでありがちな予期せぬブロック(随時更新) - mazyu36の日記
https://mazyu36.hatenablog.com/entry/2023/02/21/191736
AWS WAF を本適用の前にカウントモードで試用したい - DENET 技術ブログ
https://blog.denet.co.jp/aws-waf-count/
現状「ファイルアップロードは除外」などは対応不可らしい。
対応するなら「WAFに対して(あらかじめ安全だと確認できている)特定のURI時のリクエストに対してブロックルールを適用しない」とする必要があるらしい。
…が、本番環境に導入したら
「特定のURLから投稿できない。ルールの調整を忘れていた」
「ここは問題無いと思っていたがWAFに引っかかった」
が時々発生して障害になりそうな。他にも、新たな問題が発覚したりはありそうな。
よって、2023年3月時点では導入を見送った。
■誤検知対策に特定のURLを除外
上記のとおりWAFには誤検知の問題があるが、特定のURLを検知対象から除外することができる。
ただし後付けで除外設定を行うのは非常に大変そう。
WAFを使うことを前提として、最初から「ファイルアップロードは〇〇のURL配下でのみ行う」のような設計にしておくのが無難そう。
特定の HTTP リクエストを AWS WAF の検査から除外する | AWS re:Post
https://repost.aws/ja/knowledge-center/waf-exclude-specific-requests-inspection
AWS WAF でブロックされた特定の URI リクエストに対して除外設定を適用させてみた | AWS運用最適化サービス cloud link (クラウドリンク)
https://aws.taf-jp.com/blog/111208
「WAF & Shield → Web ACLs → (WAFを選択) → Rules → (ルールを選択) → Edit」の画面で設定できる。
「Statement」の「Inspect」で「URI path」を選択し、「Match type」で「Matches regular expression」を選択し、
「Regular expression」に正規表現でURLを入力する。
例えば「^/test/document$」と入力すると「/test/document」に一致する。
「Text transformation」は基本的に「None」で良さそう。
■WAFに検知されたときの挙動
※未検証。
物件情報の掲載サイトで、スクレイピングを防ぐことができるか…について調べたときのメモ。
・reCAPTCHAを使ってスクレイピングを防止するなら、ユーザも検索&物件表示の前に認証を行う必要があるので現実的では無いか。
・ユーザーエージェントやIPアドレスで弾くことはできるが完全では無い。
・サイトの利用にログインを必須にしても、それを踏まえてスクレイピングツールを作ることは可能。そもそもログインを必須にする改修が大変そう。
・同一IPアドレスから頻繁にアクセスがあれば自動でブロックはできるが、正常なアクセスも弾いてしまう可能性がある。
・コンテンツをJavaScriptで描画すればスクレイピングしづらくなるが不可能では無い。
・うっかりGoogleなど検索エンジンを弾くと問題になる。
・弾くまでいかなくても、対策内容によってはSEO上不利になる可能性はある。
Webスクレイピングマスターが教える「スクレイピング対策」@09/16追記 #CSS - Qiita
https://qiita.com/Azunyan1111/items/a1964c18e409fe6718fd
まだ知らないの?遭遇可能5つのスクレイピング防止技術と回避対策 | Octoparse
https://www.octoparse.jp/blog/5-anti-scraping-techniques-you-may-encounter
Web スクレイピングとは?自社サイトが晒される脅威から対策まで解説 | SBテクノロジー (SBT)
https://www.softbanktech.co.jp/special/blog/it-keyword/2021/0022/
「同一IPアドレスから頻繁にアクセスがあれば自動でブロック」の案で、AWSのWAFを使うのが正攻法か。どこまで厳しく設定するかは難しいところ。
ただし対象サイトは物件数が700件ほどなので、行儀よく「1分に1回のアクセス」でスクレイピングしても半日以内に完了できる。これを防ぐのは無理だと思われる。
スクレイピングしてくる不届きものを、AWS WAFを使ってブロックする話 #waf - Qiita
https://qiita.com/MASAMIKI/items/51d364a3eda69b2508a9
AWS WAFで悪質なスクレイピングを防ごう - ブログ - 株式会社Smallit(スモーリット)
https://smallit.co.jp/blog/a4308/
普段はWAFで「DoS-Protection」として「5分間に1万回アクセスされたら弾く」「5分間に1,000回アクセスされたら弾く」のように設定していることが多い。
Actionを「Block」にしているが、「CAPTCHA」が選択できるようになっている。
これなら「一定回数以上アクセスがあったらパズルが表示される」の対策ができるみたい。
AWS WAF の CAPTCHA 機能でアプリケーションを修正せずにボット判別する方法 | AWS運用最適化サービス cloud link (クラウドリンク)
https://aws.taf-jp.com/blog/97763
物件詳細ページに限定して設定したりは大丈夫みたい。
提案するなら、検収環境などで実際に設定して挙動を確認しておきたい。
Actionは「CAPTCHA」以外に「Challenge」というものがある。
CAPTCHAのようにパズルを表示して確認するのではなく、バックグラウンドで確認されるらしい。
GoogleのreCAPTCHAのようなものか。
ロボットと判定された場合、真っ白い画面になったりアラートが表示されたりするらしい。
いずれにせよ、検索エンジンのクローラーを弾く可能性はあるか。もしくはそれらは自動で制限対象外となっているか。
CAPTCHAChallengeの および AWS WAF - AWS WAF、 AWS Firewall Manager、および AWS Shield Advanced
https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/waf-captcha-and-challenge.html
AWS WAFルールの基本をわかりやすく解説!マネージドルールも併せて紹介|WafCharm|WAF自動運用サービス
https://www.wafcharm.com/jp/blog/aws-waf-rule/
AWS WAF で CAPTCHA 設定が可能になりました|WafCharm|WAF自動運用サービス
https://www.wafcharm.com/jp/blog/aws-waf-captcha-action-available-ja/
AWS WAF で新しいアクションの設定が可能に / 国別制限の設定が地域単位で可能に|WafCharm|WAF自動運用サービス
https://www.wafcharm.com/jp/blog/aws-waf-new-rule-action-and-granular-geo-match/
AWS WAF の CAPTCHA を試しつつログを CloudWatch Logs で確認した | DevelopersIO
https://dev.classmethod.jp/articles/logs-were-checked-in-cloudwatch-logs-while-testing-the-aws-waf-c...
AWS WAFのChallengeアクションの動作を見てみる | DevelopersIO
https://dev.classmethod.jp/articles/aws-waf-what-is-challenge-action/
ただしやはり、対象が700件とそれほど多くは無いので、「5分につき1ページ」のような頻度で取得されると防ぐことは難しい。
■メモ
AWS Shield はDDoS攻撃を緩和させるサービス。
Standardは自動で適用されているため、ユーザ側での設定は不要。
Advancedにするには、AWSサポートのビジネスレベルかエンタープライズレベルである必要がある。
5分で分かるAWS Shield
https://recipe.kc-cloud.jp/archives/9009
ただし運用していてDos攻撃を受けることはあるので、どの程度機能しているのかは不明。
以下などのように、攻撃してきたIPアドレスを自動で弾くなどの対策が必要そう。
AWS WAFを使って簡単にDoS攻撃を防いでみよう【セキュリティ対策】 | レコチョクのエンジニアブログ
https://techblog.recochoku.jp/4070