Skip to content

Feature Suggestion: Integrate lambda@edge to allow adding HTTP Security Headers #36

@NikitaKoren

Description

@NikitaKoren

Overview
It would be great if fullstack-serverless exposed an option, potentially called headers that would allow to set any custom headers for the static content using lambda@edge or some other solution.

I found it difficult to set any security headers since s3 bucket and cloudfront support very limited amount of headers. Specifically, almost none of the commonly used headers for security hardening like Strict Transport Security, Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, Referrer-Policy (infosec.mozilla).

Possible Solution with lambda@edge

Screen Shot 2021-02-22 at 9 58 34 PM

Here is how the process works:

  1. Viewer requests website www.example.com.
  2. If the object is cached already, CloudFront returns the object from the cache to the viewer, otherwise it moves on to step 3.
  3. CloudFront requests the object from the origin, in this case an S3 bucket.
  4. S3 returns the object, which in turn causes CloudFront to trigger the origin response event.
  5. Our Add Security Headers Lambda function triggers, and the resulting output is cached and served by CloudFront.

Edge function source

'use strict';
exports.handler = (event, context, callback) => {
    
    //Get contents of response
    const response = event.Records[0].cf.response;
    const headers = response.headers;

    //Set new headers 
    headers['strict-transport-security'] = [{key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubdomains; preload'}]; 
    headers['content-security-policy'] = [{key: 'Content-Security-Policy', value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"}]; 
    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'}]; 
    headers['referrer-policy'] = [{key: 'Referrer-Policy', value: 'same-origin'}]; 
    
    //Return modified response
    callback(null, response);
};

Reference


As of right now, one of the workarounds is to setup lambda@edge manually and map it to the cloudfront distribution created by the fullstack-serverless plugin. In addition, you will need to configure Basic Lambda Execution Policy allowing logs to be written to CloudWatch and Trust Relationship allowing Lambda and Lambda@Edge to assume the role. (configuring-x-frame-options-response-header-on-aws-cloudfront-and-s3).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions