安全なWebサイトの作り方まとめ
はじめに
SCの試験にて「安全なWebサイトの作り方」から出てくる問題は数知れず多いので私的まとめとして記載。
試験が終わったらもうちょっと綺麗にまとめようかと思います。
1) SQLインジェクション(SQLi)
脆弱性の説明
外部入力を文字列連結でSQLに差し込むと、攻撃者にSQLを意図せず実行される。
発生しうる脅威
機微情報の窃取・改ざん・削除、認証回避、ストアド経由でOSコマンド実行など。
根本的解決
1.SQL文は必ずプレースホルダ(Prepared Statement/静的プレースホルダ推奨)で組み立てる。
SQLと値の結合をドライバに任せ、入力が文法として解釈されない状態にする。
2.文字列連結で組む場合は、DBエンジンのAPIでリテラル生成・適切なエスケープ(数値は型保証)。
' → ''、\ → \ などDBが規定する正しいエスケープで「値」としてだけ埋め込む。
3.外部パラメータにSQL文そのものを渡さない。
hidden等にSQLを直接持たせる設計は論外で、改変で任意実行される。
保険的対策
1.DB名やSQLを含むエラーをブラウザへ出さない(詳細はログへ)。
攻撃の成否やDB実装ヒントを与えない。
2.(暫定)WAFで典型的な攻撃パターンを遮断。
改修困難時に一時的に入口でブロックする。ただし誤判定・すり抜けに注意。
2) OSコマンド・インジェクション
脆弱性の説明
外部入力をシェル経由のコマンド引数に混ぜると任意コマンド実行。
発生しうる脅威
サーバ乗っ取り、踏み台化、情報窃取など。
根本的解決
1.シェル起動APIの利用を避け、言語/ライブラリの安全なAPIで処理する。
ファイル操作や圧縮等は標準関数を使い、外部コマンド自体を呼ばない。
2.やむを得ず使う場合は、引数をホワイトリスト検証し、許可済み値のみ許容。
; や | など制御記号を含めず、事前定義の選択肢から選ばせる。
保険的対策
1.実行ユーザ権限の最小化・chroot等で被害範囲を限定。
仮に実行されても権限不足で致命傷になりにくくする(一般論としての被害縮小)。
2.(暫定)WAFの導入・監視強化。
改修までの間、疑わしいリクエストを遮断・検知。
3) パス名パラメータ未チェック/ディレクトリ・トラバーサル
脆弱性の説明
外部入力でサーバ内の任意ファイルを参照させてしまう。
発生しうる脅威
非公開ファイルの漏えい、設定ファイル閲覧など。
根本的解決
1.参照対象はサーバ側固定のディレクトリ+安全なファイル名のみ(マッピング方式)。
ユーザ入力は「キー」にとどめ、実ファイル名はサーバ側テーブルで解決。
2.正規化後に .., /, \ を含むパスを拒否(%エンコード/二重エンコードも考慮)。
デコード→正規化→禁止シーケンス検出の順で検証。
3.ウェブ公開ディレクトリ以外はWebサーバ設定で直接参照不可に。
アプリのミスでもサーバ側でブロックする二重防御。
保険的対策
1.機微ファイルは公開領域に置かない・権限/所有を厳格化。
想定外参照が起きても読めない状態にする。
4) セッション管理の不備
脆弱性の説明
推測容易なセッションID、固定化、URL埋め込みなどの不備。
発生しうる脅威
セッション・ハイジャック、不正ログイン。
根本的解決
1.予測困難なID(暗号論的擬似乱数)を用い、ID自前生成は避ける/製品機能を利用。
時間や連番ベースは不可。
2.セッションIDをURLに入れない(Cookie or POST hidden)。
Referer経由で漏えいを防ぐ。
3.HTTPS用CookieにはSecure、Cookie窃取対策にHttpOnlyを付与。
HTTP送信やスクリプトからのアクセスを抑制。
4.ログイン成功後はセッション再生成(旧ID無効化)。
固定化攻撃を断ち切る。
5.必要に応じて追加の秘密情報をCookieに保持し毎リクエスト検証。
ID盗用に対する二要素的チェック。
保険的対策
1.Cookieの有効期限を最小化/必要時のみ永続化。
窃取されても悪用期間を短縮。
5) クロスサイト・スクリプティング(XSS)
脆弱性の説明
外部入力がHTML/JSとして実行される。
発生しうる脅威
Cookie窃取、フィッシング、偽画面表示など。
根本的解決
1.すべての出力コンテキストに応じたエスケープを実施(HTML, 属性, JS, CSS, URL)。
表示直前にコンテキスト毎の無害化を徹底。
2.<script>…</script>を動的生成しない/外部CSSを任意URLから取り込まない。
埋め込み面を設計から減らす。
3.URL出力は http(s):// 始まりのみ許可。
javascript:等の危険スキームを排除。
4.HTMLテキスト入力を許す場合は構文解析→ホワイトリスト要素のみ抽出。
正規表現のブラックリストは漏れやすい。
5.レスポンスのContent-Typeに正しいcharsetを必ず指定。
UTF-7等への誤判定悪用を防ぐ。
保険的対策
1.CookieにHttpOnlyを付与、TRACE無効化、ブラウザのXSS防御ヘッダやCSPを適切に返す。
完全防御ではないが被害の核(Cookie窃取等)を抑える。
2.(暫定)WAFで典型的ペイロードを遮断。
6) CSRF(クロスサイト・リクエスト・フォージェリ)
脆弱性の説明
他サイト経由の不正リクエストを本人操作として受け入れてしまう。
発生しうる脅威
不正送金、設定改ざん、退会や投稿の強制など。
根本的解決
1.実行ページはPOSTで受け、hiddenの秘密情報(CSRFトークン)を照合。
前画面で発行した予測困難な値と一致したときのみ処理。
2.重要処理直前で再パスワード入力(再認証)。
画面設計変更が許されるなら実装容易で強力。
3.Referer/Originを確認し想定フロー外は拒否(要副作用検討)。
一部環境で送信されないため例外設計が必要。
保険的対策
1.重要操作時に登録メールへ通知。
事後検知・早期発見に役立つ。
2.(暫定)WAFで外形的に怪しいPOSTを監視・遮断。
7) HTTPヘッダ・インジェクション(レスポンス分割含む)
脆弱性の説明
レスポンスヘッダ値を外部入力で組み立てると、改行注入でヘッダ/ボディを偽造・分割される。
発生しうる脅威
任意Cookie発行、キャッシュ汚染による偽ページ配信など。
根本的解決
1.言語/実行環境のヘッダ出力APIのみを使用(直接出力しない)。
APIが改行等を適切処理する前提で安全。
2.APIで対処できない場合、ヘッダ値に改行を一切許容しない実装に。
\r\n等があれば即中止・破棄。
保険的対策
1.外部入力から改行(制御コード)を削除(TEXTAREA等の要件には要配慮)。
暫定的に注入面を潰す。
8) メールヘッダ・インジェクション
脆弱性の説明
問い合わせ等のメール送信で、外部入力をヘッダに混ぜると任意宛先へ第三者中継される。
発生しうる脅威
スパム中継、情報漏えい。
根本的解決
1.送信元/件名等のヘッダは固定値を使用し、入力は本文のみへ出力。
To/Cc/Bcc等を一切入力から組み立てない。
2.メール送信用のAPI/ライブラリを利用(標準入出力に生ヘッダを書かない)。
ヘッダ生成を堅牢な実装に委譲。
保険的対策
1.入力から改行を削除(制御コードも含め検討)。
ヘッダ分離の糸口を絶つ暫定策。
9) クリックジャッキング
脆弱性の説明
罠ページに自サイトを透明iframeで重ねられ、ユーザが意図せずクリックする。
発生しうる脅威
設定変更や退会などの意図しない操作。
根本的解決
1.X-Frame-Options ヘッダを送出(DENY/SAMEORIGIN/一部ALLOW-FROM)。
他オリジンからのiframe表示を抑止。
2.重要処理直前で再認証。
他所からの視覚トリックでも突破しづらくする。
保険的対策
1.重要処理はキーボード操作や二段階操作を要求。
純粋な「一発クリック」を成立しにくくする。
10) バッファオーバーフロー
脆弱性の説明
低レベル言語の境界超過で任意コード実行やクラッシュ。
発生しうる脅威
サービス停止、マルウェア感染等。
根本的解決
1.直接メモリ操作しない言語(PHP/Perl/Java等)で実装。
アプリ層でのBOF作り込みを回避。
2.ネイティブ部分は最小化し、最新版ライブラリを使用。
既知脆弱性を踏まない。
保険的対策
1.ASLR/DEP等のプラットフォーム防御を有効化(一般論)。
仮に欠陥があっても悪用難度を上げる。
11) アクセス制御や認可制御の欠落
脆弱性の説明
認証・認可の設計/実装が不十分で、他人のデータにアクセス可能。
発生しうる脅威
個人情報や注文情報への不正閲覧・改ざん。
根本的解決
1.秘密情報(パスワード等)を用いた認証を必須に。
メールアドレス等だけでのログインは不可。
2.認可制御を実装し、操作対象のIDとログイン中の本人IDの一致を毎回確認。
URL/POSTのuser_id等をそのまま信じず、セッション側のIDで照合。
3.参照キー(注文番号等)は本人がアクセス許可された範囲かチェック。
他人の注文番号等を指定しても通らない。
保険的対策
1.ログ/監査証跡の整備と異常検知。
万一の不正操作の早期発見につなげる。
補足:改修が難しいときのセーフティネット(WAF)
実装修正までの暫定策としてWAFでHTTPを検査・遮断する方法があるが、誤検知/すり抜けが本質的に起こり得るため、導入時は監視期間で調整の上、根本的解決と併用が前提。
Discussion