A02 セキュリティ設定の不備
コードが正しくても、動かす環境の既定値と手で足した設定で穴が開く。直し方は1つずつの修正でなく、固めた設定を毎回同じに作り直せる仕組みにすることだ。
要点
成立の条件
設定の不備は、本番が定義から外れたときに生まれる。手で直した本番、検証にしか無い修正、更新で増えた新しい既定値。
- 既定値が開いている 既定のアカウント、サンプルのアプリ、ディレクトリの一覧、詳しいエラー、共有が公開になった保管庫。
- 要らない機能が入っている 使わないポート、サービス、ページ、アカウント、試験の枠組み、権限[1]。
- 守りの設定が付いていない 応答のヘッダ、Cookie の属性、CORS の許可、更新で入った新しい守りの機能を有効にしていない。後方互換を優先して安全でない設定を残すことも OWASP は挙げる[1]。
型1 既定とデバッグの残り
OWASP の例は、本番に残したサンプルのアプリの管理画面に、変えていない既定のパスワードで入られるもの、ディレクトリの一覧からコンパイル済みのクラスを取られて解析されるもの、スタックトレースが部品の版を漏らすものだ[1]。
悪い例。架空のアプリのエラー処理
app.use((err, req, res, next) => {
res.status(500).json({ message: err.message, stack: err.stack });
});
直した例。中身は記録にだけ残し、利用者には照合の番号を返す
app.use((err, req, res, next) => {
const ref = crypto.randomUUID();
logger.error({ ref, err });
res.status(500).json({ message: 'internal error', ref });
});
- OWASP は、詳しすぎるエラーを止める中央の設定を、予備として置くよう求める[1]。エラー処理のチートシートも、技術の構成と版が偵察の材料になると書く[4]。
- 例外の扱いそのものの誤りは A10 が扱う。A02 で見るのは、本番の設定で詳しい出力が有効になっていないか。
- デバッグの有効化は、コードでなく環境変数か設定の定義で切り替え、本番の定義で固定する。CWE-489 Active Debug Code。
型2 XML の外部実体参照 XXE
XML のパーサーが文書型宣言の外部実体を解決すると、文書の中から手元のファイルや内側のURLを読ませられる。2017年版では独立したカテゴリで、2021年版から設定の不備に入った[9]。パーサーの既定値の問題なので、ここに入る。
悪い例。Java の DOM パーサーを既定のまま使う
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document doc = dbf.newDocumentBuilder().parse(input);
直した例。文書型宣言そのものを拒む
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setXIncludeAware(false);
Document doc = dbf.newDocumentBuilder().parse(input);
- 最も確実なのは文書型宣言を拒むこと。内部の DTD が要るときは、外部の参照で例外を投げる解決器を置き、外部の一般実体と引数実体の機能を切る[5]。
- 既定値は言語とライブラリと版で違う。libxml2 は 2.9 から外部実体の置き換えを既定で切ったが、PHP の
LIBXML_NOENTなどの指定で戻る[5]。使っているパーサーごとに確かめる。 - 入れ子の実体で膨らませる攻撃は CWE-776。文書型宣言を拒めば、こちらも止まる。
- XML は API の本文だけでなく、SVG、Office の文書、SAML、設定ファイルの取り込みにも来る。
型3 クラウドの保管庫の公開と静的な鍵
OWASP の例には、クラウドの事業者の共有の権限が既定でインターネットに開いていて、保管したデータに誰でも届くものがある[1]。2025年版は、コードや設定やパイプラインに静的な鍵を埋めず、基盤のID連携と短命の資格情報を使うよう求める項目を新しく足した[1]。
悪い例。架空の保管庫を誰にでも読ませる方針
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-reports/*"
}
- 保管庫は、アカウントの単位で公開を止める設定を入れ、読ませる相手は役割で指定する。AWS は S3 のパブリックアクセスのブロックを、アカウントと保管庫の単位で用意している[7]。
- 公開して配るものは、保管庫を直接開けず、配信の仕組みの後ろに置く。公開する保管庫と非公開の保管庫を分ける。
- 秘密の管理は、置き場所を1つにし、使う側には実行時に渡し、回転できる形にする[6]。
型4 応答のヘッダと Cookie と CORS
守りの指示を端末へ送らないか、送っても弱い値で送る。CORS では、要求の Origin をそのまま返し、資格情報付きで許すと、どのサイトの JavaScript からも利用者の権限でAPIを読める。
悪い例
res.set('Access-Control-Allow-Origin', req.get('Origin'));
res.set('Access-Control-Allow-Credentials', 'true');
直した例。許すオリジンを一覧で決める
const ALLOWED_ORIGINS = new Set(['https://app.example.com']);
const origin = req.get('Origin');
if (ALLOWED_ORIGINS.has(origin)) {
res.set('Access-Control-Allow-Origin', origin);
res.set('Access-Control-Allow-Credentials', 'true');
res.set('Vary', 'Origin'); // 中継のキャッシュで他のオリジンへの応答と混ざらないように
}
- 資格情報付きの要求に
*は使えない決まりがあるため、Origin を写して返す実装が生まれる[10]。写す前に一覧と完全一致で比べる。前方一致や後方一致の比較は別のドメインに抜けられる。 - OWASP は CORS の利用そのものを最小にするよう求める[1]。同じオリジンに置ければ要らない。
| 設定 | 推奨の値 | 欠けたとき |
|---|---|---|
| Strict-Transport-Security | max-age=63072000; includeSubDomains; preload | 初回や手入力で HTTP に落とされる。A04 |
| Content-Security-Policy | 少なくとも frame-ancestors で枠に入れてよい先を絞る | 他サイトの枠に入れられ、クリックを盗まれる |
| X-Content-Type-Options | nosniff | 端末が中身から型を推測し、スクリプトとして扱う |
| Referrer-Policy | strict-origin-when-cross-origin | URLの中の値が他サイトへ渡る |
| Cookie の Secure | 付ける | HTTP の通信で Cookie が流れる。CWE-614 |
| Cookie の HttpOnly | セッションの Cookie に付ける | スクリプトから読まれる。CWE-1004 |
| X-Powered-By などの版の表示 | 出さない | 既知の脆弱性を持つ版を特定される |
値は HTTP ヘッダのチートシートの推奨[3]。Cookie の属性は RFC 6265 が定める[11]。
守り方
IPA の「安全なウェブサイトの作り方」は、第2章でウェブサーバの運用に関する対策を、アプリの実装と分けて扱っている[12]。
診断で見る所
許可を得た範囲で行う。範囲の決め方は 診断の許可と範囲 にある。手順は WSTG の構成と配備の管理の試験と、エラー処理の試験が詳しい[2]。要件は ASVS 5.0 の V13 Configuration にある[13]。
| 観点 | 見る所 | 当たりの兆候 |
|---|---|---|
| 残り物 | サンプル、管理画面、試験用の経路、ディレクトリの一覧、.git、バックアップ | 認証なしで開く。既定のパスワードで入れる |
| エラー | 型の違う値、欠けた引数、長すぎる値を送る | スタックトレース、SQL の文、部品の名前と版が返る |
| XML | XML、SVG、Office の文書、SAML を受け取る所。コードではパーサーの生成の箇所 | 文書型宣言が拒まれない。パーサーの機能の設定が無い |
| ヘッダと Cookie | 応答のヘッダと Set-Cookie の属性 | 上の表の値が無いか弱い |
| CORS | Origin を替えて送り、許可のヘッダを見る | 任意の Origin が資格情報付きで許される。null が許される |
| クラウド | 保管庫の方針、公開の設定、役割の権限、コードと CI の変数の中の鍵 | 誰でも読める。静的な鍵が残っている |
| 環境の差 | 本番と定義を突き合わせる | 定義に無い設定が本番にある |
関連するCWE
A02 に対応する16のうち、Webアプリでよく当たるもの[1]。
| CWE | 名前 | この頁の型 |
|---|---|---|
| CWE-16 | Configuration | 全体 |
| CWE-489 | Active Debug Code | 型1 |
| CWE-611 | Improper Restriction of XML External Entity Reference | 型2 |
| CWE-776 | Improper Restriction of Recursive Entity References in DTDs | 型2 |
| CWE-260 | Password in Configuration File | 型3 |
| CWE-526 | Exposure of Sensitive Information Through Environmental Variables | 型3 |
| CWE-547 | Use of Hard-coded, Security-relevant Constants | 型3 |
| CWE-942 | Permissive Cross-domain Policy with Untrusted Domains | 型4 |
| CWE-614 | Sensitive Cookie in HTTPS Session Without Secure Attribute | 型4 |
| CWE-1004 | Sensitive Cookie Without HttpOnly Flag | 型4 |
| CWE-315 | Cleartext Storage of Sensitive Information in a Cookie | 型4 |
参照
- A02:2025 Security Misconfiguration OWASP Top 10:2025
- Configuration and Deployment Management Testing OWASP Web Security Testing Guide
- HTTP Security Response Headers Cheat Sheet OWASP Cheat Sheet Series
- Error Handling Cheat Sheet OWASP Cheat Sheet Series
- XML External Entity Prevention Cheat Sheet OWASP Cheat Sheet Series
- Secrets Management Cheat Sheet OWASP Cheat Sheet Series
- Blocking public access to your Amazon S3 storage Amazon Web Services
- SP 800-123 Guide to General Server Security NIST
- OWASP Top 10:2021 日本語版 OWASP Foundation
- Fetch Standard, CORS protocol and credentials WHATWG
- RFC 6265 HTTP State Management Mechanism IETF
- 安全なウェブサイトの作り方 改訂第7版 IPA 情報処理推進機構
- V13 Configuration OWASP Application Security Verification Standard 5.0