【webサイトセキュリティ対策】検索フォームへのSQL判定などがある不正な入力を、WAFで遮断する

      2384文字

【webサイトセキュリティ対策】検索フォームへのSQL判定などがある不正な入力を、WAFで遮断する

今回は、webサイトセキュリティ対策について、『検索フォームへのSQL判定などがある不正な入力を、WAF(ウェブアプリケーションファイアウォール)で遮断』というのをやってみます。
通常は『プレースホルダやエスケープ処理』などで対応しますが、念には念を入れて、WAFも取り入れてみます。さっそく、効果を確認していきましょう。

気になった経緯~urlの解析に、不正な数値を含むパラメーターが確認された

以前、SSFで検索システム(WordPress)を実装したときのことです。『フォームでは数値のみ、3桁以上入らないように・wpdbじゃなくget_posts/WP_Queryを使う(wpdbクラスは$wpdb->prepareのようなインジェクション対策が必要)』みたいなのは気にしながら作りました。


しかし、解析をみると『11616164164』みたいなありえない数値(BPMの最低値がこの値だと、デカすぎて一切レコードが出ない)があったので、フォームは大丈夫かと気になったのが経緯です。

*後から考えた内容としては、『フォームでは3桁以上入らないようにしたが、ブラウザアドレスバーに直接打ち込んだ』『数値だけだったので、ロリポップのWAFが、不正なSQLクエリやスクリプトと判定しなかった』と予想しています。ecのサイトで買い物するときに、urlパラメーターを直接アドレスバーに打ち込んで絞り込むやつ、管理人もたまにやります(笑)

WAF(ウェブアプリケーションファイアウォール)実験

下準備~フォームを改造して、不正な値が入るようにする

まずは下準備として、同じデザインでテストページを作り、フォームを改造して、不正な値が入るようにします。他人のサイトや、(取引先からセキュリティテストの依頼など)許可を得ていない段階でこれをやると、不正アクセスで訴えられる可能性があるので、気をつけましょう。

こんな感じで、よくあるインジェクション用文字列も入るようにしました。

ASCII文字URLエンコードについては『%20がスペース』『%27がシングルクオーテーション』です。¥マークは『シングルクオーテーション内のエスケープ文字が文字列として出る』というやつです。

とはいえ、『全レコードを取得』できるわけではなく、『’compare’ => ‘>’, ‘type’=>’NUMERIC’』と数値判定する形になっており、数値以外のフィールド値が入っているものはヒットしません(unknownや空、という記事は出ていない)。


また、これはSQLクエリじゃなく文字判定・数値より前のような挙動になっており、『最大値の〇〇以下』だと、一切出ません。要因としては、『WP組み込みファンクションでエスケープされて文字列が出ている』というのが考えられますね。

クエリ保護しない状態で、wpdbクラス→直接SQLとかだと、他のテーブルも抜かれる可能性はあるので、怖いところです。

サーバー側で、WAF設定する(ロリポップサーバー例)

で、このサイトやSSFはロリポサーバーに設置されています。ロリポでもWAF機能がありました(他の有料サーバーでもあると思います)。公式のアナウンスによると『攻撃パターンの定義ファイルは自動でアップデートされる』とのことです。


設定は『対応させたい割り当てドメイン/サブドメイン』を選んで、『有効』にするだけ。

WAF設定した状態で、よくあるインジェクション用文字列入力→ブロック&ログ収拾へ


WAF設定した状態で、先ほどの『条件が常にtrueになるインジェクション用文字列』をフォームに入れてみました。この状態だとWAFのブロックが発生して、サイトが見れない・情報が取得できないという形になります。


また、不正入力などは、ログに保存されます(ロリポでの期間は1週間)。インジェクション用文字列のほか、『Util/PHP/eval-stdin.php』に対するアタックをブロックした様子も確認できました。古いバージョンだと、ここの脆弱性も報告されていました。

インジェクション用文字列みたいなのはこれでブロックできたけど、『大きすぎる不正な値をブラウザから直接入れる』については判定できなかったようなので、『フロント側で警告・対策』のほか、『サーバー側で受け取った値が不適切な場合、(記事取得を停止して)メッセージを出す』などをしても良いかもしれません。

あとがき・まとめ

  • 解析やアクセスログで、怪しいurlパラメータが確認されることがある
  • ロリポップレンタルサーバーのWAFでは、インジェクション用文字列を含むパラメータをブロックできる
  • ただし、SQLやスクリプト判定されない値については、対応が必要

まとめると、こんなところでしょうか。結果として『単純な数値』についてはWAFが効かなかったんだけど、現在やっているフロントでのバリデーション(数値以外入らない、3桁まで)のほか、『サーバー側で不正な値を判定して、出力を変える』みたいな対応はできそうです。

また、『WordPress内部で文字列がエスケープされるパターン』みたいなのもあるので、これは今後まとめます。

WordPressサイト制作&リニューアル・機能開発サービス | アトリエSS


【カテゴリ】 - PHP・データベースetc
【タグ】 -

  関連記事

【WordPress別サーバー引っ越し】SQLエクスポート/インポート&Redirectionプラグインを使った方法
WordPressの記事IDで判定して転送~PHP・headerとget_the_IDで対応、the_IDとの挙動の違いも
【PHP学習】var_dumpで出力するのと、echoで出力するのは、挙動がどのように違うの?
WPデータベースの余計なデータには何がある?事例と対処方法・あるとイヤなケース
【webサイトセキュリティ対策】検索フォームへのSQL判定などがある不正な入力を、WAFで遮断する
【ユーザーデータ取得】WordPress定義済み関数の『get_userdata()』『wp_get_current_user()』ってどのように違うの?
WordPress・REST APIのjsonファイルにカスタムフィールドを入れ、タイトル・アイキャッチと共に外部サイトで取得・表示
WordPress一覧表示で、特定のカテゴリ/投稿を表示しないようにするには?→category_not_in・post_not_inで
【WordPressで覚えよう】PHP「->」(オブジェクト演算子/アロー演算子)・「=>」(ダブルアロー演算子)の違い
【PHP etc.プログラム学習サイトコードコピペ】全角引用符・バッククオートが入ってて動かない件に注意
WordPressユーザーが覚えると便利な条件分岐~投稿記事・固定ページ指定して表示/非表示
【WP記事取得クエリ・プラグイン無し】お知らせなどに使える、ショートコードで特定カテゴリ記事を表示プログラム