2026年1月28日水曜日

【Azure】WAFとの死闘168時間。ASP.NET CoreアプリをAzure WAFで守ろうとして学んだこと

 



1. イントロダクション

Azureを勉強して、ASP.NET Coreでポートフォリオ兼用のWebアプリを公開してみた。

「せっかくなら実戦的に」とAzure Web Application Firewall (WAF) を導入したが、ここからが本当の戦いの始まりだった……。

2. 最初の壁:ログインできない!

公開直後、ログインしようとすると謎の403エラー。ログを確認すると……

Restricted SQL Character Anomaly Detection (args): # of special characters exceeded (12)

何が起きていたのか?

ASP.NETの認証用Cookieに含まれる記号の多さが、「攻撃用コードを隠している」と判定されていた。

• 原因: WAFの「異常検知ルール(942450など)」。

• 気づき: セキュリティを強くしすぎると、標準的なフレームワークの挙動すら「悪」とみなされる。

3. 第二の壁:いたちごっこの泥沼

特定のCookieを除外設定(Exclusion)して「勝った!」と思ったのも束の間。今度は別のログが。

• SQL Injection Attack: SQL Tautology Detected(1=1攻撃の誤認)

• Multiple URL Encoding Detected(二重エンコードの誤認)

しかも、よく見るとCookieだけでなく、URLの引数(ARGS)でも発生している。

ここで私は、「1つ1つ除外設定を書いていたら、いつまでもアプリがまともに動かない」という現実に直面した。

4. 決戦:ログから読み解く「真犯人」

WAFのログに記録された detail_message_s をデコードして、じっくり眺めてみた。

そこには、攻撃コードではなく、ただの「日付データ」や「パスワードの記号」があった。

今回の学び(技術的な急所)

1. 多重エンコードの正体: URLの中にURLを入れる(ReturnUrl)際、記号が %252F のように多重変換される。これはモダンなWebフレームワークの「標準仕様」であって攻撃ではない。

2. パスワードの宿命: 強力なパスワードには記号が必須。これをWAFのSQLIルールで検査すること自体が、実はアンチパターン。

5. 解決策:多層防御の再設計

「WAFの設定をいじり続ける」のをやめ、「どこをWAFに任せ、どこをアプリに任せるか」の役割分担を見直した。

• WAF側: パスワードやReturnUrlなど、正規の処理で記号が入り混じる箇所は、勇気を持って「検査除外」または「特定ルールの無効化」を行う。

• アプリ側: ASP.NET Core Identityを正しく使い、「パラメータ化クエリ(静的プレースホルダ)」と「アカウントロック機能」を有効にする。

6. おわりに:本当のセキュリティとは

WAFは「魔法の杖」ではなかった。

ただボタンをポチポチして「最強」に設定するのではなく、「自分のアプリがどういうURLを吐き出し、どういうCookieを使うのか」を理解して、初めて正しく運用できる。

「いたちごっこ」を終わらせたのは、WAFの知識ではなく、自作したASP.NET Coreのソースコードの中にあった一行のエビデンスだった。