Actix Web における HTTP セキュリティヘッダーの実装と設定戦略

Actix Web におけるセキュリティヘッダーの重要性

Rust 用の Web フレームワークである Actix Web は、高いパフォーマンスと実用性を兼ね備えています。しかし、高速なアプリケーションを構築する際、セキュリティ対策を怠ると重大な脆弱性につながる可能性があります。HTTP レスポンスヘッダーの適切な設定は、クロスサイトスクリプティング(XSS)やクリックジャッキングといった一般的な攻撃からユーザーを保護するための第一線となります。

本稿では、Actix Web のミドルウェア機能を利用し、アプリケーションの堅牢性を高めるための具体的なヘッダー設定手法について解説します。

DefaultHeaders ミドルウェアの活用

Actix Web では、DefaultHeaders ミドルウェアを使用することで、レスポンスに共通のヘッダーを付加できます。このミドルウェアの挙動として、既に存在するヘッダーを上書きせず、欠落している場合にのみ追加されるという特徴があります。これにより、特定のルートで個別に設定されたヘッダーとの競合を防ぎつつ、アプリケーション全体に一貫したセキュリティポリシーを適用可能です。

基本的な導入方法は以下の通りです。

use actix_web::{web, middleware, App, HttpResponse};

fn main() {
    let web_app = App::new()
        .wrap(middleware::DefaultHeaders::new()
            .add(("X-Content-Type-Options", "nosniff"))
            .add(("X-Frame-Options", "SAMEORIGIN")))
        .service(web::resource("/").to(|| HttpResponse::Ok()));
}

XSS 対策と Content-Security-Policy

クロスサイトスクリプティング攻撃を防ぐためには、Content-Security-Policy (CSP) の設定が最も効果的です。CSP は、ブラウザが読み込むことができるリソースのソースを制限し、不正なスクリプトの実行をブロックします。

例えば、スクリプトの実行を自社ドメインと信頼された CDN のみに限定する設定は以下のようになります。

middleware::DefaultHeaders::new()
    .add(("Content-Security-Policy", 
        "default-src 'self'; script-src 'self' https://static.example.net"))

また、レガシーなブラウザにおける XSS フィルターを強制有効化するために、X-XSS-Protection ヘッダーも併せて設定することが推奨されます。

.add(("X-XSS-Protection", "1; mode=block"))

この設定により、ブラウザは攻撃を検知した場合にページをレンダリングせず、ブロック動作を取ります。

クリックジャッキング防止策

クリックジャッキングは、透明な iframe などを悪用してユーザーの操作を騙る攻撃です。X-Frame-Options ヘッダーを設定することで、ページが iframe 内に埋め込まれることを制御できます。

主な設定値は以下の通りです。

  • DENY: どのサイトからの埋め込みも禁止
  • SAMEORIGIN: 同一オリジンからの埋め込みのみ許可
  • ALLOW-FROM uri: 指定された URI からの埋め込みのみ許可

多くのケースでは、機能性と安全性のバランスを考慮し SAMEORIGIN が選択されます。

.add(("X-Frame-Options", "SAMEORIGIN"))

転送プロトコルとプライバシー保護

通信の暗号化を強制するには、Strict-Transport-Security (HSTS) ヘッダーが有効です。これにより、ブラウザは指定された期間内、HTTPS 接続のみを使用するように強制されます。

.add(("Strict-Transport-Security", "max-age=31536000; includeSubDomains"))

さらに、ユーザーのプライバシー保護のため、リファラー情報の送信を制御する Referrer-Policy の設定も重要です。

.add(("Referrer-Policy", "strict-origin-when-cross-origin"))

これにより、クロスオリジンリクエスト時にはオリジン情報のみが送信され、パスなどの詳細情報は含まれなくなります。

MIME タイプの自動判定(スニッフィング)を無効化し、予期しないファイル実行を防ぐためには、X-Content-Type-Options を設定します。

.add(("X-Content-Type-Options", "nosniff"))

統合設定の実装例

上記のセキュリティヘッダーを統合し、アプリケーション全体に適用するための設定例を示します。ミドルウェアのチェーン内で一貫したポリシーを定義することで、管理性を高めています。

use actix_web::{middleware, App};

fn build_secure_app() -> App {
    App::new()
        .wrap(middleware::DefaultHeaders::new()
            // 基本セキュリティ設定
            .add(("X-Content-Type-Options", "nosniff"))
            .add(("X-Frame-Options", "SAMEORIGIN"))
            .add(("X-XSS-Protection", "1; mode=block"))
            
            // CSP 設定
            .add(("Content-Security-Policy", 
                "default-src 'self'; script-src 'self' https://static.example.net; \
                 style-src 'self' 'unsafe-inline'; img-src 'self' data:;"))
            
            // 通信とプライバシー
            .add(("Referrer-Policy", "strict-origin-when-cross-origin"))
            .add(("Strict-Transport-Security", "max-age=31536000; includeSubDomains"))
            
            // 権限制御
            .add(("Permissions-Policy", "camera=(), microphone=(), geolocation=()"))
            .add(("X-Permitted-Cross-Domain-Policies", "none")))
        // 以降にルート定義を追加
}

設定の検証方法

セキュリティヘッダーが正しく適用されているかを確認するには、いくつかの方法があります。ブラウザの開発者ツールにある「ネットワーク」タブでレスポンスヘッダーを直接確認するのが最も簡単です。

また、コマンドラインツール curl を使用することで、自動化された検証やスクリプトによるチェックが可能になります。

curl -I https://service.example.io

さらに、Security Headers などのオンラインスキャナを利用することで、設定の妥当性や不足しているヘッダーを第三者の視点から評価することも有効です。

タグ: Actix-Web rust-lang web-security content-security-policy hsts

7月7日 21:57 投稿