2019年4月14日日曜日

AWS WAFでハマった話

言わずと知れたクラウドサービスの代表格であるAWSに、AWS WAFというものがあります。
その名の通りWAFのサービスなのですが、これでちょっとハマったことがあるのでここに残しておきます。

謎の403

とあるサービスをAWSに移行したところ、突然403エラーが頻発しました。
ただ、毎回発生するわけではなく、発生する場合としない場合があります。
さらに、ブラウザーやOSによっても変わります。

AWSに移行したタイミングで発生したので多分AWSが原因だろうと推測できるのですが、特定がさっぱりできない状態でした。

リクエストがALBで止まっている

サーバー構成は、ざっくりこんなかんじです。
(リクエスト) → ALB → バランサー → APサーバー → DBサーバー
なんでALB使ってるのにその下にバランサー置いてんの?無知なの?というツッコミは勘弁してください。大人の事情でいろいろあるんです。

で、ここのバランサーのアクセスログを見ると、問題のリクエストだけログが残っていない。つまりALBでブロックされていることが判明。

Server: awselb/2.0

問題のリクエストのレスポンスヘッダーを見てみると、こんなものが目に留まりました。

Server: awselb/2.0

apacheとかnginxとかじゃなくてawselb。
これは何だということで調べてみたら、どうやらWAFがあやしいという情報が。

WAFのルールを1つずつ切ってみる

WAFに適用しているルールはいろいろあったので、1つずつ無効化して原因を探ることにしました。

すると、xxx-sqliというこれはSQLインジェクションのルールを無効化したときに403が発生しなくなりました。

つまりSQLインジェクションがあやしい。

大量の試行錯誤の末に

しかし。

問題のリクエストにはどこをどう見てもSQLインジェクションっぽいデータがありません。
そもそもこれGETリクエストだしパラメーターも何もありません。

原因を特定するために、全く同じリクエストをcurlコマンドで実行し、少しずつ情報を削ぎ落としていくという地味ーな作業を繰り返していきました。

そしてとうとう発見!これがSQLインジェクションにひっかかる最小のリクエストだ!

$ curl --cookie "a=null;" -i https://example.com
HTTP/1.1 403 Forbidden
Server: awselb/2.0
Date: Sat, 20 Apr 2019 22:53:31 GMT
Content-Type: text/html
Content-Length: 134
Connection: keep-alive

<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center>
<h1>
403 Forbidden</h1>
</center>
</body>
</html>

(URLはexample.comにしています。実際にexample.comにこのリクエストを投げてもこのエラーは発生しません)

Cookieの先頭foo=null;という値が入っていただけでSQLインジェクションのルールにひっかかることが判明。

なんだよこの判定基準…

対処方法

そもそもこんなCookieを発行しなければいいんですが、このCookieって外部サービスが発行しているんです。
だからアプリケーション側で制御しようがないのでどうしようか悩みました。

最終的に、SQLインジェクションのルールを無効化するという一番単純な方法で解決することに。

アプリケーション側ではちゃんとORMとかプレースホルダーを使っているので、注入される危険性は低いと信じて。

まとめ

AWS WAFのSQLインジェクションルールには気をつけましょう。

0 件のコメント:

コメントを投稿