0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PHP開発者必見:今押さえたい脆弱性対策と堅牢設計の基本

0
Posted at

はじめに

2026年になっても、サーバーサイドプログラミング言語が判別できるWebサイトの71.7%でPHPが使われています(W3Techs調べ、2026年4月7日時点)。 一方で、現場で向き合うPHPは最新の理想的なコードばかりではなく、長年の保守や改修で積み重なった"レガシーな実装"であることも多いはずです。そうしたコードは、仕様変更や継ぎ足しの結果として、知らないうちに脆弱性を抱えやすくなります。

さらに2026年は、AIの普及によって攻撃の作り方そのものが変わっています。Cloudflareはこの状況を「工業化された脅威」と表現し、攻撃者がMOE(少ない労力でどれだけ成果を出せるか)を重視していると述べています。Verizonの2025 DBIRでも、脆弱性悪用の増加やサードパーティ経由の侵害拡大が報告されており、従来以上に"守れる設計"が重要になっています。

本記事では、PHP開発において2026年時点で特に意識したい脆弱性対策と、堅牢な設計の考え方を4つに絞って整理します。単なるチェックリストではなく、保守・改修の多い現場でも活かせる視点としてまとめてみました。

1. 【対策1】アクセス制御の不備(IDOR):ログイン済みでも安心できない理由

PHPでWebアプリを作っていると、つい「ログインしているユーザーだから大丈夫」と考えてしまうことがあります。
でも、ここで気をつけたいのが 認証認可 は別物だという点です。

認証は「その人が誰か」を確認すること、認可は「その人がそのデータや機能に触っていいか」を確認することです。
つまり、ログイン済みであることは、あくまでスタート地点なんです。

ここで起こりやすいのが、IDOR(Insecure Direct Object Reference) のような問題です。たとえばURLやリクエストパラメータのIDを書き換えるだけで、他ユーザーのデータが見えたり更新できたりするケースです。
APIでは特にこの種の問題が起きやすく、BOLA(Broken Object Level Authorization) として扱われることもあります。

また、「UUIDを使っているから大丈夫」と思いたくなる場面もありますが、ここも少し注意が必要です。
UUIDは連番IDより推測しにくいという意味では有効ですが、認可チェックの代わりにはなりません。何らかの形で識別子が漏れれば、それだけでアクセスできてしまう可能性があるからです。

結局のところ大事なのは、リクエストごとに、そのユーザーが本当にそのリソースを扱ってよいか確認すること です。
たとえば「この注文はこのユーザーのものか」「このレコードを更新する権限があるか」といったチェックを、取得・更新・削除それぞれで丁寧に入れていく必要があります。

アクセス制御の不備は、難しい実装というより、うっかり抜けやすいポイント が問題です。
だからこそPHP開発では、「ログイン済みだからOK」で終わらせず、認可を都度確認する ことを基本にしておくのが大切です。

2. 【対策2】SQLインジェクション:文字列連結を避けるだけでもかなり変わる

SQLインジェクションは古典的な脆弱性として知られていますが、いまでも油断できない代表例のひとつです。
原因はシンプルで、SQLの命令部分とユーザー入力を文字列としてつなげてしまうこと にあります。

PHPでは、PDOなどを使って プリペアドステートメント を利用するのが基本です。値をバインドして処理することで、入力値をSQLの一部として解釈されにくくできます。
そのため、まずは「値を直接連結しない」を徹底するだけでも大きな効果があります。

ただ、実務では少しやっかいな場面もあります。
たとえば、テーブル名、カラム名、ORDER BY の並び順 のような動的な要素です。これらはSQLの構文そのものに関わるため、通常のプレースホルダでは扱えません。ここで安易に文字列連結を使ってしまうと、脆弱性の入り口になりやすくなります。

こういう場面で大事なのは、入力値をそのまま使わないこと です。
よくある対策は、あらかじめ使ってよい値だけを決めておく 許可リスト(Allow-list) 方式です。たとえば、ソート条件に使える値を namecreated_atupdated_at のように限定しておき、それ以外が来た場合はエラーにするか、安全なデフォルト値に置き換えます。

つまり、動的なSQLが必要なときほど、
「自由に受け取る」のではなく「使ってよい候補の中から選ばせる」
という考え方が大切になります。

SQLインジェクション対策は、特別なテクニックというより、文字列連結を避けること例外的に動的要素を扱う部分を厳しく制御すること の積み重ねです。
逆に言えば、1か所でも危ない組み立て方が残っていると、そこが攻撃の入口になる可能性があります。だからこそ、クエリ生成まわりは「たぶん大丈夫」で済ませず、丁寧に見直しておきたいポイントです。

3. 【対策3】クロスサイト・スクリプティング(XSS):出力時のエスケープを基本にする

XSSは、PHP開発でも今なお気をつけたい脆弱性のひとつです。
特にありがちなのが、「入力時にある程度整えているから大丈夫」と思ってしまうこと です。

ただ、XSS対策で本当に大事なのは、入力時に頑張ることよりも、出力時に適切なエスケープを行うこと です。
どんな場所に出力するのかによって、安全な扱い方は変わるため、出力先に応じて処理を使い分ける ことが基本になります。

たとえば、HTML本文に文字列を表示するなら htmlspecialchars() を使うのが基本です。
PHPでは、ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML5 を指定し、文字コードも UTF-8 で明示しておくと、より安全に扱いやすくなります。

URLに動的な値を含める場合、クエリパラメータの値はurlencode() 、URLパスを構成する文字列は rawurlencode() を使うと、用途に合った形式で安全にエンコードできます。
また、JavaScriptの中にPHPの値を直接書き込むような場面では、文字列連結で埋め込むのではなく、json_encode() を使ってJSONとして渡す 形にしておくほうが安全です。これによって、意図しない形でスクリプトとして解釈されるリスクを減らせます。

つまり、XSS対策では
「入力をきれいにする」よりも、
「どこに出すかに合わせて、出力時に安全な形へ変換する」
という考え方のほうが重要です。

さらに、サーバー側の実装だけに頼らず、ブラウザ側でも防御を重ねておくと安心です。
その代表が Content Security Policy(CSP) です。CSPを設定しておくことで、許可していないスクリプトの読み込みや実行を制限できるため、XSS対策の補強として役立ちます。

XSSは、「ちょっとした埋め込み方の違い」で起きやすい脆弱性です。
だからこそ、都度判断に頼るのではなく、HTMLならこれ、URLならこれ、JavaScriptならこれ という形で、安全な出力方法を実装の基本にしておくのが大切です。

4. 【対策4】ソフトウェア・サプライチェーンの不備:依存関係と実行環境も含めて守る

最近のPHP開発では、Composerを使ったパッケージ管理はほぼ前提になっています。
便利な反面、これは 自分たちのコード以外の要素も一緒に運用している ということでもあります。つまり、自作コードに問題がなくても、依存しているライブラリに脆弱性が見つかれば、アプリケーション全体に影響が及ぶ可能性があります。

そのため、依存関係の更新や監査は「余裕があればやること」ではなく、日常的に確認すべき項目です。
特に、脆弱性情報をチェックする仕組みや、危険なパッケージを早めに検知できる運用を入れておくと、問題の発見を後回しにしにくくなります。

あわせて意識したいのが、SBOM(ソフトウェア部品構成表) の考え方です。
どのライブラリを、どのバージョンで使っているのかを把握しやすくしておくことで、脆弱性対応や影響調査がしやすくなります。依存関係が増えやすい今の開発では、「何を使っているか分かる状態」を保つこと自体が大切です。

また、セキュリティはアプリケーションコードだけで完結するものではありません。
PHPそのものやWebサーバー、実行環境の設定によっては、コードに大きな問題がなくても深刻な影響につながることがあります。たとえば、設定不備がきっかけで情報漏えいやリモートコード実行のリスクが高まるケースもあるため、実行基盤の設定も含めて守る 視点が必要です。

最低限見直しておきたい項目としては、たとえば次のようなものがあります。

; 本番環境では詳細なエラー情報を画面に表示しない
display_errors = Off

; 不要な実行系関数を制限し、侵害時の被害拡大を抑えるための補助策として使う
; ただし、disable_functions だけで十分な防御になるわけではない
disable_functions = exec, system, shell_exec, passthru

; JavaScript からセッション Cookie を読み取りにくくする
session.cookie_httponly = On

こうした設定だけで万全になるわけではありませんが、「もしものときに被害を広げにくくする」 という意味で、基本として押さえておきたい部分です。

依存関係の管理も、実行環境の設定も、つい後回しになりやすいところです。
でも実際には、このあたりは コードレビューだけでは見落としやすい重要ポイント でもあります。だからこそPHP開発では、アプリの実装だけでなく、使っているパッケージと動かしている基盤まで含めて、継続的に見直していくことが大切です。

おわりに

2025年から2026年にかけて、セキュリティはAIを活用する攻撃と防御の両方が進む時代に入っています。攻撃側はAIを使って脆弱性やロジックの抜け漏れを効率よく探せるようになり、防御側もAIを活用したコードレビューや、XDR・SIEMによる異常検知などで対抗する流れが強まっています。

こうした状況では、対策を個人の経験や注意力だけに任せるのは難しくなっています。だからこそ、セキュリティを「気をつけるもの」で終わらせず、フレームワークの標準機能や共通処理、CI/CDのチェックなどを通して、開発の流れの中で自然に守れる形にしていくことが大切です。

PHPのセキュリティ対策も同じで、特別なことを一気にやるというより、危ない実装を残さないことの積み重ねが重要です。今回取り上げた、認可チェックの漏れ、SQLの文字列連結、出力時のエスケープ不足、依存パッケージや実行環境の放置は、どれも実務の中で起こりやすいポイントです。

しかも、こうした問題は「知らなかった」よりも、「そのうち直そうと思って残っていた」ことで起きやすいものでもあります。まずは今のプロジェクトの中で、見直せるところから一つずつ確認していくことが、結果として安全なシステムづくりにつながっていくと心に刻んでおきたいですね。

採用拡大中!

アシストエンジニアリングでは一緒に働くフロントエンド、バックエンドのエンジニア仲間を大募集しています!

少しでも興味ある方は、カジュアル面談からでもぜひお気軽にお話ししましょう!

お問い合わせはこちらから↓

https://official.assisteng.co.jp/contact/

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?