ストーリー
佐藤CTOがセキュリティインシデントの報告書を手に、あなたをミーティングルームに呼びました。
佐
佐藤CTO
先月、同業他社がサプライチェーン攻撃を受けて3日間サービスが停止した。うちも他人事じゃない
あなた
サプライチェーン攻撃…依存ライブラリ経由の攻撃ですか?
あ
佐
佐藤CTO
そうだ。npm パッケージに悪意のあるコードが仕込まれていた。境界防御だけでは防げない。全てを疑え — それがセキュリティの新常識だ
佐
佐藤CTO
今月は組織全体のセキュリティを強化する。開発速度を落とさずにセキュリティレベルを上げる方法を、一緒に探ろう
OWASP Top 10 — 最も警戒すべきWebアプリケーションの脅威
OWASP(Open Worldwide Application Security Project)は、Webアプリケーションのセキュリティリスクを定期的にランキングしています。
OWASP Top 10 (2021)
| 順位 | カテゴリ | 概要 | 影響度 |
|---|
| A01 | アクセス制御の不備 | 認可チェックの欠如、権限昇格 | 極めて高い |
| A02 | 暗号化の失敗 | 機密データの平文保存、弱い暗号化 | 高い |
| A03 | インジェクション | SQL/NoSQL/OS/LDAPインジェクション、XSS | 高い |
| A04 | 安全でない設計 | 設計段階でのセキュリティ考慮不足 | 高い |
| A05 | セキュリティの設定ミス | デフォルト設定の放置、不要な機能の有効化 | 中〜高い |
| A06 | 脆弱なコンポーネント | 既知の脆弱性を持つライブラリの使用 | 中〜高い |
| A07 | 認証の不備 | セッション管理の欠陥、弱いパスワードポリシー | 高い |
| A08 | ソフトウェアとデータの整合性の不備 | CI/CDパイプラインの保護不足 | 中〜高い |
| A09 | セキュリティログと監視の不備 | 侵入検知の遅れ、ログ不足 | 中 |
| A10 | SSRF(サーバーサイドリクエストフォージェリ) | 内部リソースへの不正アクセス | 中〜高い |
// A01: アクセス制御の不備 -- 脆弱なコード例
app.get('/api/users/:id/profile', async (req, res) => {
// 危険: 認可チェックなし -- 誰でも他人のプロフィールを取得できる
const user = await userRepository.findById(req.params.id);
res.json(user);
});
// 修正版: 認可チェックを追加
app.get('/api/users/:id/profile', authenticate, async (req, res) => {
const requestedUserId = req.params.id;
const currentUserId = req.user.id;
// 自分自身または管理者のみアクセス可能
if (requestedUserId !== currentUserId && !req.user.roles.includes('admin')) {
return res.status(403).json({ error: 'Forbidden' });
}
const user = await userRepository.findById(requestedUserId);
res.json(user);
});
最新の攻撃トレンド
サプライチェーン攻撃
サプライチェーン攻撃は、ソフトウェアの依存関係やビルドプロセスを狙った攻撃です。
| 攻撃手法 | 説明 | 実例 |
|---|
| 依存関係の汚染 | 正規パッケージに悪意のあるコードを注入 | event-stream事件(2018) |
| タイポスクワッティング | 類似名のパッケージで開発者を騙す | crossenv → cross-env |
| アカウント乗っ取り | メンテナのアカウントを奪取してパッケージを改ざん | ua-parser-js事件(2021) |
| ビルドパイプラインの侵害 | CI/CDシステムを攻撃してビルド成果物を改ざん | SolarWinds事件(2020) |
| 依存関係の混同 | 内部パッケージと同名の公開パッケージを登録 | Dependency Confusion攻撃 |
// package.json の依存関係を検証するスクリプト例
import { execSync } from 'child_process';
import * as fs from 'fs';
interface AuditResult {
vulnerabilities: {
[severity: string]: number;
};
}
function checkDependencySecurity(): void {
// npm audit で脆弱性をチェック
const auditOutput = execSync('npm audit --json', { encoding: 'utf-8' });
const audit: AuditResult = JSON.parse(auditOutput);
const criticalCount = audit.vulnerabilities['critical'] ?? 0;
const highCount = audit.vulnerabilities['high'] ?? 0;
if (criticalCount > 0 || highCount > 0) {
console.error(`重大な脆弱性が検出されました: Critical=${criticalCount}, High=${highCount}`);
process.exit(1);
}
console.log('依存関係のセキュリティチェック: OK');
}
ゼロデイ脆弱性
ゼロデイ脆弱性は、ベンダーやセキュリティコミュニティが認識する前に悪用される脆弱性です。
| 特徴 | 説明 |
|---|
| 発見から悪用までの時間 | パッチ提供前に攻撃が発生(0日間の猶予) |
| 検出の困難さ | シグネチャベースの検知では防げない |
| 対策 | 多層防御、振る舞い検知、最小権限の原則 |
| 最近の傾向 | Log4Shell(2021)、Spring4Shell(2022)などフレームワークの脆弱性が増加 |
ランサムウェアとデータ漏洩
| 攻撃段階 | 手法 | 対策 |
|---|
| 初期侵入 | フィッシング、VPN脆弱性 | MFA、セキュリティ教育 |
| 横展開 | 権限昇格、ラテラルムーブメント | マイクロセグメンテーション |
| データ持ち出し | 機密データの暗号化・外部送信 | DLP、ネットワーク監視 |
| ランサム要求 | データ暗号化・公開脅迫 | バックアップ、インシデント対応計画 |
脅威ランドスケープの全体像
graph TD
Title["脅威ランドスケープ"]
Title --- External["外部脅威<br/>・標的型攻撃<br/>・DDoS攻撃<br/>・フィッシング<br/>・ランサムウェア<br/>・ゼロデイ"]
Title --- Internal["内部脅威<br/>・内部不正<br/>・設定ミス<br/>・権限の乱用<br/>・シャドーIT<br/>・退職者リスク"]
Title --- Supply["サプライチェーン脅威<br/>・依存ライブラリの脆弱性<br/>・ビルドパイプラインの侵害<br/>・サードパーティサービスの侵害<br/>・OSS汚染<br/>・コンテナイメージの改ざん"]
classDef title fill:#1a1a2e,stroke:#e94560,color:#fff
classDef external fill:#e94560,stroke:#e94560,color:#fff
classDef internal fill:#f5a623,stroke:#f5a623,color:#fff
classDef supply fill:#0f3460,stroke:#0f3460,color:#fff
class Title title
class External external
class Internal internal
class Supply supply
脅威アクターの分類
| アクター | 動機 | 能力 | 典型的な攻撃 |
|---|
| スクリプトキディ | 自己顕示、いたずら | 低い | 既知の脆弱性を悪用 |
| サイバー犯罪グループ | 金銭的利益 | 中〜高い | ランサムウェア、フィッシング |
| 内部犯行者 | 不満、金銭 | 内部知識 | データ漏洩、サボタージュ |
| 国家支援型 | 情報収集、破壊 | 極めて高い | APT、ゼロデイ |
| ハクティビスト | 政治的・社会的主張 | 中程度 | DDoS、データ公開 |
セキュリティの基本原則:CIA + AAA
CIAトライアド
| 原則 | 英語 | 説明 | 脅威例 |
|---|
| 機密性 | Confidentiality | 認可されたユーザーだけがデータにアクセスできる | データ漏洩、盗聴 |
| 完全性 | Integrity | データが不正に改ざんされていないことを保証 | データ改ざん、MITM攻撃 |
| 可用性 | Availability | 必要なときにシステムとデータが利用できる | DDoS攻撃、ランサムウェア |
AAA(認証・認可・監査)
| 原則 | 英語 | 説明 |
|---|
| 認証 | Authentication | 「あなたは誰ですか?」の検証 |
| 認可 | Authorization | 「あなたは何ができますか?」の制御 |
| 監査 | Accounting/Auditing | 「あなたは何をしましたか?」の記録 |
// CIA + AAA を意識したAPIミドルウェアの例
import { Request, Response, NextFunction } from 'express';
// 認証(Authentication): JWTトークンの検証
function authenticate(req: Request, res: Response, next: NextFunction): void {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
res.status(401).json({ error: 'Authentication required' });
return;
}
try {
req.user = verifyJwt(token);
next();
} catch {
res.status(401).json({ error: 'Invalid token' });
}
}
// 認可(Authorization): ロールベースのアクセス制御
function authorize(...requiredRoles: string[]) {
return (req: Request, res: Response, next: NextFunction): void => {
const userRoles = req.user?.roles ?? [];
const hasRole = requiredRoles.some(role => userRoles.includes(role));
if (!hasRole) {
res.status(403).json({ error: 'Insufficient permissions' });
return;
}
next();
};
}
// 監査(Auditing): アクセスログの記録
function audit(req: Request, res: Response, next: NextFunction): void {
const logEntry = {
timestamp: new Date().toISOString(),
userId: req.user?.id ?? 'anonymous',
method: req.method,
path: req.path,
ip: req.ip,
userAgent: req.headers['user-agent'],
};
securityLogger.info('API_ACCESS', logEntry);
next();
}
まとめ
| ポイント | 内容 |
|---|
| OWASP Top 10 | Webアプリケーションの最も深刻な10のセキュリティリスク |
| サプライチェーン攻撃 | 依存関係やビルドプロセスを狙った攻撃が急増 |
| ゼロデイ脆弱性 | パッチ提供前に悪用される脆弱性、多層防御が重要 |
| CIAトライアド | 機密性・完全性・可用性がセキュリティの三本柱 |
| AAA | 認証・認可・監査を組み合わせてアクセスを制御 |
チェックリスト
次のステップへ
次は「脅威モデリング(STRIDE)」を学びます。脅威を体系的に分析するためのフレームワークを使い、システムの弱点を事前に特定する方法を身につけましょう。
推定読了時間: 30分