diff --git a/index.js b/index.js new file mode 100644 index 0000000..322b994 --- /dev/null +++ b/index.js @@ -0,0 +1,18 @@ +'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 'self:'; img-src 'self'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; 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); +}; \ No newline at end of file diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..d7612f0 --- /dev/null +++ b/main.tf @@ -0,0 +1,77 @@ +data "aws_partition" "current" {} + + +resource "aws_iam_role" "execution_role" { + name = "${var.name}-execution-role" + assume_role_policy = <<-EOF + { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Principal": { + "Service": [ + "lambda.amazonaws.com", + "edgelambda.amazonaws.com" + ] + }, + "Effect": "Allow", + "Sid": "" + } + ] + } + EOF + tags = var.tags +} + +data "aws_iam_policy_document" "execution_role" { + statement { + sid = "AllowCloudWatchLogs" + actions = [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ] + effect = "Allow" + resources = [ + format( + "arn:%s:logs:*::log-group:/aws/lambda/*:*:*", + data.aws_partition.current.partition + ) + ] + } +} + +resource "aws_iam_policy" "execution_role" { + name = "${var.name}-policy" + path = "/" + policy = data.aws_iam_policy_document.execution_role.json +} + +resource "aws_iam_role_policy_attachment" "execution_role" { + role = aws_iam_role.execution_role.name + policy_arn = aws_iam_policy.execution_role.arn +} + +data "archive_file" "this" { + type = "zip" + source_file = "${path.module}/index.js" + output_path = "${path.module}/deploy.zip" +} + +resource "aws_lambda_function" "this" { + function_name = var.name + description = "Adds security headers for Cloudfront" + filename = data.archive_file.this.output_path + source_code_hash = data.archive_file.this.output_base64sha256 + handler = "index.handler" + runtime = "nodejs12.x" + role = aws_iam_role.execution_role.arn + timeout = var.timeout + memory_size = var.memory_size + publish = true + tags = var.tags + depends_on = [ + data.archive_file.zip + ] +} \ No newline at end of file diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..7bc6659 --- /dev/null +++ b/outputs.tf @@ -0,0 +1,3 @@ +output "lambda_arn" { + value = aws_lambda_function.this.qualified_arn +} \ No newline at end of file diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..032ffbf --- /dev/null +++ b/variables.tf @@ -0,0 +1,22 @@ +variable "tags" { + default = {} + type = map(string) + description = "Tags to add to resouces created by this module" +} + +variable "name" { + type = string + description = "Name to use for resource names created by this module" +} + +variable "timeout" { + type = number + default = 1 + description = "Timeout to use for Lambda, defaults to 1ms" +} + +variable "memory_size" { + type = number + default = 128 + description = "Memory to use for Lambda, defaults to 128mb" +} \ No newline at end of file