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

更新: 2023/10/26 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
【タグ】-

関連記事

テスト環境(ローカル含む)でPHPサイト開発に使えるツール&XAMPPでやってみた例(設定や表示ファイルetc)
【PHPライブラリでスクレイピング】PHP Simple HTML DOM Parserで、クラスやID指定で別サイトの内容を取得する方法
【WordPressで覚える】PHP「->」(オブジェクト演算子/アロー演算子)・「=>」(ダブルアロー演算子)の違い
【PHPプログラミング】メモ帳に適当にメモったPV数値をexplodeで配列にし、array_sumで合計値を計算する
【WPカスタマイズ】プラグイン不使用、テーマに関連記事表示機能を実装しPV・滞在時間を上げる
PHP・shuffleやarrayを使った、画像ランダム表示方法~メインビジュアルやバナー・テキストに利用可
WordPress一覧表示で、特定のカテゴリ/投稿を表示しないようにするには?→category_not_in・post_not_inで
【別に止めなくてOK】WordPressサイトなどに、アメブロ・fc2などの更新情報を表示・連携する方法
【WordPress更新情報表示】php/wp組み込みファンクション(fetch_feed)で取得と、プラグインで表示どちらが良い?
【PHP学習】var_dumpで出力するのと、echoで出力するのは、挙動がどのように違うの?
【WordPressでPHP学習】用語:PHP変数・関数・定数を、WPの機能を通して覚える
YouTube Data APIを使って、PHPで『タイトル・動画id・サムネイル画像』などを取得してみる(Search: listリソース)