security について
開発者向けの、技術スタックに依存しないセキュリティリファレンスです。アプリケーションの設計、実装、レビュー、インシデント対応を対象に、OWASP Top 10、入力検証、認証、データ保護、シークレット管理を扱います。
主な機能
- 01OWASP Top 10 のリスク指針
- 02入力検証と安全なクエリの実践
- 03認証と認可のパターン
- 04データ保護とシークレット管理
- 05HTTP セキュリティヘッダーと CORS
- 06セキュリティレビューのチェックリストとアンチパターン
活用シーン
- 01入力や機密データを扱うコードをレビューする
- 02認証・認可フローを設計する
- 03セキュリティ監査に備える
- 04脆弱性報告に対応する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ krzysztofsurdy/ code-virtuoso --skill securityインストール後、Claude Code で/securityを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/auth-patterns.mdowasp-top-10.mdsecure-coding.md詳細
セキュリティ
セキュリティは機能ではなく、すべての機能に備わっているべき性質です。すべてのエンドポイント、フォーム、データフロー、統合ポイントは、最初からセキュリティを考慮して設計する必要があります。後からセキュリティを付け足すのはコストがかかり、エラーが発生しやすく、多くの場合、不完全です。
このスキルでは、特定のスタックに依存しない、安全なアプリケーションを構築するための指針を紹介します。OWASP Top 10、入力検証、認証と認可のパターン、データ保護、シークレット管理、セキュリティヘッダー、よくあるアンチパターンを取り上げます。
使用するタイミング
次のような場合に、このスキルを参照してください。
- ユーザー入力、認証、機密データを扱う新機能を設計するとき
- セキュリティ上の懸念がないかコードをレビューするとき
- 認証または認可のフローを実装するとき
- シークレット、API キー、認証情報を扱うとき
- HTTP セキュリティヘッダーを設定するとき
- 依存関係や設計上の選択によってリスクが生じるか評価するとき
- セキュリティ監査や侵入テストに備えるとき
- セキュリティインシデントや脆弱性の報告に対応するとき
OWASP Top 10
OWASP Top 10(2021 年版)は、Web アプリケーションにおける最も重大なセキュリティリスクを示しています。網羅的なリストではなく、出発点となるチェックリストとして活用してください。
| # | 脆弱性 | 概要 | 主な防御策 |
|---|---|---|---|
| A01 | アクセス制御の不備 | ユーザーが意図された権限の範囲を超えて操作できる | デフォルトで拒否し、サーバー側で適用する |
| A02 | 暗号化の失敗 | 暗号化の不備や欠如により機密データが漏えいする | 強力なアルゴリズムを使用し、通信中と保存中のデータを暗号化する |
| A03 | インジェクション | 信頼できないデータがコマンドやクエリの一部としてインタープリターに送られる | パラメーター化クエリ、入力検証 |
| A04 | 安全でない設計 | 設計上、セキュリティ制御が欠如または無効になっている | 脅威モデリング、安全な設計パターン |
| A05 | セキュリティ設定の不備 | 安全でないデフォルト設定、不完全なセットアップ | 強化されたデフォルト設定、設定の自動検証 |
| A06 | 脆弱なコンポーネント | 既知の脆弱性があるコンポーネントを使用している | 依存関係のスキャン、適時の更新 |
| A07 | 認証の失敗 | 認証または識別が適切に機能しない | MFA、レート制限、安全なパスワード保存 |
| A08 | 完全性の失敗 | コードやデータの完全性が検証されていない | 署名付き更新、CI/CD の完全性チェック |
| A09 | ログ記録の失敗 | ログ記録と監視が不十分 | セキュリティイベントを記録し、アラートを設定する |
| A10 | SSRF | サーバーがだまされ、意図しないリクエストを送信する | 許可リストによる送信先の制限、URL のサニタイズ |
入力検証
入力検証は最初の防御線です。UI だけでなく、システムの境界ごとに検証してください。
基本原則:
- サーバー側で検証する — クライアント側の検証は UX の利便性を高めるものであり、セキュリティ対策ではありません
- 拒否リストより許可リストを使う — 危険なものを遮断しようとするのではなく、許容されるものを定義してください
- 型、長さ、形式、範囲を検証する — 「名前」フィールドで 10MB のデータを受け付けたり、制御文字を含めたりしてはいけません
- 想定外の入力は拒否する — 安全側に倒して失敗し、悪意のある入力を「クリーンアップ」して処理を続けようとしないでください
- 検証前に正規化する — Unicode を正規化し、URL エンコーディングをデコードし、パスのトラバーサルを解決してからチェックしてください
型強制の危険性:
緩い型比較はセキュリティチェックを回避される原因になります。文字列の「0」は、言語によって整数の 0 やブール値の false と等しいと判定される場合があります。常に厳密な比較演算子を使用し、明示的に型変換してください。
パラメーター化クエリ:
ユーザー入力を SQL、LDAP、OS コマンドに連結してはいけません。必ずパラメーター化クエリまたはプリペアドステートメントを使用してください。ORM にも同じことが当てはまります。生のクエリメソッドは ORM の保護を迂回します。詳細はセキュアコーディングのリファレンスを参照してください。
認証パターン
認証は「あなたは誰ですか?」を確認するものです。詳しくは認証パターンのリファレンスを参照してください。
パスワードのハッシュ化:
- bcrypt、scrypt、または Argon2id を使用してください。パスワードに MD5、SHA-1、または SHA-256 のみを使用してはいけません
- ソルトはパスワードごとに一意である必要があり、ハッシュ化ライブラリで生成してください
- 平文のパスワードを保存してはいけません。また、パスワードに可逆暗号化を使用してはいけません
- 最低限の複雑さを求めつつ、ユーザーがより弱いパターンに走るような過度に厳しいルールは避けてください
多要素認証(MFA):
- TOTP(時間ベースのワンタイムパスワード)が基本です
- WebAuthn/パスキーは、最も強力なフィッシング耐性を提供します
- SMS ベースの MFA は何もしないよりは有効ですが、SIM スワッピングに対して脆弱です
- 必ずリカバリーコードを提供してください
セッション管理:
- 十分なエントロピー(128 ビット以上)を持つ、暗号学的にランダムなセッション ID を生成してください
- セキュア Cookie 属性を設定してください:
HttpOnly、Secure、SameSite=Lax(またはStrict) - セッション固定を防ぐため、ログイン後にセッション ID を再生成してください
- 絶対タイムアウトとアイドルタイムアウトを実装してください
- ログアウト時にサーバー側でセッションを無効化してください
トークンベースの認証(JWT の注意点):
- JWT はセッションではありません。追加のインフラストラクチャがなければ取り消せません
- サーバー側で署名アルゴリズムを必ず検証し、
alg: noneを拒否してください - トークンの有効期間は短くしてください(数時間ではなく数分)
- 長期間有効なセッションにはリフレッシュトークンを使用し、安全に保存してください
- JWT のペイロードに機密データを保存してはいけません。ペイロードは Base64 エンコードされているだけで、暗号化されていません
OAuth2 フロー:
- Authorization Code with PKCE — Web アプリとモバイルアプリの標準です
- Client Credentials — マシン間通信に使用します
- Implicit フローは使用しないでください。セキュリティ上の理由で非推奨になっています
認可パターン
認可によって権限、つまり「何を行うことが許可されているか」が決まります。認可は認証とは異なります。詳細は認証パターンのリファレンスを参照してください。
最小権限の原則:
- タスクに必要な最小限の権限を付与します
- デフォルトでは拒否し、アクセス権を取り消すのではなく、明示的に付与します
- 可能であれば、昇格した権限に有効期限を設定します
ロールベースアクセス制御(RBAC):
- 権限をロールに割り当て、ロールをユーザーに割り当てます
- ロールは大まかな分類にとどめ、ロールの増えすぎを避けます
- アプリケーションコードではロール名ではなく権限を確認します。これにより、認可ロジックをロール定義から切り離せます
属性ベースアクセス制御(ABAC):
- ユーザー、リソース、アクション、環境の属性に基づいて判断します
- 複雑なポリシー(例:「営業時間中に、マネージャーは10,000ドル未満の経費を承認できる」)では、RBAC よりも柔軟です
- 複雑性が高いため、RBAC では不十分な場合に使用します
よくある認可の誤り:
- UI でのみ認可を確認すること。必ずサーバー側で強制してください
- アクセス制御ではなく、推測困難な URL などの秘匿性に頼ること
- API 呼び出し、ファイルのダウンロード、間接参照を含むすべてのリクエストで認可を確認しないこと
- IDOR(安全でない直接オブジェクト参照)。要求された特定のリソースへのアクセス権がユーザーにあることを必ず確認してください
データ保護
保存データの暗号化:
- データベース、ファイル、バックアップに保存される機密データを暗号化します
- 共通鍵暗号には AES-256 または同等の方式を使用します
- 暗号鍵は暗号化されたデータとは別に管理します
- 暗号鍵は定期的に、また侵害が疑われる場合にローテーションします
転送中データの暗号化:
- すべてのネットワーク通信に TLS 1.2 以降を使用します
- 古いプロトコル(SSL、TLS 1.0、TLS 1.1)を無効にします
- 証明書を適切に検証します。証明書の検証を無効にしないでください
PII の取り扱い:
- 個人を特定できる情報をすべて特定し、分類します
- 収集を最小限に抑え、必要のないデータは収集しません
- データ保持ポリシーを実施し、不要になったデータを削除します
- コンプライアンス(GDPR、CCPA)に対応するため、データのエクスポートと削除の機能を提供します
- ログ内の PII をマスキングします。パスワード、トークン、クレジットカード番号、完全な SSN は決して記録しないでください
安全な削除:
- 言語で可能な場合は、メモリを解放する前に機密データを上書きします
- データベースの削除によって、データが実際に削除されることを確認します(機密レコードをソフトデリートだけで済ませないでください)
- バックアップの保持期間も考慮してください。削除したデータがバックアップに残っている場合があります
シークレット管理
コードや設定ファイルには決して保存しないでください:
- API キー、パスワード、トークンを、ソースコード、設定ファイル、またはバージョン管理にコミットされる環境固有のファイルに含めないでください
- ローカルの設定ファイルには
.gitignoreを使用しますが、それだけを保護手段として頼らないでください - リポジトリをスキャンして、誤ってコミットされたシークレットを検出します(git-secrets、truffleHog、Gitleaks などのツールを使用します)
環境変数:
- シンプルなデプロイでは許容されますが、制約があります
- 同じ環境内のすべてのプロセスから参照できます
- プロセス一覧やクラッシュダンプに表示されます
- ハードコードするよりは安全ですが、最も強力な選択肢ではありません
シークレットマネージャー:
- 専用のシークレットマネージャー(HashiCorp Vault、AWS Secrets Manager、Azure Key Vault、GCP Secret Manager)を使用します
- シークレットにはビルド時ではなく、実行時にアクセスします
- シークレットへのアクセスを監査します
ローテーション戦略:
- シークレットを定期的にローテーションします
- 侵害が疑われる場合は直ちにローテーションします
- ダウンタイムなしでローテーションできるようにシステムを設計します(移行中は2つのバージョンを同時に有効にします)
- 可能な場合はローテーションを自動化します
セキュリティヘッダー
すべてのレスポンスに、これらの HTTP レスポンスヘッダーを設定してください。それぞれが特定の種類の攻撃に対処します。
| ヘッダー | 目的 | 推奨値 |
|---|---|---|
Content-Security-Policy (CSP) | コンテンツの読み込み元を制御して、XSS を防ぎます | 制限の厳しいポリシーから始め、unsafe-inline と unsafe-eval は避けてください |
Strict-Transport-Security (HSTS) | 今後のすべてのリクエストで HTTPS を強制します | max-age=63072000; includeSubDomains; preload |
X-Content-Type-Options | MIME タイプのスニッフィングを防ぎます | nosniff |
X-Frame-Options | iframe への埋め込みを制御して、クリックジャッキングを防ぎます | DENY または SAMEORIGIN |
Referrer-Policy | 送信するリファラー情報の量を制御します | strict-origin-when-cross-origin |
Permissions-Policy | ブラウザーの機能(カメラ、マイク、位置情報)を制御します | 使用しない機能を無効にしてください |
CORS(クロスオリジンリソース共有):
- 認証が必要なエンドポイントでは、
Access-Control-Allow-Origin: *を使用しないでください - 特定のオリジンを許可リストに登録してください
Access-Control-Allow-MethodsとAccess-Control-Allow-Headersは制限的に設定してください- CORS はブラウザーによって適用されるものであり、サーバー間の呼び出しを保護するものではないことを理解してください
よくあるアンチパターン
脆弱性につながる、よく見られる間違いを以下に示します。
- 隠蔽によるセキュリティ — URL を隠したり、予測しにくい ID を使用したり、コードを難読化したりしても、セキュリティ対策にはなりません。実際の対策を補完するものであり、決してその代わりにはなりません。
- クライアント側だけでの検証 — JavaScript やモバイルコードで行う検証は、どれも回避できます。必ずサーバー側で検証してください。
- 独自の暗号処理 — 暗号化、ハッシュ化、乱数生成を独自に実装しないでください。十分にテストされたライブラリを使用してください。
- 過度に許可的な CORS —
Access-Control-Allow-Origin: *と認証情報の組み合わせは脆弱性になります。許可するオリジンを具体的に指定してください。 - リポジトリへのシークレットの保存 — 「プライベート」リポジトリであっても、コード内のシークレットはフォーク、CI システム、開発者のマシンに拡散します。
- 利便性のためのセキュリティ機能の無効化 — 「開発」モードで CSRF 保護、SSL 検証、認証を無効にし、その設定が本番環境に持ち込まれることがあります。
- 内部ネットワークへの信頼 — ゼロトラストでは、内部のサービス間呼び出しであっても、ID と認可を検証します。
- 依存関係の脆弱性の無視 — 依存関係にある既知の脆弱性は、最も簡単に悪用できる攻撃経路の一つです。定期的にスキャンして更新してください。
- 機密データのログ出力 — ログにパスワード、トークン、クレジットカード番号、PII を含めると、二次的な情報漏えいのリスクが生じます。
- 例外の捕捉と握りつぶし — エラーを握りつぶすと、セキュリティ上の問題が見えなくなります。(機密情報は含めずに)ログに記録し、安全に失敗するようにしてください。
セキュリティレビューのチェックリスト
コードのレビュー、機能の設計、またはリリース準備の際に、このチェックリストを使用してください。
入出力:
- すべてのユーザー入力がサーバー側で検証されている
- すべてのデータベース操作でパラメーター化クエリを使用している
- 出力が適切なコンテキスト(HTML、URL、JavaScript、SQL)に合わせてエンコードまたはエスケープされている
- ファイルのアップロード時に種類、サイズ、内容を検証し、Web ルート外に保存している
認証:
- パスワードが bcrypt/Argon2id でハッシュ化されている
- ログイン後にセッション ID が再生成されている
- セキュア Cookie 属性(HttpOnly、Secure、SameSite)が設定されている
- ログインエンドポイントにレート制限が設定されている
- ログイン失敗後にアカウントをロックするか、段階的に遅延時間を設けている
認可:
- すべてのリクエストで、サーバー側にて認可を適用している
- 最小権限の原則を適用している
- 直接オブジェクト参照が現在のユーザーに対して検証されている
- 管理者機能が保護され、URL を推測してアクセスできない
データ:
- 機密データが保存時および転送時に暗号化されている
- 個人を特定できる情報(PII)をログに記録していない
- データ保持ポリシーを実施している
- バックアップが暗号化されている
設定:
- ソースコードや設定ファイルにシークレットが含まれていない
- セキュリティヘッダーが設定されている
- 本番環境でデバッグモードが無効になっている
- エラーメッセージからクライアントに内部情報が漏れない
- 既知の脆弱性がないか依存関係をスキャンしている
- TLS 1.2 以降を強制し、古いプロトコルを無効にしている
監視:
- セキュリティイベント(ログイン失敗、認可拒否、入力検証失敗)を記録している
- 不審なパターンに対するアラートを設定している
- ログが改ざんから保護されている
- インシデント対応計画を文書化している