Web アプリのセキュリティ

PHP と Node.js のサーバーを題材に、基本の脆弱性の仕組みと対策を学ぶ。後半では 2026 年 10 月時点の最近の事例を取り上げ、仕組みの理解を対策の判断につなげる。

この教材で学ぶ

学習記録を読み込んでいる

1 回は約 10 分。段階 1 の短い問いで温めてから、段階 2・3 の問いを考える

概念 23

段階 1 のカードがすべて定着した概念には段階 2 を勧める。勧めるだけで、どの段階も選べる

  • SQL インジェクション

    入力を文字列連結で SQL に埋め込むと、入力の一部が SQL の構文として解釈され、データを盗まれたり書き換えられたりする。プリペアドステートメントで値を構文と分けて渡す。

  • XSS (クロスサイトスクリプティング)

    利用者の入力をそのまま HTML に出すと、攻撃者のスクリプトが他の利用者のブラウザで動く。出力先に合わせたエスケープが基本で、CSP を重ねて被害を抑える。

  • コマンドインジェクション

    入力を含む文字列をシェルに渡すと、; や | で別のコマンドをつなげられる。シェルを介さずに引数を配列で渡す API を使う。

  • パストラバーサル

    入力をファイルパスに使うと、../ で公開ディレクトリの外のファイルを読まれる。パスを解決してから、許可したディレクトリの配下にあるかを確かめる。

  • SSRF

    利用者が指定した URL へサーバーにリクエストさせる機能を悪用され、外から届かない内部のネットワークやクラウドのメタデータに届いてしまう。宛先を許可リストで絞り、名前解決後の IP アドレスで判断する。

  • 安全でないデシリアライズ

    PHP の unserialize に信頼できない入力を渡すと、任意のクラスのオブジェクトが作られ、マジックメソッドを通じて意図しない処理が動く。外部とのデータ交換には JSON を使う。

  • プロトタイプ汚染

    Node.js でオブジェクトを再帰的にマージするとき、__proto__ のようなキーを通すと Object.prototype が書き換わり、アプリ全体のオブジェクトに影響する。危険なキーを弾くか、Map や Object.create(null) を使う。

  • CSRF

    ブラウザがリクエストに Cookie を自動で付けることを悪用し、ログイン中の利用者に意図しない操作をさせる。CSRF トークンや SameSite 属性で防ぐ。

  • セッション固定

    攻撃者が用意したセッション ID を被害者に使わせ、被害者のログイン後にその ID で乗っ取る。ログインの成功時にセッション ID を作り直して防ぐ。

  • パスワードの保存

    パスワードは平文でも高速なハッシュでもなく、ソルト付きの遅いハッシュ (bcrypt や Argon2) で保存する。PHP では password_hash と password_verify を使う。

  • メモリ破壊と use-after-free

    C や C++ で書かれた処理系やライブラリの欠陥で、範囲外への書き込みや解放済みメモリの使用が起きると、攻撃者がコードを実行できる場合がある。アプリのコードが正しくても起きる。

  • サポートが終わったランタイム

    サポート期間 (EOL) を過ぎた PHP や Node.js の版には、脆弱性が見つかっても公式の修正が出ない。サポート中の版へ計画的に移る。

  • サプライチェーン攻撃

    アプリが依存するパッケージや、その公開の経路に悪意のあるコードを紛れ込ませる攻撃。自分のコードを確かめても防げない。

  • install スクリプト

    npm のパッケージは preinstall や postinstall などのフックで、入れた時点に任意のコマンドを動かせる。npm は既定で依存のスクリプトを動かすので、不要なら ignore-scripts で止める。pnpm は v10 から依存のスクリプトを既定で動かさず、許可したものだけを動かす。

  • lockfile

    依存関係の版と中身のハッシュを、推移的な依存まで固定するファイル。CI では lockfile どおりに入れ、更新時は差分を確かめる。

  • 依存関係の取り違え (dependency confusion)

    社内パッケージと同じ名前のパッケージを公開レジストリに置き、パッケージマネージャーにそちらを選ばせる攻撃。スコープを付け、社内のスコープは社内レジストリだけから引く。

  • CSP (Content Security Policy)

    ページが読み込んで実行してよいスクリプトの出どころを、レスポンスヘッダーでブラウザに伝える仕組み。XSS が起きたときの被害を抑える多層防御で、エスケープの代わりにはならない。

  • Cookie のセキュリティ属性

    HttpOnly は JavaScript から Cookie を読めなくし、Secure は HTTPS のときだけ送らせ、SameSite は他サイトからのリクエストに Cookie を付けるかを決める。

  • 新しい版の冷却期間

    公開されたばかりの版をすぐには入れず、一定時間待ってから入れる運用。悪意のある版は公開から数時間で見つかり取り下げられることが多く、待つだけで避けられる場合がある。

  • 公開トークンの保護

    npm の公開トークンを盗まれると、そのアカウントが持つすべてのパッケージに悪意のある版を出される。長期のトークンを減らし、CI からは OIDC を使う Trusted Publishing で公開する。

  • 事例: PHP2Shell

    2026 年 10 月 21 日に修正された PHP 本体の 2 つの欠陥。メモリ不足時の処理でのメモリ破壊と、リクエストをまたいで残る状態の use-after-free で、認証なしにリモートからコードを実行されうる。8.5.12・8.4.27・8.3.36・8.2.35 で修正された。

  • 事例: Node.js の 2026 年 10 月のセキュリティリリース

    2026 年 10 月 21 日のリリースで 10 件の脆弱性を修正した (High 4 件)。node:zlib の Brotli 展開での範囲外書き込みや、TLS で IP アドレスへの接続を、その IP アドレス向けでない証明書で認証できてしまう欠陥を含む。修正は 22・24・26 系だけで、EOL の 20 系以前には出ない。

  • 事例: npm のサプライチェーン攻撃 (axios、ChainDrop)

    2026 年 3 月、乗っ取られた公開者アカウントから axios に悪意のある版 (1.14.1 と 0.30.4) が出され、追加された依存が postinstall フックで遠隔操作ツールを入れるスクリプトを動かすようにした。ChainDrop は盗んだ公開トークンで他のパッケージにも preinstall フックを仕込み、400 以上のパッケージへ自分を広げた。

段階 2・3 の論点 9

復習のたびに同じ論点を別の角度から問う。答えられなければ段階 1 の問いに分けて出し直す

  • 段階 2 つなげる · 問い 3XSS と CSRF は、攻撃者が何を悪用する点で違う?
  • 段階 2 つなげる · 問い 3SQL インジェクションとコマンドインジェクションに共通する原因は?
  • 段階 2 つなげる · 問い 2PHP の unserialize の危険と、Node.js のプロトタイプ汚染は、何が似ていて何が違う?
  • 段階 2 つなげる · 問い 2パスワードの保存に SHA-256 を 1 回かけるだけでは不十分なのはなぜ?
  • 段階 3 使う · 問い 2利用者が入れた画像の URL をサーバーが取りに行き、サムネイルを作る機能を作る。何に気をつける?
  • 段階 3 使う · 問い 3依存パッケージの新しい版が出た翌日に `pnpm update` する運用に、どんな危険がある?
  • 段階 2 つなげる · 問い 3PHP2Shell では、アプリのコードを直しても防げないのはなぜ?
  • 段階 3 使う · 問い 3社内ツールがまだ Node.js 20 で動いている。今回のリリースを受けて何を判断する?
  • 段階 3 使う · 問い 3install スクリプトを止める、版を固定する、公開トークンを守る、はそれぞれ何を防ぐ?