メインコンテンツまでスキップ

HTTPセキュリティ

Zeltは、2つの自動登録されるmiddlewareクラス SecureHeadersMiddlewareCorsMiddleware を通じて、組み込みのHTTPセキュリティを提供します。どちらもすべてのHTTPアプリにグローバルに登録され、あなたが設定したグローバルmiddlewareより先に、すべてのrouteで実行されます。

設定は SecureHeadersConfigCorsConfig を通じて制御します。どちらも型安全でDIベースの設定のための @Config デコレータパターンを使用します。

  • SecureHeadersConfig は、安全なデフォルト値でデフォルトで有効になっています
  • CorsConfig はデフォルトで無効(空のorigin)で、明示的に設定する必要があります

SecureHeadersConfig

セキュリティヘッダーはすべてのレスポンスに自動的に適用されます。デフォルト設定では推奨されるセキュリティヘッダーが有効になります。

デフォルトヘッダー

ヘッダーデフォルト
Cross-Origin-Resource-Policysame-origin
Cross-Origin-Opener-Policysame-origin
Origin-Agent-Cluster?1
Referrer-Policyno-referrer
Strict-Transport-Securitymax-age=15552000; includeSubDomains
X-Content-Type-Optionsnosniff
X-DNS-Prefetch-Controloff
X-Download-Optionsnoopen
X-Frame-OptionsSAMEORIGIN
X-Permitted-Cross-Domain-Policiesnone
X-XSS-Protection0
X-Powered-By削除される
Cross-Origin-Embedder-Policy無効

ヘッダーのカスタマイズ

SecureHeadersConfig を継承し、プロパティをoverrideしてヘッダー値をカスタマイズします:

import { Config, SecureHeadersConfig } from '@zeltjs/core';

@Config
class MySecureHeadersConfig extends SecureHeadersConfig {
  override readonly xFrameOptions = 'DENY';

  override readonly referrerPolicy = 'strict-origin-when-cross-origin';
}

ヘッダーの無効化

ヘッダープロパティを false に設定すると無効になります:

import { Config, SecureHeadersConfig } from '@zeltjs/core';

@Config
class MySecureHeadersConfig extends SecureHeadersConfig {
  override readonly xXssProtection = false;

  override readonly xDownloadOptions = false;
}

CorsConfig

CORSはデフォルトで無効です。有効にするには、CorsConfig を継承して origin プロパティを設定します。

CORSの有効化

import { Config, CorsConfig } from '@zeltjs/core';

@Config
class MyCorsConfig extends CorsConfig {
  override readonly origin = 'https://example.com';
}

複数のOrigin

import { Config, CorsConfig } from '@zeltjs/core';

@Config
class MyCorsConfig extends CorsConfig {
  override readonly origin = ['https://app.example.com', 'https://admin.example.com'];
}

利用可能なオプション

オプションデフォルト説明
originstring | string[][]許可するorigin(空の場合CORSは無効)
credentialsbooleanfalsecredentialを許可する
allowMethodsstring[]['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH']許可するHTTPメソッド
allowHeadersstring[][]許可するrequestヘッダー
exposeHeadersstring[][]clientに公開するヘッダー
maxAgenumber | undefinedundefinedpreflightキャッシュの秒数

設定の全体例

import { Config, CorsConfig } from '@zeltjs/core';

@Config
class MyCorsConfig extends CorsConfig {
  override readonly origin = 'https://example.com';

  override readonly credentials = true;

  override readonly allowHeaders = ['Content-Type', 'Authorization'];

  override readonly exposeHeaders = ['X-Request-Id'];

  override readonly maxAge = 86400;
}

登録

middlewareクラスは自動的に登録されます。アプリ作成時にカスタムconfigを登録します:

import { createApp, Config, CorsConfig, SecureHeadersConfig, Controller, Get, http } from '@zeltjs/core';

@Config
class MyCorsConfig extends CorsConfig {
  override readonly origin = 'https://example.com';
  override readonly credentials = true;
}

@Config
class MySecureHeadersConfig extends SecureHeadersConfig {
  override readonly xFrameOptions = 'DENY';
}

@Controller('/') class AppController { @Get('/') index() { return { ok: true }; } }

const app = createApp([http({
    controllers: [AppController],
  })], { configs: [MyCorsConfig, MySecureHeadersConfig] });

frameworkは、configs 配列に登録されたカスタム設定クラスを自動的に検出して使用します。

セキュリティmiddlewareのスキップ

@SkipMiddleware を使うと、1つのendpointまたはcontroller内のすべてのendpointについて、いずれかの組み込みmiddlewareをスキップできます。メソッドレベルとcontrollerレベルのスキップは組み合わされます。

import {
  Controller,
  CorsMiddleware,
  Get,
  SecureHeadersMiddleware,
  SkipMiddleware,
} from '@zeltjs/core';

@SkipMiddleware(CorsMiddleware)
@Controller('/webhook')
class WebhookController {
  @Get('/health')
  health() {
    return { ok: true };
  }

  @SkipMiddleware(SecureHeadersMiddleware)
  @Get('/raw')
  raw() {
    return { ok: true };
  }
}

この例では、WebhookController のendpointへのnon-preflightリクエストはCORSレスポンスヘッダーをスキップします。/webhook/raw endpointはセキュリティヘッダーもスキップします。

@SkipMiddleware(CorsMiddleware) はCORS preflightの処理を無効にしません。OPTIONS preflightリクエストは、endpoint handlerが選択される前に CorsMiddleware によって処理されるため、preflightレスポンスにはCORS allowヘッダーが引き続き含まれる場合があります。CorsMiddleware をスキップするのは、実際のendpointレスポンスの部分です。