C
セキュリティ/攻撃/Lesson 02

Web攻撃 — OWASP Top 10 + XSS · CSRF · SQLインジェクション

45分·theory

Web攻撃 — OWASP Top 10 + XSS · CSRF · SQLインジェクション

🎯 このlessonを読み終えたら

このlessonを最後まで読み終えると、以下の3つを自信を持って実践できます。

  • ✅ OWASP Top 10のTop 5を暗記する
  • ✅ SQLインジェクション · XSS · CSRFの防御コードパターン
  • ✅ PreparedStatement / DOMPurify / SameSiteの活用

学習目標をチェックリストとして手元に置き、すべて答えられるようになったらlessonを閉じてください。

OWASP Top 10 (2021) — 最も危険なWebの脆弱性

一言で言うと: OWASP = 非営利のセキュリティ団体。Top 10は最も一般的なWebの脆弱性カテゴリ一覧。面接の定番テーマ。

順位カテゴリ意味
A01Broken Access Control認可チェックの欠如 → 他ユーザーのデータへのアクセス
A02Cryptographic Failures平文通信 · 弱いハッシュ · 鍵の漏洩
A03InjectionSQL · NoSQL · コマンド · LDAPインジェクション
A04Insecure Design設計段階でのセキュリティ上の欠陥
A05Security Misconfigurationデフォルトパスワード · デバッグモード · 管理者ページの露出
A06Vulnerable Components古いライブラリ · 未パッチのCVE
A07Auth Failuresブルートフォース攻撃 · セッション固定
A08Software & Data Integrity未検証のアップデート · CI/CDの侵害
A09Logging Failures侵入の痕跡を検知できない
A10SSRFサーバーが外部リクエストを実行 → 内部ネットワークへのアクセス

> 💡 A01 · A03 · A07が最も頻繁に発生します。入社後の最初のコードレビューで100%遭遇します。

XSS · CSRF · SQLインジェクション — 3大よくある攻撃

XSS (クロスサイトスクリプティング) — 悪意のあるスクリプトの注入

種類
Stored<script>steal()</script>をDBに保存 → ページ訪問者全員に実行される
ReflectedURLパラメータ ?q=<script> → レスポンスにそのまま反映 → クリック時に実行
DOM-basedJSが location.hash などをそのまま innerHTML に設定

XSSの4つの防御策:
1. 出力のエスケープ<&lt;(React · Vueがデフォルトで処理)
2. CSP (Content-Security-Policy) — 信頼できるスクリプトのみ許可
3. httpOnlyクッキー — JSからセッショントークンにアクセス不可
4. innerHTMLの代わりにtextContentを使用


CSRF (クロスサイトリクエストフォージェリ) — 別サイトが自分の認証情報でリクエストを実行

  • 例: evil.comのページに <img src="bank.com/transfer?to=hacker&amt=999"> を埋め込む
  • ブラウザが自動的にbank.comのクッキーを添付 → 送金が実行される

CSRFの防御策:

  • CSRFトークン — フォームにランダムなトークンを埋め込み、サーバーが検証。Spring Securityがデフォルトで提供
  • SameSiteクッキーSameSite=Lax/Strict — 外部ドメインからクッキーを送信しない
  • Origin/Refererの検証 — リクエストの送信元を確認

SQLインジェクション — ユーザー入力がSQLの一部になる

  • ❌ 脆弱: "SELECT * FROM users WHERE id='" + input + "'"
  • 入力: 1' OR '1'='1 → 全行が返される
  • 入力: 1'; DROP TABLE users; -- → テーブルが削除される

防御策:

  • パラメータ化クエリ (Prepared Statement):
python
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
  • ORMの使用 (SQLAlchemy · Hibernate · Prisma) — 自動エスケープ
  • 入力のホワイトリスト — 数値やUUIDなど明確なフォーマットのみ受け付ける

> ⚠️ 「'をエスケープすれば安全」は誤った通念です。常にパラメータ化クエリを使用してください。

💻 📌 攻撃防御コード例 (Spring + Node)
// === Spring Security — CSRF + XSS + ヘッダー ===
@Configuration
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
            // CSRF — Spring Security デフォルト有効
            .csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
            // セキュリティヘッダー
            .headers(h -> h
                .contentSecurityPolicy(csp -> csp.policyDirectives("default-src 'self'"))
                .frameOptions(f -> f.deny())              // Clickjacking 防御
                .xssProtection(xss -> xss.disable())      // モダンブラウザはCSPを推奨
                .httpStrictTransportSecurity(hsts -> hsts.maxAgeInSeconds(31536000))
            )
            // クッキーセキュリティ
            .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .build();
    }
}

// === Parameterized Query — Spring JPA ===
// ❌ 脆弱 (絶対 X):
// @Query("SELECT u FROM User u WHERE u.name = '" + name + "'")
// ✅ 安全:
public interface UserRepo extends JpaRepository<User, Long> {
    @Query("SELECT u FROM User u WHERE u.name = :name")
    Optional<User> findByName(@Param("name") String name);
}

// ─────────────────────────────────────────────────
// Node.js (Express) 例
// ─────────────────────────────────────────────────
/*
const helmet = require('helmet');
const csrf = require('csurf');

app.use(helmet());                 // セキュリティヘッダー自動
app.use(csrf({ cookie: true }));   // CSRFトークン自動検証
app.use(express.json({ limit: '10kb' }));   // payload制限

// XSS - React が基本で escape。dangerouslySetInnerHTML のみ注意

// SQL Injection - pg parameterized
const result = await pool.query(
  'SELECT * FROM users WHERE id = $1',     // $1 placeholder
  [userId]                                  // 値
);

// クッキー
app.use(session({
  cookie: { httpOnly: true, secure: true, sameSite: 'lax' }
}));
*/

🤖 AIにこう依頼してみましょう

このlessonの概念を理解すれば、AIに具体的に指示できるようになります。漠然とした「直して」ではなく、語彙を持った依頼をすること — それがトークン節約の出発点です。

  • 「このコードのSQLインジェクション / XSS / CSRFの脆弱性を確認して」
  • 「この入力値の検証をホワイトリスト方式で強化して」

なぜこれがトークンを減らすのか

概念を知らないと、AIの回答を受け取っても「それって何ですか?」と再度尋ねなければなりません。その「再質問」がトークンを消費します。概念を一度学んでおけば、会話が一度で完結します。

Web攻撃 — OWASP Top 10 + XSS・CSRF・SQLインジェクション - セキュリティ