OWASP ASVS(アプリケーションセキュリティ検証標準)
ASVSとは
OWASP ASVS(Application Security Verification Standard) は、Webアプリケーションのセキュリティ検証を標準化するためのフレームワークです。開発者・テスター・セキュリティ専門家が参照できる包括的なセキュリティ要件の一覧を提供し、アプリケーションの設計・開発・テストの各フェーズで活用できます。
- 最新バージョン: ASVS 4.0(2019年リリース)、5.0(開発中)
- 主な目的:
- セキュリティ要件の実装基準を明確化
- セキュリティテストの深さと範囲を定義
- セキュリティコントロールの調達・評価基準として活用
- サプライチェーンセキュリティの検証
OWASP Top 10 との違い
| 項目 | OWASP Top 10 | OWASP ASVS |
|---|---|---|
| 目的 | 最重要リスクの啓発 | 包括的なセキュリティ検証基準 |
| 範囲 | 10項目の脅威 | 14カテゴリ・数百項目の要件 |
| 用途 | リスク認識・優先度付け | 設計・実装・テストの検証 |
| 詳細度 | 概要レベル | 具体的な実装要件 |
3つの検証レベル
ASVSでは、アプリケーションのリスクプロファイルに応じた3段階の検証レベルを定義しています。
Level 1 - オポチュニスティック(Opportunistic)
最低限のセキュリティ要件。ペネトレーションテストやコードレビューで比較的容易に検証できる項目のみを対象とします。
- 対象: 低リスクアプリケーション、概念実証(PoC)
- 検証方法: ペネトレーションテスト、自動スキャン
- 特徴: 「機会があれば攻撃者が試みること」への対策
Level 2 - 標準(Standard)
機密データを扱う多くの業務アプリケーションが達成すべきレベル。防御的なプログラミングと適切なセキュリティコントロールが求められます。
- 対象: 個人情報・機密情報を扱うアプリ、Eコマース、業務システム
- 検証方法: コードレビュー、セキュリティテスト、脅威モデリング
- 特徴: 「動機があれば攻撃者が試みること」への対策
Level 3 - 高度(Advanced)
最高レベルのセキュリティ要件。医療・金融・政府機関、生命や安全に関わるシステムが対象です。
- 対象: 医療・金融・政府・重要インフラ
- 検証方法: 徹底的なコードレビュー、設計レビュー、アーキテクチャ検証
- 特徴: 「巧妙な標的型攻撃」への対策
14のセキュリティチャプター
ASVSは14のカテゴリ(チャプター)で構成されています。
V1: アーキテクチャ・設計・脅威モデリング
セキュアな設計原則と脅威モデリングに関する要件です。
主な要件
- すべてのコンポーネントが識別・信頼境界が定義されていること
- 各コンポーネントに必要なセキュリティコントロールが定義されていること
- 高価値のトランザクションには脅威モデルが存在すること
- セキュリティに関するアーキテクチャ決定が文書化されていること
例: 脅威モデリングの実施
1. システム概要の作成(DFDなど)
2. 信頼境界の定義
3. STRIDE(なりすまし、改ざん、否認、情報漏洩、DoS、権限昇格)を用いた脅威の列挙
4. リスク評価と対策の決定
5. ドキュメント化と継続的な見直し
V2: 認証(Authentication)
ユーザーのアイデンティティを正しく検証する要件です。
主な要件(Level 1)
- パスワードに長さ制限(最低8文字以上)と複雑性要件を設ける
- ブルートフォース対策(アカウントロックアウト、遅延など)を実装する
- 認証情報はHTTPS経由でのみ送受信する
- デフォルトパスワードを使用しない
主な要件(Level 2)
- 多要素認証(MFA)のサポート
- パスワードリセットの安全な実装(タイムアウト付きトークン使用)
- 認証に関するすべてのイベントをログに記録する
- 有効なセッションIDを認証成功後に再生成する
主な要件(Level 3)
- パスワードレス認証(WebAuthn、FIDO2)のサポート
- アダプティブ認証(リスクベース認証)
// 良い例: bcryptを使ったパスワードハッシュ化
import * as bcrypt from 'bcrypt';
const SALT_ROUNDS = 12; // 十分なコストファクター
async function hashPassword(password: string): Promise<string> {
return bcrypt.hash(password, SALT_ROUNDS);
}
async function verifyPassword(password: string, hash: string): Promise<boolean> {
return bcrypt.compare(password, hash);
}
// 悪い例(絶対にやってはいけない)
// const hash = md5(password); // MD5は暗号学的に破られている
// const hash = sha1(password); // SHA-1も脆弱
V3: セッション管理(Session Management)
セッションの適切な管理に関する要件です。
主な要件(Level 1)
- セッションIDは128ビット以上のエントロピーを持つこと
- セッションIDはURL・ログ・エラーメッセージに含めない
- セッションにアイドルタイムアウトと絶対タイムアウトを設定する
- ユーザーがログアウトしたらセッションを無効化する
主な要件(Level 2)
- 認証後にセッションIDを再生成する(セッション固定攻撃対策)
- CSRF対策(二重送信Cookieパターン、SynchronizerToken)
- HTTPOnly・Secure属性付きのCookie使用
- Cookie の SameSite 属性の適切な設定
// 良い例: セキュアなセッション設定(Express.js)
import session from 'express-session';
import crypto from 'crypto';
app.use(session({
secret: process.env.SESSION_SECRET!, // 環境変数から取得
resave: false,
saveUninitialized: false,
genid: () => crypto.randomUUID(), // 十分なエントロピー
cookie: {
secure: true, // HTTPS必須
httpOnly: true, // JavaScriptからのアクセスを禁止
sameSite: 'strict', // CSRF対策
maxAge: 1000 * 60 * 30, // 30分のタイムアウト
},
}));
V4: アクセス制御(Access Control)
認可・権限管理に関する要件です。
主な要件(Level 1)
- すべてのリソースにアクセス制御が実装されていること
- ディレクトリリスティングを無効化すること
- デフォルトで拒否(Deny by Default)の原則を採用すること
主な要件(Level 2)
- 最小権限の原則に従った設計
- 機密データへのすべてのアクセスをログに記録する
- 水平方向のアクセス制御(他ユーザーのデータへのアクセス防止)
- 機能レベルのアクセス制御(RBAC/ABACの適切な実装)
// 良い例: RBAC(ロールベースアクセス制御)の実装
enum Role {
ADMIN = 'admin',
EDITOR = 'editor',
VIEWER = 'viewer',
}
function requireRole(...allowedRoles: Role[]) {
return (req: Request, res: Response, next: NextFunction) => {
const userRole = req.user?.role as Role;
if (!userRole || !allowedRoles.includes(userRole)) {
// 403ではなく404を返すことで、リソースの存在を隠す手法もある
return res.status(403).json({ error: 'Access denied' });
}
next();
};
}
// 使用例
app.delete('/api/users/:id', requireRole(Role.ADMIN), deleteUser);
app.put('/api/articles/:id', requireRole(Role.ADMIN, Role.EDITOR), updateArticle);
app.get('/api/articles/:id', requireRole(Role.ADMIN, Role.EDITOR, Role.VIEWER), getArticle);
V5: バリデーション・サニタイゼーション・エンコーディング
入力値の検証と出力エンコーディングに関する要件です。
主な要件(Level 1)
- すべての入力を「信頼できない」ものとして扱う(入力値の網羅的な検証)
- インジェクション攻撃(SQLi、XSS、OS Commandなど)への対策
- 出力先に応じた適切なエスケープ・エンコーディング
- XMLパーサーのXXE(外部エンティティ)機能を無効化
// 良い例: パラメータ化クエリ(SQLインジェクション対策)
import { Pool } from 'pg';
const pool = new Pool();
// 安全: パラメータ化クエリ
async function getUserByEmail(email: string) {
const result = await pool.query(
'SELECT id, name, email FROM users WHERE email = $1',
[email] // プレースホルダーに値を渡す
);
return result.rows[0];
}
// 危険(絶対に使用しない)
// const query = `SELECT * FROM users WHERE email = '${email}'`;
// 良い例: DOMベースXSS対策(React)
// Reactは基本的に自動エスケープするが、dangerouslySetInnerHTMLに注意
import DOMPurify from 'dompurify';
function SafeHtmlRenderer({ content }: { content: string }) {
// ユーザー入力をそのまま埋め込まない
const sanitized = DOMPurify.sanitize(content);
return <div dangerouslySetInnerHTML={{ __html: sanitized }} />;
}
V6: 保存時の暗号化(Stored Cryptography)
データの保存時における暗号化に関する要件です。
主な要件
- 承認された暗号化アルゴリズムのみを使用する(AES-256、RSA-2048以上など)
- MD5・SHA-1など、破られたアルゴリズムを使用しない
- 暗号化キーはソースコードに埋め込まない
- 乱数生成には暗号学的に安全な疑似乱数生成器(CSPRNG)を使用する
| 用途 | 推奨アルゴリズム | 非推奨 |
|---|---|---|
| 対称暗号化 | AES-256-GCM | DES, 3DES, RC4 |
| 非対称暗号化 | RSA-2048以上, ECDSA | RSA-1024以下 |
| ハッシュ(汎用) | SHA-256以上 | MD5, SHA-1 |
| パスワードハッシュ | bcrypt, Argon2, scrypt | MD5, SHA-256(ソルトなし) |
| 鍵交換 | ECDH, DHE | 静的DH |
// 良い例: AES-GCMによる暗号化(C#)
using System.Security.Cryptography;
public static (byte[] ciphertext, byte[] nonce, byte[] tag) EncryptAesGcm(
byte[] plaintext, byte[] key)
{
var nonce = new byte[AesGcm.NonceByteSizes.MaxSize]; // 12バイト
var tag = new byte[AesGcm.TagByteSizes.MaxSize]; // 16バイト
var ciphertext = new byte[plaintext.Length];
RandomNumberGenerator.Fill(nonce); // CSPRNGで生成
using var aes = new AesGcm(key, AesGcm.TagByteSizes.MaxSize);
aes.Encrypt(nonce, plaintext, ciphertext, tag);
return (ciphertext, nonce, tag);
}
V7: エラー処理とログ記録(Error Handling and Logging)
エラー処理とログ管理に関する要件です。
主な要件(Level 1)
- エラーメッセージにスタックトレースや内部情報を含めない
- デフォルトのエラーページをカスタマイズする
- セキュリティに関連するイベント(ログイン成功・失敗、権限エラーなど)をログに記録する
主な要件(Level 2)
- ログに個人情報・パスワード・セッションIDを含めない
- ログは改ざん防止のため、書き込み専用ストレージに保管する
- セキュリティイベントにはタイムスタンプと十分な文脈情報を含める
- ログインジェクション攻撃への対策(改行コードのサニタイズなど)
// 良い例: 安全なエラーハンドリング(Express.js)
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
// 内部エラー情報はログに記録(機密情報は除く)
logger.error({
message: err.message,
stack: process.env.NODE_ENV === 'development' ? err.stack : undefined,
requestId: req.id,
userId: req.user?.id, // ユーザーIDのみ、パスワード等は除く
path: req.path,
});
// クライアントには汎用メッセージのみ返す
res.status(500).json({
error: 'Internal server error',
requestId: req.id, // サポートのための参照IDのみ
});
});
V8: データ保護(Data Protection)
機密データの取り扱いに関する要件です。
主な要件(Level 1)
- 機密データが意図せずキャッシュ・ログ・URLに日漏れないようにする
- HTTPレスポンスヘッダーにキャッシュ制御を適切に設定する
- 機密データを含むフォームのオートコンプリートを無効化する
主な要件(Level 2)
- すべての機密データに暗号化を適用する
- 古い・不要なデータを安全に削除する
- 個人情報(PII)は最小限しか収集しない(データ最小化原則)
- 機密データへのすべてのアクセスをログに記録する
// 良い例: HTTPセキュリティヘッダーの設定(Helmet.js)
import helmet from 'helmet';
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'nonce-{nonce}'"], // CSP Nonce
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", 'data:', 'https:'],
},
},
referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
hsts: {
maxAge: 31536000, // 1年
includeSubDomains: true,
preload: true,
},
noSniff: true, // X-Content-Type-Options: nosniff
frameguard: { action: 'deny' }, // X-Frame-Options: DENY
}));
V9: 通信(Communications)
通信の安全性に関する要件です。
主な要件(Level 1)
- すべての通信にTLS 1.2以上を使用する
- 証明書の有効性を検証する
- HTTPS以外の通信からHTTPSへのリダイレクトを実装する
主な要件(Level 2)
- TLS 1.0・1.1を無効化する
- 弱い暗号スイートを無効化する(RC4, DES, 3DESなど)
- HSTS(HTTP Strict Transport Security)を有効化する
- 証明書のピンニング(ハイリスクなケース)
推奨TLS設定(nginx)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
add_header Strict-Transport-Security "max-age=63072000" always;
V10: 悪意あるコード(Malicious Code)
悪意のあるコードやバックドアからの保護に関する要件です。
主な要件
- ソースコードに悪意あるロジック(時限爆弾、バックドアなど)がないこと
- サードパーティコンポーネントの検証・完全性チェック
- 整合性チェックメカニズムの実装
V11: ビジネスロジック(Business Logic)
ビジネスルールの悪用防止に関する要件です。
主な要件(Level 1)
- ビジネスロジックフローが順序通りにのみ実行されること
- 処理を繰り返し実行することへの制限(レート制限)
- 自動化ツールによる不正利用への対策
主な要件(Level 2)
- 高価値トランザクションに対する異常検知の実装
- ビジネスロジック攻撃(マイナス数量、整数オーバーフローなど)への対策
// 良い例: レート制限の実装(express-rate-limit)
import rateLimit from 'express-rate-limit';
// ログインAPIへのブルートフォース対策
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分
max: 10, // 最大10回
message: 'Too many login attempts, please try again later.',
standardHeaders: true,
legacyHeaders: false,
skipSuccessfulRequests: true, // 成功リクエストはカウントしない
});
app.post('/api/auth/login', loginLimiter, loginHandler);
V12: ファイルとリソース(Files and Resources)
ファイルアップロードやリソース管理に関する要件です。
主な要件(Level 1)
- アップロードファイルの種別検証(MIMEタイプ、マジックバイト確認)
- アップロードファイルをWebルート外に保存する
- ファイル名のサニタイズ(パストラバーサル対策)
主な要件(Level 2)
- アップロードファイルのウイルス/マルウェアスキャン
- ファイルサイズ制限の実装
- アップロードファイルの実行を防止する
// 良い例: ファイルアップロードのバリデーション(Multer)
import multer from 'multer';
import path from 'path';
import { v4 as uuidv4 } from 'uuid';
const ALLOWED_MIME_TYPES = ['image/jpeg', 'image/png', 'image/webp'];
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
const storage = multer.diskStorage({
destination: '/var/app/uploads', // Webルート外
filename: (req, file, cb) => {
// 元のファイル名を使わず、ランダムなIDを使用(パストラバーサル対策)
const ext = path.extname(file.originalname).toLowerCase();
cb(null, `${uuidv4()}${ext}`);
},
});
const upload = multer({
storage,
limits: { fileSize: MAX_FILE_SIZE },
fileFilter: (req, file, cb) => {
if (ALLOWED_MIME_TYPES.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error('Invalid file type'));
}
},
});
V13: API(API and Web Service)
APIとWebサービスのセキュリティに関する要件です。
主な要件(Level 1)
- REST APIに認証・認可が適切に実装されていること
- GraphQLやSOAPの既知の脆弱性への対策
- JSONおよびXMLのパーサーが安全に設定されていること
主な要件(Level 2)
- APIスキーマの検証(OpenAPI Specificationの活用)
- レート制限とクォータの実装
- HTTPメソッドの制限(不要なメソッドを無効化)
- JWT(JSON Web Token)の適切な検証
// 良い例: JWTの安全な検証
import jwt from 'jsonwebtoken';
function verifyToken(token: string): jwt.JwtPayload {
// 署名アルゴリズムを明示的に指定('none'アルゴリズム攻撃対策)
const decoded = jwt.verify(token, process.env.JWT_PUBLIC_KEY!, {
algorithms: ['RS256'], // 許可するアルゴリズムを明示
issuer: 'https://auth.example.com',
audience: 'api.example.com',
});
if (typeof decoded === 'string') {
throw new Error('Invalid token payload');
}
return decoded;
}
V14: 設定(Configuration)
セキュリティ設定に関する要件です。
主な要件(Level 1)
- デバッグ機能・開発ツールを本番環境で無効化する
- 不要なコンポーネント・機能・ページを削除する
- デフォルトの認証情報を変更する
主な要件(Level 2)
- HTTPセキュリティヘッダーの適切な設定
- Content Security Policy(CSP)の実装
- 依存関係の既知の脆弱性チェック(SCA: Software Composition Analysis)
// 良い例: package.jsonのセキュリティ監査
// npm audit, Dependabot, Snykなどで定期的に脆弱性チェック
// GitHub Dependabot設定(.github/dependabot.yml)
// version: 2
// updates:
// - package-ecosystem: "npm"
// directory: "/"
// schedule:
// interval: "weekly"
// open-pull-requests-limit: 10
ASVSの活用方法
1. セキュリティ要件定義
プロジェクト開始時に、アプリケーションのリスクレベルに応じてASVSのレベルを選定し、セキュリティ要件として取り込みます。
2. セキュアコーディングガイドラインとして
チーム内のコーディング標準に組み込み、コードレビューのチェックリストとして活用します。
| フェーズ | ASVSの活用 |
|---|---|
| 設計 | V1(アーキテクチャ)、V8(データ保護)を参照 |
| 実装 | V5(バリデーション)、V6(暗号化)、V13(API)を参照 |
| テスト | 各チャプターのテストケースをテスト設計に利用 |
| デプロイ | V9(通信)、V14(設定)を参照 |
| 運用 | V7(ログ)、V8(データ管理)を参照 |
3. セキュリティペネトレーションテストの基準
外部セキュリティ機関やペネトレーションテスターへの依頼時に、テスト範囲・深度の基準として提示します。
4. コンプライアンスへのマッピング
ASVSは主要なコンプライアンス標準と対応しています。
| 標準 | ASVSとの関連 |
|---|---|
| PCI DSS | Level 2要件がPCI DSS要件の多くを満たす |
| GDPR | V8(データ保護)との強い対応 |
| ISO/IEC 27001 | A.14(システム取得・開発・保守)との対応 |
| NIST SP 800-53 | 多くのコントロールが対応 |
ASVSチェックリスト(Level 1 主要項目)
セキュリティレビュー時の確認事項として活用してください。
認証・セッション
- パスワードの最小長(8文字以上、推奨12文字以上)
- ブルートフォース対策(アカウントロックアウトまたはCAPTCHA)
- セッションIDは128ビット以上のエントロピー
- ログイン後にセッションIDを再生成
- ログアウト時にサーバーサイドでセッションを無効化
- Cookieに
Secure・HttpOnly・SameSite属性
アクセス制御・認可
- デフォルト拒否(Deny by Default)の実装
- サーバーサイドでの権限チェック(クライアントサイドのみに依存しない)
- 水平方向のアクセス制御(他ユーザーのデータにアクセスできないか)
入力バリデーション
- すべての入力をサーバーサイドで検証
- SQLインジェクション対策(パラメータ化クエリ)
- XSS対策(出力エスケープ)
- XXE対策(外部エンティティの無効化)
通信・暗号化
- TLS 1.2以上を全通信で使用
- HTTPからHTTPSへの強制リダイレクト
- HSTSヘッダーの設定
- 弱い暗号アルゴリズムの不使用(MD5、SHA-1、DES等)
エラー処理・ログ
- エラーメッセージに内部情報が含まれない
- 認証関連のイベントをログに記録
- ログにパスワード・セッションIDが含まれない
設定・依存関係
- Webサーバーのバージョン情報が非公開
- 不要なHTTPメソッドを無効化(TRACE等)
- 依存パッケージの既知の脆弱性チェック
- HTTPセキュリティヘッダー(X-Content-Type-Options、X-Frame-Options等)
ツール・リソース
自動検証ツール
| カテゴリ | ツール | 用途 |
|---|---|---|
| SAST | Semgrep, CodeQL, Checkmarx | ソースコードの静的解析 |
| DAST | OWASP ZAP, Burp Suite | 動的アプリケーションスキャン |
| SCA | Snyk, Dependabot, OWASP Dependency-Check | 依存関係の脆弱性チェック |
| シークレットスキャン | GitLeaks, TruffleHog | 認証情報の漏洩検出 |
| IaC スキャン | Checkov, tfsec, Trivy | インフラコードのセキュリティチェック |
公式リソース
まとめ
OWASP ASVSはWebアプリケーションのセキュリティを体系的に検証するための強力なフレームワークです。
- Level 1: すべてのアプリケーションの最低ラインとして活用
- Level 2: 業務システム・機密データを扱うアプリの標準基準として活用
- Level 3: 医療・金融・政府など高いセキュリティが求められるシステムで活用
段階的にASVSへの準拠を進めることで、セキュリティの成熟度を継続的に向上させることができます。OWASP Top 10が「知っておくべきリスク」を示すのに対し、ASVSは「実際にどう対処するか」を具体的に定義したものであり、両者を組み合わせることが効果的なセキュリティ実践につながります。