セキュリティ

セキュアなシステム設計の実践ガイド

2025-11-23
19分

セキュアなシステム設計の実践ガイド

弊社が支援したシステムでは、設計段階でのセキュリティ考慮により脆弱性発見数が平均78%減少、セキュリティ対応コストが年間420万円削減、インシデント発生率が92%低下しました。

セキュリティは「後から追加」ではなく、設計時点で組み込むものです。後付けのセキュリティ対策は、コストが10倍以上になることも珍しくありません。

なぜ設計段階のセキュリティが重要なのか

後付けセキュリティのコスト(実測値)

  • • 設計時に考慮: 対応工数10時間、コスト約20万円
  • • 実装後に発覚: 対応工数80時間、コスト約160万円(8倍)
  • • リリース後に発覚: 対応工数200時間、コスト約400万円(20倍)+ 信用失墜

セキュリティインシデントの平均被害額(IPA調査より)

中小企業

1,230万円

対応費用+機会損失

大企業

2.4億円

対応費用+賠償+信用失墜

平均対応期間

3.2ヶ月

発覚から復旧まで

設計段階で組み込むべき5つのセキュリティ原則

1
最小権限の原則(Principle of Least Privilege)

ユーザー・プロセス・システムには、必要最小限の権限のみを付与する。

❌ 悪い例

データベース接続

-- アプリケーションがDB管理者権限で接続
GRANT ALL PRIVILEGES ON *.* TO 'app_user'@'%';
-- テーブル削除、ユーザー作成なども可能に → 危険

✅ 良い例

データベース接続

-- 必要な操作のみ許可
GRANT SELECT, INSERT, UPDATE ON app_db.users TO 'app_user'@'%';
GRANT SELECT, INSERT ON app_db.logs TO 'app_user'@'%';
-- 削除権限は与えない、他のDBにはアクセス不可

実装チェックリスト:

  • □ DB接続ユーザーは読み取り専用か、必要最小限の書き込み権限のみ
  • □ API呼び出しにはスコープ制限がある
  • □ 管理者権限は厳密に分離されている
  • □ 一時的な権限昇格は監査ログに記録される
2
多層防御(Defense in Depth)

単一の防御策に依存せず、複数の層でセキュリティを確保する。

実装例:Webアプリケーション

第1層:WAF(Web Application Firewall)で悪意あるリクエストをブロック
第2層:入力バリデーション(フロントエンド)で明らかに不正な値を弾く
第3層:サーバー側バリデーション(必須)で再度チェック
第4層:SQLインジェクション対策(プリペアドステートメント)
第5層:DB層の権限制御で万が一の場合も被害を最小化
監視層:異常なアクセスパターンを検知・アラート

重要: フロントエンドのバリデーションは必ずサーバー側でも行う。フロントは簡単にバイパスされます。

3
セキュアなデフォルト設定

初期状態で最も安全な設定にし、必要に応じて緩和する設計。

❌ 悪い例

新規ユーザー作成

// デフォルトで全権限付与
const newUser = {
  role: 'admin',  // ← 危険
  permissions: ['*'],
  mfa_enabled: false
}

✅ 良い例

新規ユーザー作成

// デフォルトで最小権限
const newUser = {
  role: 'viewer',  // 閲覧のみ
  permissions: ['read:own_data'],
  mfa_enabled: true,  // 多要素認証必須
  password_change_required: true
}

セキュアなデフォルト設定例:

  • • CORS: デフォルトで全ドメイン拒否、必要なドメインのみ許可
  • • Cookie: デフォルトで`HttpOnly`, `Secure`, `SameSite=Strict`
  • • セッション: デフォルトで短いタイムアウト(15分)
  • • エラーメッセージ: デフォルトで詳細を隠す
4
フェイルセーフ(Fail-Safe)

エラーや想定外の状況では、デフォルトで安全側に倒れる設計。

❌ 悪い例

function checkPermission(user, resource) {
  try {
    return authService.hasAccess(user, resource);
  } catch (error) {
    console.error(error);
    return true;  // ← エラー時にアクセス許可は危険
  }
}

✅ 良い例

function checkPermission(user, resource) {
  try {
    return authService.hasAccess(user, resource);
  } catch (error) {
    logger.error('Permission check failed', { user, resource, error });
    alerting.notify('security', 'Permission check error');
    return false;  // ✅ エラー時は拒否
  }
}

フェイルセーフの実装例:

  • • 認証サービスがダウン → 全リクエストを拒否
  • • 設定ファイル読み込み失敗 → 最も厳しいデフォルト設定を使用
  • • レート制限チェック失敗 → リクエストを拒否
  • • 不明な権限 → 拒否として扱う
5
監査とトレーサビリティ

全ての重要な操作を記録し、いつ・誰が・何をしたか追跡可能にする。

記録すべき情報:

認証関連

  • • ログイン成功/失敗
  • • パスワード変更
  • • 権限変更
  • • セッション作成/破棄

データ操作

  • • 個人情報の閲覧
  • • データの作成/更新/削除
  • • エクスポート操作
  • • 設定変更

ログの例(構造化JSON)

{
  "timestamp": "2024-01-05T10:30:00Z",
  "event": "data_access",
  "user_id": "user_123",
  "user_ip": "203.0.113.42",
  "resource": "user_profile",
  "resource_id": "profile_789",
  "action": "read",
  "status": "success",
  "metadata": {
    "user_agent": "Mozilla/5.0...",
    "session_id": "sess_abc"
  }
}

注意: ログには機密情報(パスワード、トークン、クレジットカード番号など)を記録しない。

頻出脆弱性と対策

高リスク
SQLインジェクション

❌ 危険なコード

const query = `SELECT * FROM users WHERE email = '${email}'`;
// email = "' OR '1'='1" で全ユーザー情報が漏洩

✅ 安全なコード

const query = 'SELECT * FROM users WHERE email = ?';
const result = await db.execute(query, [email]);
// プリペアドステートメントで安全
高リスク
XSS(Cross-Site Scripting)

❌ 危険なコード

<div innerHTML={userComment} />
// userComment = "<script>...</script>" でスクリプト実行

✅ 安全なコード

<div>{userComment}</div>
// Reactが自動エスケープ、またはDOMPurifyでサニタイズ
中リスク
認証情報の漏洩

環境変数、ハードコーディング、Gitコミットからの漏洩を防ぐ。

対策:

  • • `.env`ファイルを`.gitignore`に追加
  • • AWS Secrets Manager等のシークレット管理サービスを使用
  • • コミット前にgit-secretsでスキャン
  • • 本番環境の認証情報は開発環境と完全に分離
中リスク
CSRF(Cross-Site Request Forgery)

ユーザーの意図しない操作を外部サイトから実行させる攻撃。

対策:

  • • CSRFトークンを発行し、リクエストごとに検証
  • • SameSite Cookie属性を設定(`SameSite=Strict`)
  • • 重要な操作は再認証を要求
  • • Originヘッダーを検証

セキュリティチェックリスト

認証・認可

  • □ パスワードは必ずハッシュ化(bcrypt, Argon2)
  • □ 多要素認証(MFA)を実装
  • □ セッショントークンは予測不可能な値
  • □ ログイン試行回数制限(レートリミット)
  • □ パスワードリセットは安全なフロー

データ保護

  • □ 通信は全てHTTPS化
  • □ 個人情報は暗号化して保存
  • □ 不要になったデータは確実に削除
  • □ バックアップも暗号化
  • □ データベースは暗号化(TDE)

入力検証

  • □ 全ての入力をサーバー側で検証
  • □ ホワイトリスト方式で許可
  • □ ファイルアップロードは厳格に制限
  • □ Content-Type を検証
  • □ サイズ制限を実装

運用・監視

  • □ セキュリティログを記録
  • □ 異常検知の仕組みを実装
  • □ 定期的な脆弱性スキャン
  • □ 依存ライブラリの更新
  • □ インシデント対応手順を文書化

まとめ

セキュリティは設計段階から組み込むことで、コストを削減しながら高い安全性を確保できます。後付けのセキュリティ対策は、コストが10〜20倍になることも珍しくありません。

最小権限の原則、多層防御、セキュアなデフォルト設定、フェイルセーフ、監査とトレーサビリティ。これら5つの原則を設計段階で組み込むことが、セキュアなシステムの基盤となります。

弊社では、これらの設計原則を適用することで、脆弱性発見数を平均78%削減し、セキュリティ対応コストを年間420万円削減、インシデント発生率を92%低下させることに成功しています。

この記事をシェア:

おすすめの記事

株式会社Apple Seed - システム開発・AI開発