Dance with Agents

Webアプリの主要セキュリティリスク一覧——傾向と対策

実践

Webアプリを公開したら、その日から始まることで書いたとおり、公開するというのは世界中からアクセスできる状態にすることです。この記事では、そこで実際に向き合うことになる代表的なリスクを一覧にします。

全部を一度に理解する必要はありません。 まずこの一覧で「こういう種類の問題がある」という地図を持ち、気になったものから個別記事を読む、という使い方を想定しています。

一覧

リスク 一言でいうと 主に狙われるもの
クロスサイトスクリプティング(XSS) 悪意のあるスクリプトを、他人のブラウザで動かされる 機密性・完全性
認証・認可の不備 ログインの仕組み自体や、「誰に何を見せるか」の線引きが甘い 機密性
秘密情報の漏洩 APIキーやパスワードが、見えるはずのない場所に現れてしまう 機密性
DDoS・過剰アクセス 大量のアクセスでサービスを止められる、または高額請求を招かれる 可用性
依存ライブラリの脆弱性 自分では書いていない部品(ライブラリ)経由で穴が開く 機密性・完全性
インジェクション 入力欄経由で、想定外の命令をデータベースなどに実行される 機密性・完全性
CSRF・CORSの設定ミス 別サイトを経由して、本人になりすました操作をされる 完全性

「主に狙われるもの」は、『Webアプリを公開したら、その日から始まること』で書いた機密性・完全性・可用性の3観点です。狙われる観点が分かると、対策の方向性も見えてきます。

個別に見ていく

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

ユーザーが入力した文字列を、そのままページに表示する作りになっていると起きます。攻撃者は、ただの文章のふりをしたスクリプトを入力欄に送り込みます。それが他のユーザーの画面でそのまま実行されると、ログイン情報を盗まれたり、勝手な操作をされたりします。

対策の要点:ユーザーの入力をそのままHTMLとして扱わない(多くのフレームワークは初期状態でエスケープ処理をしてくれます)。dangerouslySetInnerHTMLのような「そのままHTMLとして差し込む」機能は、使う理由が明確なときだけに絞る。

認証・認可の不備

「ログインできるか」(認証)と「ログインした人が、これを見てよいか」(認可)は別の話です。ログインの仕組みは実装したのに、URLの番号を変えるだけで他人のデータが見えてしまう、という事故がよく起きます。これはIDOR(Insecure Direct Object Reference、安全でない直接オブジェクト参照)と呼ばれる典型的な穴で、「自分の注文は3番でした。では4番を開いたら?」で他人の注文が見えてしまう、というようなものです。

対策の要点:データを返す前に、必ず「これを見る権限が、本当にこの人にあるか」をサーバー側で確認する。ブラウザ側の表示を隠すだけでは対策になりません(隠しているのは画面だけで、その裏のAPIには誰でも直接アクセスできてしまうため)。

秘密情報の漏洩

APIキーやデータベースの接続情報が、意図せず外部から見える場所に置かれてしまうケースです。これはすでに2本、具体的な記事があります。

対策の要点:秘密情報はコードに直接書かず環境変数にする。ブラウザに配ってよい値かどうかを、登録する前に必ず確認する。

DDoS・過剰アクセスと「気づいたら高額請求」

DDoS(Distributed Denial of Service、分散型サービス拒否攻撃)は、大量のアクセスを送りつけてサービスを止める攻撃です。Vercelのようなサービスは大規模な攻撃への基礎的な防御を備えていますが、非エンジニアがそれ以上に注意したいのは別の形の被害です。

従量課金のAPIを裏で呼んでいる場合、大量アクセスはそのまま高額請求に直結します。 たとえば、AIモデルのAPIを呼び出す機能を公開している場合、誰かがそのエンドポイントを繰り返し叩けば、攻撃者はサービスを止めずとも、持ち主に高額な請求を負わせることができます。サービスは動き続けているので、被害に気づくのが請求書を見たときになりがちです。

対策の要点:呼び出し回数に上限を設ける仕組み(レート制限)を入れる。誰でも呼べるAPIエンドポイントを公開しない。使用量に上限やアラートを設定できるサービスなら、先に設定しておく。

依存ライブラリの脆弱性

Webアプリは、自分で書いた部分だけでなく、大量の外部ライブラリ(npmのパッケージなど)の上に成り立っています。自分では1行も書いていない部分にも、脆弱性は存在します。 悪意のあるパッケージが紛れ込むサプライチェーン攻撃(ソフトウェアの調達経路そのものを狙う攻撃)も知られています。

対策の要点:ライブラリは定期的に更新する。使っていないライブラリは減らす(減らすほど、影響を受ける範囲も減ります)。名前が似ているだけの怪しいパッケージを、確認せずに追加しない。

インジェクション

入力欄に渡された文字列を、データベースへの命令文にそのまま組み込んでしまうと起きます。代表的なものがSQLインジェクションで、名前を入力する欄に命令文の断片を混ぜて送ることで、想定外のデータベース操作を引き起こされます。

対策の要点:多くの場合、ORM(データベース操作をコードから安全に行うための道具)や、標準的なライブラリの用意された書き方を使っていれば、これは自動的に防がれます。「文字列をつなぎ合わせて命令文を組み立てる」書き方だけは避ける、という意識を持っておくと安心です。

CSRF・CORSの設定ミス

CSRF(Cross-Site Request Forgery、クロスサイトリクエストフォージェリ)は、ログイン中のユーザーに別サイトを踏ませて、本人の意図しない操作を実行させる攻撃です。CORS(Cross-Origin Resource Sharing、オリジン間リソース共有)は、どのサイトからのアクセスを許可するかを決める仕組みで、これを緩めすぎる(どこからでも許可する設定にする)と、想定していないサイトから自分のAPIを呼ばれてしまいます。

対策の要点:多くのフレームワークには標準の防御が組み込まれているので、まずはそれを無効化しないこと。CORSの設定は「困ったから全部許可」にせず、許可する相手を絞る。

この一覧の使い方

  • まず気になるリスクの「対策の要点」だけでも実践する
  • エージェントに「このリスクへの対策はできているか確認して」と、ここに挙げた名前をそのまま伝えると、具体的な点検につながりやすくなります
  • 対策の実装そのものは、多くの場合エージェントに頼めます。読者に必要なのは、コードを自分で直す技術ではなく、ここに挙げた名前を知っていて、具体的に点検を頼めることです

セキュリティの記事

セキュリティのページへ →