速報

X.Orgのクライアントライブラリーで17件を修正!Linux端末と画像処理の利用範囲を点検

CATEGORY

SQLインジェクションを防ぐ実装と検証|プレースホルダーで守れない部分も確認

※本ページのリンクにはプロモーションが含まれています。

SQLの構造と入力データを分けるアイボリー背景のフラットな概念イラスト

目次

スポンサーリンク

値とSQLの構造を分けることが出発点

SQLインジェクション対策は、危険そうな文字を削除する処理を増やすことではありません。アプリケーションが決めたSQLの構造へ、入力データが入り込まないようにすることが基本です。検索画面だけでなく、管理画面、CSV取り込み、定期処理も対象になります。

本記事は2026年10月18日に確認したOWASPとPHPの一次資料を踏まえた恒久的な実装解説です。特定製品の新しい脆弱性や侵害を報じるものではありません。以下の会員一覧の例は仮想のもので、確認手順と運用上の判断は本サイトの提案です。実際のライブラリとDBドライバーの仕様を確認して適用してください。

プレースホルダーは値を渡すために使う

たとえば会員一覧を検索するとき、検索語を文字列結合してSQLへ差し込むのではなく、クエリのひな型を用意して値をパラメーターとして渡します。PHPのPDOであればprepareとexecuteを使う方式があります。重要なのはAPIの名前ではなく、値がSQLの命令部分として扱われない経路を維持することです。

入力が数値に見えるかどうかだけを防御の基準にしません。数値なら適切な型と範囲を検証し、そのうえでパラメーターへ渡します。表示時のHTMLエスケープはブラウザー向けの対策であり、SQLの安全な組み立てを代替しません。

PDOにはドライバーやプリペアドステートメントのエミュレーションに関する違いがあります。同じ名前のパラメーターを何度も使えるなどの前提を、別の環境へそのまま持ち込まないことが大切です。採用環境で動作する標準的な書き方へそろえ、設定の変更もレビュー対象にします。

基本となる資料:OWASP SQL Injection Prevention Cheat Sheet。

スポンサーリンク

列名や並べ替え方向は固定の対応表にする

値を安全に渡せても、ORDER BYの列名を要求パラメーターから直接結合すれば、別の境界に危険が残ります。プレースホルダーは、テーブル名、列名、SQLキーワードを自由に差し替えるための仕組みではありません。

本サイトは画面で選べる並べ替え項目を、アプリケーション内の固定のSQL断片へ対応させる方式を勧めます。たとえば「新着順」は作成日時、「名前順」は表示名の列へ対応させ、未知のキーは拒否または安全な既定値にします。列名らしい正規表現に一致しただけで、任意の識別子を許可しないでください。

昇順・降順も、選択肢から固定したASCまたはDESCへ変換します。管理者専用の検索であっても例外にしません。アカウントが侵害された場合や将来権限が変わった場合に、入力の自由度がそのままDB操作の自由度へ広がるのを防ぐためです。

IN検索とLIKE検索は意味の境界も扱う

複数IDをIN条件へ渡す場合、一つのプレースホルダーにカンマ区切りの一覧を入れるだけでは、複数の値を束縛したことにはなりません。採用するクエリビルダーの配列対応を使うか、値の個数に対応したプレースホルダーを作って各値を束縛します。件数の上限と空配列の扱いも決めます。

LIKE検索では、パラメーター化によりSQL構造への混入を防ぐ問題と、ワイルドカードが検索条件を広げる問題を分けます。利用者が入力したパーセントやアンダースコアを文字として検索したいなら、DBの仕様に沿った別の処理が必要です。これは単純に「SQLインジェクションが残っている」という話とは異なります。

大きな検索条件や無制限の取得件数による負荷も、パラメーター化だけでは防げません。安全に構文を組み立てた後で、検索の権限、対象範囲、件数、実行時間を制御します。一つのAPIを使っただけで、検索機能全体の安全性が保証されるわけではありません。

スポンサーリンク

ORMと保存済みデータを安全だと決め付けない

ORMを導入していても、生SQL、独自スコープ、動的な集計、拡張ライブラリを通じて文字列結合が入り込むことがあります。レビューではORMを使っているかだけで終わらず、最終的にクエリを作る箇所とパラメーターを渡す箇所を追います。

いったんDBへ保存した値も、後でSQLへ結合してよいとは限りません。プロフィールの入力値が夜間バッチや管理画面の集計に使われる場合を想定し、保存時と再利用時の両方の経路を確認します。取り込み元が社内CSVや外部サービスであっても、命令として信用しない扱いを維持します。

ストアドプロシージャも、内部で動的SQLを危険な形で連結すれば万能ではありません。クエリを組み立てる責任がDB側に移っただけなのか、実際に値と構造が分離されているのかを区別します。生成AIが提案したコードでも同じ基準で判断できます。

認可とDBの最小権限で影響を広げない

安全なクエリでも、他人の会員IDを指定すれば他人の記録を読める実装なら認可の問題が残ります。検索対象の所有者や組織は、信頼できる認証情報から決め、外部入力だけで切り替えられないようにします。パラメーター化は、利用者がその情報へアクセスしてよいかを判断しません。

実行用のDBアカウントには必要な操作だけを与えます。通常の参照機能が使う資格情報へ、構造変更や不要な管理操作まで与えないことが基本です。マイグレーション用と通常運用用の役割を分ける場合は、デプロイ後に高権限の設定が残らない手順も作ります。

WAFやエラーメッセージの抑制は補助になりますが、クエリ構築の修正を先送りする理由にはなりません。詳細なSQLや接続情報を利用者へ返さず、運用側にもパスワードや個人情報を含むクエリ全文を不用意に保存しないようにします。

並べ替え機能のレビューを具体化する

仮想の会員管理画面に「新着順」「名前順」「利用回数順」の選択肢があるとします。検索語だけをパラメーター化しても、並べ替えの列名をそのままSQLへ結合していれば、構造を制御する入力が残ります。検索フォームの一つの項目だけを見るのではなく、クエリへ影響する値をすべて追うことが重要です。

本サイトの提案は、画面で使う短いキーと、アプリ内で固定した列名を対応付けることです。要求のキーが既知かを確認し、対応先の固定値だけをSQLへ組み込みます。入力値を一度エスケープしたので自由な列名として使ってよい、という設計にはしません。新しい並べ替え項目を追加するときは、重い集計を起こさないかも合わせてレビューします。

ページ送りの件数や開始位置は型と範囲を検証し、DBやドライバーが対応する方法で渡します。最大件数を超えた値や負の値、極端なページ番号を受けたときの扱いを決めます。SQLの構文として安全な値でも、大量取得や高負荷を許可してよいわけではありません。

検索結果の試験には、通常の名前と同じように引用符を含む名前や日本語を用意します。攻撃に見える値を全部拒否して合格にするのではなく、正当な文字列を正しく検索できることも確認します。値とSQLを分ける設計は、安全性と国際化を両立しやすくする点でも有用です。

入力や経路扱い方テストの着眼点
氏名と検索語値としてパラメーターへ渡す引用符や日本語を正しく扱う
並べ替え列固定した対応表から選ぶ未知のキーがSQLへ入らない
複数の対象ID個数に応じて値を束縛する空配列と上限を制御する
CSVから保存した値再利用時も値として渡すバッチで構造に混ぜない

生成コードを取り込むときの確認単位

生成AIや外部のサンプルからコードを取り込む場合、短い断片だけでは接続設定、権限、例外処理が分かりません。安全そうなprepareの呼び出しがあっても、その前に文字列結合で完成した条件を渡していないかを見ます。クエリのひな型と値がどの時点で分かれるかを説明できることが確認の基準になります。

レビュー結果は、同じ処理を別画面へコピーする前に共通のクエリ構築へ戻します。ただし、共通化した関数へSQL断片を自由に渡せる設計にすると、危険な自由度を隠すだけになります。入力の種類、許可する構造、認可の責任を関数の境界で明確にしてください。

スポンサーリンク

改修漏れを減らすための棚卸し

検索すべき箇所は画面の検索処理だけではありません。DBへ渡す文字列を作る共通関数、帳票生成、エクスポート、管理用の一括更新、定期処理を一覧にします。古いコードが使われていないと判断する場合は、呼び出し元と実行予定を確認し、残すなら同じ安全基準を適用します。

機械的な検査は候補を探す補助として使います。文字列結合があるだけで即座に危険と決め付けず、それが固定のSQL構造か外部入力かを追います。逆に、検査がprepareという文字を見つけたことだけで安全と判定しないようにします。レビューの記録には、値の出所と束縛する場所を残します。

改修後に取得件数や処理時間が変わった場合は、安全対策だから仕方ないとせず、クエリの意味が変わっていないかを確かめます。認可の条件と検索条件がともに維持されることを、複数組織のテストデータで確認してください。

実際のデータ境界を確かめるテストへ進む

テスト環境に複数の組織と会員を用意し、引用符、日本語、空文字、長すぎる文字列、不正な並べ替えキーを入力します。エラーが出ないことだけでなく、検索結果の範囲が期待どおりであること、他組織のデータが混ざらないことを確認します。

監視や検証のために本番環境へ強い攻撃文字列を無計画に投げる必要はありません。自分が管理する隔離環境で、クエリのひな型とパラメーターが分かれて渡されていることを確認し、保存済みの入力が使われるバッチも試験します。

改修の優先順位は、外部入力を結合する箇所、動的な識別子、生SQLを使う例外経路、権限の広い接続の順に整理すると判断しやすくなります。文字の置換を積み重ねるよりも、安全なクエリ構築の規約を一つにそろえ、レビューとテストで維持できる状態を目指してください。

スポンサーリンク

参考資料

以下は本文の作成時に直接確認した一次資料です。確認日は2026年10月18日です。設定や提供条件は、利用環境に対応した資料も確認してください。

この記事を書いた人

Ryohei

Webエンジニア / アプリ開発者 / 技術ブログ運営者

福岡のWeb制作会社に勤務するWebエンジニアです。10年以上にわたりWeb制作・開発に携わり、これまでに100以上のWordPressサイトの構築・保守を担当してきました。Webサイト制作に加え、アプリ開発やAIを活用した開発にも取り組み、近年はWebセキュリティにも注力しています。

2015年から技術メディア「Into the Program」を運営し、実務や開発で得た知識をもとに、プログラミングの実装方法やWebサイトの運用・セキュリティ情報を発信しています。

主な分野
WordPress / PHP / JavaScript / アプリ開発 / Webサイトの運用・セキュリティ対策
資格・試験合格
情報セキュリティマネジメント試験
基本情報技術者試験
AWS認定ソリューションアーキテクト アソシエイト
メディア運営
2015年〜

記事の作成・更新について

セキュリティ記事は、ベンダーの公式アドバイザリやCVE・JVNなどの一次情報を参照し、出典と情報確認日を記載します。実環境での検証を行った場合は、その環境と確認範囲を明示します。重要な追加情報や誤りを把握した場合は、内容を確認して追記・訂正します。

スポンサーリンク

関連する記事

おすすめの書籍