ストーリー
OWASP Top 10 とは
OWASP(Open Worldwide Application Security Project)は、Webアプリケーションのセキュリティ向上を目的とした非営利団体です。OWASP Top 10は、最も深刻なWebアプリケーション脆弱性を示すリストで、数年ごとに更新されます。
OWASP Top 10(2021年版)
| 順位 | カテゴリ | 説明 |
|---|---|---|
| A01 | アクセス制御の不備 | 認可チェックの欠如・不備 |
| A02 | 暗号化の失敗 | 機密データの不適切な保護 |
| A03 | インジェクション | SQL/NoSQL/OS コマンドの注入 |
| A04 | 安全でない設計 | 設計レベルの欠陥 |
| A05 | セキュリティ設定ミス | デフォルト設定、不要な機能の有効化 |
| A06 | 脆弱で古いコンポーネント | 既知の脆弱性を持つライブラリの使用 |
| A07 | 認証の不備 | 認証メカニズムの実装ミス |
| A08 | ソフトウェアとデータの整合性の不備 | CI/CDの不正利用、安全でないデシリアライゼーション |
| A09 | セキュリティログと監視の不備 | 不十分なログ記録と監視 |
| A10 | SSRF(サーバーサイドリクエストフォージェリ) | サーバーから不正なリクエストを発行させる攻撃 |
主要な脆弱性の詳細
A01: アクセス制御の不備
最も多い脆弱性です。ユーザーが許可されていないリソースにアクセスできてしまう問題です。
// 脆弱なコード:誰でも他人のプロフィールを編集できる
app.put("/api/users/:id", async (req, res) => {
const user = await userRepo.update(req.params.id, req.body);
res.json(user);
});
// 安全なコード:本人または管理者のみ編集可能
app.put("/api/users/:id", authenticate, async (req, res) => {
const targetId = req.params.id;
const currentUser = req.user;
// 本人チェック or 管理者チェック
if (currentUser.id !== targetId && currentUser.role !== "admin") {
return res.status(403).json({ error: "Forbidden" });
}
const sanitizedData = sanitizeUpdateData(req.body);
const user = await userRepo.update(targetId, sanitizedData);
res.json(user);
});
A03: インジェクション
ユーザー入力がそのままクエリに組み込まれることで、意図しないコマンドが実行される攻撃です。
// 脆弱なコード:SQLインジェクション
const getUser = async (email: string) => {
const query = `SELECT * FROM users WHERE email = '${email}'`;
// 攻撃者が email = "'; DROP TABLE users; --" を送信すると...
return db.query(query);
};
// 安全なコード:パラメータ化クエリ
const getUser = async (email: string) => {
const query = "SELECT * FROM users WHERE email = $1";
return db.query(query, [email]);
};
// さらに安全:ORMを使用
const getUser = async (email: string) => {
return prisma.user.findUnique({ where: { email } });
};
A05: セキュリティ設定ミス
デフォルト設定のまま本番運用したり、不要な機能が有効になっていたりする問題です。
// 脆弱な設定例
const app = express();
app.use(express.json()); // サイズ制限なし
// 安全な設定例
const app = express();
app.use(helmet()); // セキュリティヘッダーを自動設定
app.use(express.json({ limit: "10kb" })); // ペイロードサイズ制限
app.disable("x-powered-by"); // サーバー情報を隠す
app.use(cors({
origin: ["https://example.com"], // 許可するオリジンを明示
methods: ["GET", "POST", "PUT", "DELETE"],
credentials: true,
}));
OWASP Top 10 を設計に活かす
脆弱性を知るだけでなく、設計段階で対策を組み込むことが重要です。
| 脆弱性 | 設計段階での対策 |
|---|---|
| A01 アクセス制御 | 認可ミドルウェアを必須にする設計 |
| A02 暗号化の失敗 | データ分類ポリシーの策定 |
| A03 インジェクション | ORM/パラメータ化クエリの強制 |
| A04 安全でない設計 | 脅威モデリングの実施 |
| A05 設定ミス | セキュリティベースライン設定の定義 |
| A06 脆弱なコンポーネント | SBOM管理と自動更新 |
| A07 認証の不備 | 認証フレームワークの採用 |
| A08 整合性の不備 | CI/CDパイプラインの署名検証 |
| A09 ログ・監視不備 | 監査ログの設計 |
| A10 SSRF | URLバリデーションとホワイトリスト |
まとめ
| ポイント | 内容 |
|---|---|
| OWASP | Webセキュリティの標準的な指針 |
| Top 10 | 最も一般的な脆弱性のランキング |
| A01 | アクセス制御の不備が最多 |
| 活用方法 | 設計レビューのチェックリストとして使う |
チェックリスト
- OWASP Top 10の各カテゴリを把握した
- アクセス制御の不備がなぜ1位なのか理解した
- インジェクションの防止方法を理解した
- 設計段階でOWASP Top 10を活用する方法を把握した
次のステップへ
次は「攻撃者の視点で考える」を学びます。守る側の視点だけでなく、攻撃者がどのようにシステムを狙うかを理解しましょう。
推定読了時間: 25分