エンジニアのはしがき

プログラミングの日々の知見を書き連ねているブログです

APIGateway+Lambda構成のAPIにlocalhostからPOSTできなくて半日悩んだ

f:id:tansantktk:20201120002649p:plain

いつも書いてるようなソースコードなのに何故かどうやっても動かない!各種設定値も間違ってない!でも動かない! 今回はそんな出来事を書き残していきたいと思います。

やりたかったこと

  • APIGateway+Lambdaで構成しているAPIに対して、localhost:3000で立ち上げたデバッグ用のAngularサーバからPOSTリクエストをしたかった。
  • POSTリクエストのボディにはログとして使う為の文字列http://localhost:3000/***が含まれている。

悩んだこと

  • 何故かPOSTリクエスト後にエラーレスポンスが返る。Chromeの開発者ツールで確認するとOPTIONSメソッドのリクエストがCORSエラーになっている。
  • APIのCORS設定を確認するものの全てのオリジンを許可されている。

原因

  • APIGatewayに適用していたWAFのルールにひっかかった為、ブロックされていた。
    • いろいろPostmanで試してみたところ、リクエストボディに含まれるlocalhostの文字列がまずかったのだと思われます。(ocalhostみたいな形で文字を削るとリクエストが通る)
  • AWSManagedRulesCommonRuleSet#EC2MetaDataSSRF_BODYというAWSがデフォルトで用意していたルールによってブロックされていた。

ブラウザはCORSエラー扱いしていましたが、実際はWAF側の問題でした。 ブロックされたということ自体を確認するには、AWSコンソールのWAFの画面を見る必要がある為、発見までかなり手こずりました…。

EC2MetaDataSSRF_BODYについて

AWS公式に記載がありました。

EC2MetaDataSSRF_BODY

リクエスト本文から Amazon EC2 メタデータを盗み出す試みがないかを検査します。 docs.aws.amazon.com

メタデータを盗むリクエストと誤認された模様。 詳しいアルゴリズムの記載はないので、デバッグして回避していくしかなさそうです。

反省

エラーの見当がつかない時は処理のフローを1から順に追って、各処理に関わるリソースについてしっかり確認をすべきでした。

CORSエラーを情報源にAPIの設定値周りばかり調べまわってたのは良くなかったですね。

あとがき

WAFは適用するのはとっても簡単ですが、何も考えずにコーディングをしていると結構ルールに引っかかったりすることが多いです。WAF適用後のデバッグ大事!