サイトアイコン 協栄情報ブログ

CloudFrontディストリビューションにセキュリティヘッダーを追加する方法

CloudFrontディストリビューションにセキュリティヘッダーを追加する方法

AWS CloudFrontは、世界中のエッジロケーションでコンテンツをキャッシュし、高速に配信できるCDNサービスです。クラウドフロントを使用してS3バケットなどのオリジンから配信されるコンテンツに対し、セキュリティヘッダーを付与することで、Webサイトのセキュリティを強化できます。この記事では、CloudFormationを利用してLambda@EdgeでCloudFrontにセキュリティヘッダーを追加する方法を説明します。

前提条件

  1. CloudFrontディストリビューション:S3をオリジンとして設定します。
  2. Lambda@Edge:CloudFrontディストリビューションのレスポンスに対してカスタムセキュリティヘッダーを追加するためにLambda関数を作成し、Edgeでの実行を設定します。

セキュリティヘッダーとは?

セキュリティヘッダーは、ブラウザがWebページをより安全にレンダリングするための指示を含むHTTPレスポンスヘッダーです。以下のヘッダーをCloudFrontディストリビューションに追加することで、Webアプリケーションのセキュリティを高めます。

  1. Strict-Transport-Security (HSTS)

    • 指示:ブラウザに対し、指定された期間中、HTTPS接続を強制する。
    • 例:Strict-Transport-Security: max-age=63072000; includeSubdomains; preload
    • 効果:HTTPからHTTPSへのリダイレクトにより、通信内容の傍受や中間者攻撃を防ぎます。
    • 属性:
      • max-age: 有効期限(秒単位)。例えば「63072000」は2年間を意味します。
      • includeSubdomains: サブドメインも含む。
      • preload: HSTSプリロードリストへの登録用のオプション。
  2. X-Content-Type-Options

    • 指示:ブラウザに対し、MIMEタイプの宣言を無視しないよう指示する。
    • 例:X-Content-Type-Options: nosniff
    • 効果:コンテンツのMIMEタイプが正確に宣言されていない場合でも、ブラウザが独自にファイルタイプを判別することを防ぎます。これにより、クロスサイトスクリプティング(XSS)やMIMEスニッフィング攻撃のリスクを低減します。
  3. X-Frame-Options

    • 指示:ブラウザに対し、指定したページをフレーム内でレンダリングしないよう指示する。
    • 例:X-Frame-Options: DENY
    • 効果:ページをフレーム内に表示することを禁止するため、クリックジャッキング攻撃を防止します。
  4. X-XSS-Protection

    • 指示:XSS(クロスサイトスクリプティング)フィルターを有効化。
    • 例:X-XSS-Protection: 1; mode=block
    • 効果:ブラウザのXSSフィルターをオンにし、攻撃が検知された場合にページのレンダリングを停止します。

CloudFormationでLambda@Edgeを設定してセキュリティヘッダーを追加

以下のCloudFormationテンプレート例では、Lambda関数を定義し、CloudFrontディストリビューションのビヘイビアにセキュリティヘッダーを追加する処理を行います。

CloudFormationテンプレート例

Resources:
  # Lambda関数の作成 (セキュリティヘッダーを追加)
  EdgeLambdaFunction:
    Type: AWS::Lambda::Function
    Properties: 
      FunctionName: InsertSecurityHeaders
      Handler: index.handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile: |
          exports.handler = async (event) => {
              const response = event.Records[0].cf.response;
              const headers = response.headers;

              headers['strict-transport-security'] = [{key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubdomains; preload'}];
              headers['x-content-type-options'] = [{key: 'X-Content-Type-Options', value: 'nosniff'}];
              headers['x-frame-options'] = [{key: 'X-Frame-Options', value: 'DENY'}];
              headers['x-xss-protection'] = [{key: 'X-XSS-Protection', value: '1; mode=block'}];

              return response;
          };
      Runtime: nodejs14.x
      MemorySize: 128
      Timeout: 5

  # Lambdaの実行ロール
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: LambdaEdgePolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: '*'

  # CloudFrontディストリビューションの作成
  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Origins:
          - DomainName: your-s3-bucket.s3.amazonaws.com
            Id: S3Origin
            S3OriginConfig: {}
        DefaultCacheBehavior:
          TargetOriginId: S3Origin
          ViewerProtocolPolicy: redirect-to-https
          LambdaFunctionAssociations:
            - EventType: origin-response
              LambdaFunctionARN: !GetAtt EdgeLambdaFunction.Arn
        Enabled: true

設定のポイント

これで、CloudFormationテンプレートを利用して、CloudFrontディストリビューションにセキュリティヘッダーを追加する設定が完了です。セキュリティヘッダーを適切に設定することで、クロスサイトスクリプティングやクリックジャッキングといったさまざまな攻撃からWebサイトを保護できます。

このコードはCloudFrontレスポンスにセキュリティヘッダーを追加するLambda関数を作成するCloudFormationテンプレートの一部です。
以下で各セクションの詳細を説明します。
CloudFormationでレスポンスヘッダーポリシー (AWS::CloudFront::ResponseHeadersPolicy) を作成し、セキュリティヘッダーを追加する基本的なテンプレート例を以下に示します。
このテンプレートでは、Content Security Policy、HSTS、XSS Protection、Frame Options など、よく使用されるセキュリティヘッダーを設定します。

Resources:
  MyResponseHeadersPolicy:
    Type: AWS::CloudFront::ResponseHeadersPolicy
    Properties: 
      ResponseHeadersPolicyConfig: 
        Name: SecurityHeadersPolicy
        Comment: "Response Headers Policy with Security Headers"

        # セキュリティヘッダーの設定
        SecurityHeadersConfig: 
          ContentSecurityPolicy: 
            ContentSecurityPolicy: "default-src 'self'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'; frame-ancestors 'none';"
            Override: true
          ContentTypeOptions:
            Override: true  # X-Content-Type-Options: nosniff
          FrameOptions: 
            FrameOption: DENY  # X-Frame-Options: DENY
            Override: true
          ReferrerPolicy: 
            ReferrerPolicy: no-referrer  # Referrer-Policy: no-referrer
            Override: true
          StrictTransportSecurity: 
            AccessControlMaxAgeSec: 63072000  # HSTS (max-age 2 years)
            IncludeSubdomains: true
            Preload: true
            Override: true
          XSSProtection: 
            Protection: true
            ModeBlock: true  # X-XSS-Protection: 1; mode=block
            Override: true

        # カスタムヘッダーの設定 (任意)
        CustomHeadersConfig: 
          Items: 
            - Header: X-Custom-Header
              Value: CustomValue
              Override: true

各プロパティの説明

使用方法

このテンプレートをCloudFormationスタックにデプロイすることで、SecurityHeadersPolicy という名前のレスポンスヘッダーポリシーが作成され、CloudFrontディストリビューションで再利用可能になります。このポリシーをCloudFrontディストリビューションに関連付けることで、指定したセキュリティヘッダーがレスポンスに追加されます

レスポンスヘッダーポリシー (ResponseHeadersPolicy)
CloudFrontに直接設定でき、CORSやセキュリティヘッダーの追加が簡単に行えます。
複数のCloudFrontディストリビューションで共有・再利用可能なため、設定が一貫します。
設定可能なヘッダーが限定されており、細かい条件での追加や動的な制御には制限があります。
メンテナンスや運用が簡単なため、基本的なセキュリティヘッダーを一貫して追加する場合に便利です。

Lambda@Edgeを使用すると、レスポンスヘッダーを動的に追加・変更できます。
レスポンス内容に応じたカスタマイズや、特定の条件下でのみヘッダーを追加するなどの柔軟な制御が可能です。
Lambda実行の追加コストが発生します。
複雑なヘッダー処理が必要な場合や、CloudFrontの標準設定だけでは対応できない場合に役立ちます。
基本的なセキュリティヘッダーのみであれば、レスポンスヘッダーポリシーを作成する方が簡単で管理も楽です。しかし、条件によって異なるヘッダーを設定したい場合や、動的にヘッダーを追加する必要がある場合は、Lambda@Edgeの活用が効果的です。

モバイルバージョンを終了