Giter Site home page Giter Site logo

amazon-cloudfront-functions's Introduction

Amazon CloudFront Functions

This repository contains example CloudFront functions and instructions to deploy them to CloudFront.

Overview

CloudFront Functions is a serverless edge compute feature allowing you to run JavaScript code at the 225+ Amazon CloudFront edge locations for lightweight HTTP(S) transformations and manipulations. Functions is purpose-built to give you the flexibility of a full programming environment with the performance and security that modern web applications require. At a fraction of the price of AWS Lambda@Edge, CloudFront Functions can scale instantly and affordably to support millions of requests per second.

CloudFront Functions is natively built into CloudFront, allowing you to easily build, test, and deploy viewer request and viewer response functions entirely within CloudFront. This GitHub repo offers a collection of example code that can be used as a starting point for building functions. You can build functions using the IDE in the CloudFront console, or with the CloudFront APIs/CLI. Once your code is authored, you can test your function against a production CloudFront distribution, ensuring your function will execute properly once deployed. The test functionality in the console offers a visual editor to quickly create test events and validate functions. You can use CloudFront Functions in addition to the existing AWS Lambda@Edge capability that also allows you to run custom code in response to CloudFront events.

CloudFront functions are ideal for lightweight computation tasks on web requests. Some popular use cases are:

  • HTTP header manipulation : View, add, modify, or delete any of the request or response headers. For example, add HTTP Strict Transport Security (HSTS) headers to your response or copy the client IP address into a new HTTP header (like True-Client-IP) to forward this IP to the origin with the request.
  • URL rewrites and redirects : Generate a response from within CloudFront Functions to redirect requests to a different URL. For example, redirect a non-authenticated user from a restricted page to a paywall. You could also use URL rewrites for A/B testing a website.
  • Cache key manipulations and normalization : Transform HTTP request attributes (URL, headers, cookies, query strings) to construct the CloudFront cache key that is used for determining cache hits on future requests. By transforming the request attributes, you can normalize multiple requests to a single cache key, leading to an improved cache hit ratio.
  • Access authorization : Implement access control and authorization for the content delivered through CloudFront by creating and validating user-generated tokens, such as HMAC tokens or JSON web tokens (JWT), to allow or deny requests.

Example CloudFront functions

Example Description
Add a True-Client-IP request header True-Client-IP is an HTTP request header that you can add to incoming CloudFront requests so that the IP address of the viewer (client) is passed along to the origin.
Add HTTP security response headers This function adds several of the more common HTTP security headers to the response from CloudFront, including HTTP Strict Transport Security (HSTS), Content Security Policy (CSP), X-Content-Type-Options, X-Frame-Options, and X-XSS-Protection.
Perform URL rewrite for single page applications You can use this function to perform a URL rewrite to append "index.html" to the end of URLs that don’t include a filename or extension. This is particularly useful for single page applications or statically generated websites using frameworks like React, Angular, Vue, Gatsby, or Hugo.
URL redirect based on a user’s country This function redirects a user to a country-specific version of a site based on the country of the user. In this example, if the user is in Germany, the function redirects the user to the /de/index.html page which is the German version of the site. If the user is not in Germany, the request passes through with no modification to the URL.
Add origin request header if missing This function adds an origin header if it is not present on the incoming request. The origin header, part of cross-origin resource sharing (CORS), is a mechanism using HTTP headers to tell the web server which origin initiated this particular request.
Verify JSON Web Tokens This function performs a lightweight security token validation using JSON Web Tokens. You can use this type of tokenization to give a user of your site a URL that is time-bound. Once the predetermined expiration time has occurred, the user can no longer access the content at that URL.
Add CORS headers if missing This function adds an Access-Control-Allow-Origin response header if it is not present on the outgoing response from CloudFront.
Add a Cache-Control header This function adds a Cache-Control response header to the outgoing response from CloudFront for browser caching.

Deploying a CloudFront function using the AWS CLI

We will use the example that adds cache control headers to responses as our function, but the same process can be used for all the functions with only minor changes.

Step 1: Install the AWS CLI. If you already have the AWS CLI, upgrade to the most recent version.

Note: The examples below assume you are using version 2 of the AWS CLI. There are breaking changes between v1 and v2 of the AWS CLI, which can be found here. In v2 of the AWS CLI, binary parameters are passed as base64-encoded strings by default. If you are using v2 of the AWS CLI, you need to do one of the following:

  • You can tell the AWS CLI version 2 to revert to the AWS CLI version 1 behavior by specifying the following line in the ~/.aws/config file for a given profile: cli_binary_format=raw-in-base64-out
  • Pass all files using fileb://, which treats the file content as unencoded binary.

Step 2: Clone this repository.

Step 3: Change directories into the repo directory.

cd amazon-cloudfront-functions/

Step 4: Create a CloudFront function.

aws cloudfront create-function \
--name add-cache-control-headers \
--function-config Comment="Function to add cache-control headers",Runtime=cloudfront-js-1.0 \
--function-code fileb://add-cache-control-header/index.js

{
    "Location": "https://cloudfront.amazonaws.com/2020-05-31/function/arn:aws:cloudfront::XXXXXXXXXXXX:function/add-cache-control-headers",
    "ETag": "EXXXXXXXXXXXX,
    "FunctionSummary": {
        "Name": "add-cache-control-headers",
        "Status": "UNPUBLISHED",
        "FunctionConfig": {
            "Comment": "Function to add cache-control headers",
            "Runtime": "cloudfront-js-1.0"
        },
        "FunctionMetadata": {
            "FunctionARN": "arn:aws:cloudfront::XXXXXXXXXXXX:function/add-cache-control-headers",
            "Stage": "DEVELOPMENT",
            "CreatedTime": "2021-04-09T22:35:57.256000+00:00",
            "LastModifiedTime": "2021-04-09T22:35:57.256000+00:
        }
    }
}

Make sure you capture the ETag value, since you will need it to publish your function.

Step 5: Test the CloudFront function.

To test a function, you need to pass in a JSON request or response object used to simulate a viewer request or response. A sample of the event object format can be found here. This repo contains test events that you can use to test the example functions.

Test the function using the provided test event by running the following command, using the function's ETag (from the previous command's output) as the value for --if-match:

aws cloudfront test-function \
--name add-cache-control-headers \ 
--if-match EXXXXXXXXX \
--event-object fileb://add-cache-control-header/test-event.json

{
    "TestResult": {
        "FunctionSummary": {
            "Name": "add-cache-control-headers",
            "Status": "UNPUBLISHED",
            "FunctionConfig": {
                "Comment": "Function to add cache-control headers",
                "Runtime": "cloudfront-js-1.0"
            },
            "FunctionMetadata": {
                "FunctionARN": "arn:aws:cloudfront::XXXXXXXXXXXX:function/add-cache-control-headers",
                "Stage": "DEVELOPMENT",
                "CreatedTime": "2021-04-09T22:35:57.256000+00:00",
                "LastModifiedTime": "2021-04-09T22:35:57.256000+00:00"
            }
        },
        "ComputeUtilization": "16",
        "FunctionExecutionLogs": [],
        "FunctionErrorMessage": "",
        "FunctionOutput": "{\"response\":{\"headers\":{\"server\":{\"value\":\"CustomOriginServer\"},\"content-length\":{\"value\":\"9593\"},\"content-type\":{\"value\":\"text/html; charset=UTF-8\"},\"cache-control\":{\"value\":\"public, max-age=63072000;\"}},\"statusDescription\":\"OK\",\"cookies\":{\"loggedIn\":{\"attributes\":\"Secure; Path=/; Domain=example.com; Expires=Wed, 05 Jan 2024 07:28:00 GMT\",\"value\":\"true\"},\"id\":{\"attributes\":\"Expires=Wed, 05 Jan 2024 07:28:00 GMT\",\"value\":\"a3fWa\"}},\"statusCode\":200}}"
    }
}

The function is running successfully since we did not receive an error message and there is a FunctionOutput object returned. Inside the FunctionOutput object, we can see the cache-control header was added as expected.

Step 6: Publish your CloudFront function.

If you received a similar response (to the one above) from the test-function command, you can publish the function.

aws cloudfront publish-function \
--name add-cache-control-headers \
--if-match EXXXXXXXXX

{
    "FunctionSummary": {
        "Name": "add-cache-control-headers",
        "Status": "UNASSOCIATED",
        "FunctionConfig": {
            "Comment": "Function to add cache-control headers",
            "Runtime": "cloudfront-js-1.0"
        },
        "FunctionMetadata": {
            "FunctionARN": "arn:aws:cloudfront::XXXXXXXXXXXX:function/add-cache-control-headers",
            "Stage": "LIVE",
            "CreatedTime": "2021-04-09T22:35:57.256000+00:00",
            "LastModifiedTime": "2021-04-09T22:35:57.256000+00:00"
        }
    }
}

Step 7: Associate to a CloudFront distribution cache behavior.

First, get the current configuration of the distribution where you want to add the CloudFront function.

aws cloudfront get-distribution-config --id EXXXXXXXXXXXXX --output json > dist-cfg.json

Edit the JSON file (dist-cfn.json) to add a CloudFront function association. The following shows an example CloudFront function association, which you add to one of the distribution’s cache behaviors. Use the ARN of the function that you created in a previous step.

"FunctionAssociations": {
    "Quantity": 1,
    "Items": [
        {
            "EventType": "viewer-response",
            "FunctionARN": "arn:aws:cloudfront::XXXXXXXXXXXX:function/add-cache-control-headers"
        }
    ]
}

Also, make sure to change the ETag key name in the JSON file to IfMatch.

When you finish editing the JSON file, run this command to add the CloudFront function association to your distribution.

aws cloudfront update-distribution --id EXXXXXXXXXXXXX --cli-input-json fileb://dist-cfg.json

When your distribution’s status changes from InProgress to Deployed (this takes a few minutes), your CloudFront function is deployed and live at all CloudFront edge locations worldwide.

License

This project is licensed under the Apache-2.0 License.

amazon-cloudfront-functions's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

amazon-cloudfront-functions's Issues

anti-hotlinking with referer header

Some users want to protect against hotlinking. A simple way is checking the value of Referer header with a CloudFront Functions function. The request will be rejected if the referer is not in the allow list.

There is a Lambda@Edge code example on Github, but no CloudFront Functions code.

The following is my CFF code. It has been tested in my environment and has been deployed in the production of a few customers. I was wondering if it is useful for this project?

//Escape "." character in a string
RegExp.escape = function(string) {
    return string.replace(/\./g, '\\.');
};

function handler(event) {
    var request = event.request;
    var headers = request.headers;

    var referrer = headers['referer'];

    var response = {
        statusCode: 403,
        statusDescription: 'Forbidden',
        headers: {
            'content-type': { 'value': 'text/plain' }
        },
        body: 'Invalid referrer domain'
    };

    // Allow requests without the Referer header
    if (!referrer) return request;
    // Or block requests without the Referer header
    // if (!referrer) return response;

    var fqdn = referrer['value'].split('/')[2];

    // Input your allowed domain name here
    var allowedDomains = [
        'domain1.com',
        '*.domain1.com',
        'domain2.com',
        '*.domain2.com',
        'sub.domain3.com',
        '*.sub.domain3.com'
    ];

    var allowedRegexList = [];

    //Convert string to regex
    for (var i=0; i<allowedDomains.length; i++) {
        var domainName = allowedDomains[i];
        if (domainName.startsWith('*')) {
            domainName = domainName.replace('*', '');
            var reg = new RegExp(RegExp.escape(domainName) + '$');
        } else {
            reg = new RegExp('^' + RegExp.escape(domainName) + '$');
        }
        allowedRegexList.push(reg);
    }

    var matchFound = false;
    for (var j=0; j<allowedRegexList.length; j++) {
        if (fqdn.match(allowedRegexList[j])) {
            matchFound = true;
            break;
        }
    }

    if (!matchFound) return response;

    return request;
}

Improving caching key

There is no example on one of the most frequent use-cases (also one mentioned in the docs as an example usage of CloudFront Functions) of improving caching key and using queryparams.

I've managed to use it to sort values within a comma-separated param, but how do I e.g. sort the queryparams themselves?

Using cloudfron functions to remove server header

I currently have a cloudfront that responds with the path /login/<client-A> and I would like to remove the server header from the response. It's possible?

I tried this code:

function handler(event) {
    var response = event.response;
    var headers = response.headers;

    headers['x-content-type-options'] = { value: 'nosniff'}; 
    headers['x-frame-options'] = {value: 'DENY'}; 
    headers['x-xss-protection'] = {value: '1; mode=block'};
    headers['referrer-policy'] = {value:  #'same-origin'};
    headers['server'] = {value: '*'};

    return response;
}

But it only worked when I accessed the cloudfront from the root path /:

Screen Shot 2021-12-09 at 13 30 00

With the path /login/<client> I got the following result, but it's not what I want:

Screen Shot 2021-12-09 at 13 31 15

Redirect naked to www example

It would be helpful for me to have an example of how to redirect naked to www (e.g. requests to domain.com should 301 to www.domain.com). When migrating from lambda@edge to cloudfront functions, some things seemed to change, like the structure of the "event" parameter, and it was a little confusing to me at first.

I'm also not sure if best practice is that it's more efficient/cheaper to use lambda@edge Origin Request for this type of an operation (because it can then be cached for a long time on subsequent requests), or cloudfront function Viewer Request.

Thanks

Decrypt a Cookie

There is a function to validate a JWT token passed in the QueryString, but is there a way to decrypt a cookie as well?

What I am attempting to do is decrypt a cookie, check the information for the user in said cookie and add a header that identifies the user as authenticated.

The function would then add a header to the request identifying the user as such. This would allow us to serve protected content cached at CloudFront as opposed to going deeper into our stack.

Security header CSP: add nonce support

My organization needs for compliancy a really secure CSP to be on our cloudfront distribution. Currently I host my index.html file on a API gateway instead of our s3 bucket to allow me add nonces to style an scripts blocks.

Lambda function I use on this API gate way is as follows:

const crypto = require('crypto')
const fs = require('fs')
const cheerio = require('cheerio')

exports.handler = (event, context, callback) => {
    const $ = cheerio.load(fs.readFileSync('./index.html').toString('utf-8'))
    const nonce = crypto.randomBytes(16).toString('base64')
    $('script').attr('nonce', nonce)
    $('style').attr('nonce', nonce)
    $('meta[property="csp-nonce"]').attr('content', nonce)

    callback(null, {
        statusCode: 200,
        headers: {
            'Cache-Control': 'no-cache, no-store, must-revalidate',
            'Content-Security-Policy': `default-src 'none'; img-src 'self'; script-src 'nonce-${nonce}' 'self'; 'nonce-${nonce}' 'self'; object-src 'none'`,
            'Content-Type': 'text/html; charset=utf-8',
            'Expires': '0',
            'Pragma': 'no-cache',
            'Referrer-Policy': 'same-origin',
            'Strict-Transport-Security': 'max-age=31536001; includeSubDomains',
            'X-Content-Type-Options': 'nosniff',
            'X-Frame-Options': 'DENY',
            'X-XSS-Protection': '1; mode=block'
        },
        body: $.html()
    })
}

This method is made by @csarkosh you can also read his medium post about this issue he tried to solve:
https://medium.com/@csarkosh/my-experience-getting-an-a-from-mozillas-observatory-tool-on-aws-f0abf12811a1

For my stack it would be really beneficial that cloudfront support adding a nonce to CSP headers natively.

Currently Laravel functions / Lambda edge let you only change viewer requests/viewer response. What I need is to be able to change the body of the origin response.

So that I can:
Scan the HTML file I get from S3 on <script> and <style> blocks
Add via the function a attribute to these blocks ex <style nonce="test">

So what I ask is to:
Response body manipulation from within a CloudFront Function and/or Lambda@Edge function. You fetch the content from cache or the origin and I want to be able to manipulate that response body inside a Cloudfront function before the response is sent to the client.

Edit 12-5-2021:
added more clarification based on comments below.

add-true-client-ip-header Runtime.HandlerNotFound

The function of add-true-client-ip-header is incomplete.
Nodejs function cannot find the index.handler, because it is not exported.

This behavior is seen in all currently supported runtimes:
Nodejs 14
Nodejs 12
Nodejs 10

Error message is below:

{
"errorType": "Runtime.HandlerNotFound",
"errorMessage": "index.handler is undefined or not exported",
"trace": [
"Runtime.HandlerNotFound: index.handler is undefined or not exported",
" at Object.module.exports.load (/var/runtime/UserFunction.js:144:11)",
" at Object. (/var/runtime/index.js:43:30)",
" at Module._compile (internal/modules/cjs/loader.js:999:30)",
" at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)",
" at Module.load (internal/modules/cjs/loader.js:863:32)",
" at Function.Module._load (internal/modules/cjs/loader.js:708:14)",
" at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)",
" at internal/main/run_main_module.js:17:47"
]
}

Functions are not executed when CloudFront returns an error from S3

If CloudFront serves files from S3, the CloudFront function is not executed if the file doesn't exist on S3 (404). This is especially harmful in the provided example where security headers such as CSP are set. It basically eliminates all protections provided by the security headers. Any XSS vulnerability that exists on the page can easily be exploited by sending the user to a page that doesn't exist and therefore doesn't include any of the security headers.

This is a very common setup for hosting single page applications on S3 in combination with CloudFront and I assume that most developers are unaware of this behavior. There should be a huge disclaimer on this specific example that the CSP headers are only added to requests to files that exist on the S3 bucket. Any error response (even if it was rewritten to return a 200 status code) will not invoke the function and therefore not include any custom headers.

Unable to use CloudFront Function "Test" Feature with host.value

Doubt this is actually the correct place to report; maybe the repo owner could send this up the chain?

When using the property for the host header value in a CloudeFront Function and then testing with the "Test" tab, the test fails with the error:

The CloudFront function associated with the CloudFront distribution is invalid or could not run. TypeError: cannot get property "value" of undefined

Property used: event.request.headers.host.value

The example event in the AWS documentation for CloudFront Event Structure > Example Event shows this is a valid path and is also used in the redirect-based-on-country sample.

Reproducible Example

Create a new function with the following basic structure:

function handler(event) {
    var host = event.request.headers.host.value

    return request
}

Expected result: Execution result status succeeded

Actual result: Execution result status failed
Output: The CloudFront function associated with the CloudFront distribution is invalid or could not run. TypeError: cannot get property "value" of undefined

Works in Practice

Oddly enough, the host value is evaluated correctly when CloudFront executes the function. Just seems to be an issue in the Test sandbox.

redirect on response

hi guys, my use case is if the response is 404 from S3, to redirect to the original source to create it.

currently if I do

function handler(event) {
    var response = event.response;
    if (response.statusCode == '404') { 
            var newResponse = {
                        statusCode: 302,
                        statusDescription: 'Found',
                        headers:{ 
                            "location": { "value": "https://alternative-cdn-cname.com/path-to-regenerate-asset/" } 
                        }
             }
    }
    return newResponse;
}

on the response I get

502 ERROR
The request could not be satisfied.
The CloudFront function tried to add, delete, or change a read-only header.

  1. is there a way to create a redirect (edit location header) on the response?
  2. can lambda solve this?

Thanks.

Response interceptor

Can you please consider adding a feature to intercept the response HTML? Something like this:

function handler(event)  {
    var request = event.request;
    var response  = event.response;
 
    // meta tags array
    // Even better if we can fetch tags from DynamoDB in future?
    const tags = [
    { name: “example1.domain.com”, value : “abc”},
     { name: “example2.domain.com”, value : “cuz”}
    ]
    
    // find meta tags for custom domain 
    const meta = tags.find(x => x.name == request.host)

    // Inject in index.html received from S3
    response.content.replace(“<head><\head>”, ‘<head><meta name=“verification” content =${meta.value}<\meta><\head>’

    return response;
}

x-frame-options works but not x-xss-protection

Here you have my lambda edge function

'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['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);
};

I set it as Viewer Response in cloudfront
image

and the result:
image

x-frame-options is appearing, but not x-xss-protection, and not referrer-policy

Cut the .html from uri but remain querystring

I have no idea how to remain querystring on the full url?

Here my now code

function handler(event) {
  var request = event.request;
  var uri = request.uri;

  // Check whether the URI is end with .html
  if (uri.includes(".html")) {
    var newUri = uri.replace(".html", ""); // Delete .html from URI

    var response = {
      statusCode: 302,
      statusDescription: "Found",
      headers: { "location": { "value": newUri } }
    };

    return response; // Redirect user to new location without .html
  }

  return request; // Pass normal request to CloudFront
}

Let's say client request with

https://abc.xyz/index.html?region=ap-southeast-1

, So I want to redirect client to

https://abc.xyz/index?region=ap-southeast-1

but when I testing with real CloudFront Functions I got this result instead.

https://abc.xyz/index

This missing my query param. How to solve this?

Verify cognito jwt with cloudfront function

Is it possible to verify cognito jwt (not simple jwt) with cloudfront function if we hard code public key? I know we can do cognito jwt verification with labda@edge. Built in module crypto has only 6 methods exposed.

How to make a rewrite?

The docs says that is possible to use a rewrite, but there isn't any example on how to achieve that
CloudFront Functions Docs

I tried to change the request, in the test tab it works but no in the cloudfront distribution.

Code:

  if (host.startsWith("www.")) {
    host = host.replace("www.", "");
    request.headers.host.value = host;
    return request;

  }

Test in cloudfront Function:
Screenshot 2022-11-29 at 11 33 16

Test against distribution URL:

502 ERROR
The request could not be satisfied.
The CloudFront function tried to add, delete, or change a read-only header. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.

Use of crypto module?

I am trying to use the "crypto" module in my CF something similar to the example shown below:

return crypto.createHmac(method, key).update(input).digest('base64url');

but unfortunately I don't seem to get access to other functions like createDecipheriv from the crypto module. I see errors like:

TypeError: (intermediate value)["createDecipheriv"] is not a function

Based on the example above, it looks like the crypto module is this one : https://nodejs.org/api/crypto.html#crypto_crypto.

And yes, the crypto module is required at the top like the example:

var crypto = require('crypto');

Is it not the same crypto module? Could not find any documentation around this module for Cloud functions.

URL redirect/rewrite

finding a way to successfully do a URL redirect/rewrite so that your base URL does not change and the query string should be rewritten with another query string. We are planning to away from my website hosted on NGINX, which is currently where these redirect/rewrites are happening.

For example, try to run www.gopetplan.com/aapo it will redirect to www.gopetplan.com/partners/AAPO by serving static webpage(which is hosted on 3rd party vendor) without changing base URL, though static webpage content getting served from another domain

How can I redirect with a huge list of urls?

Say I have about 2k urls that need to redirect to new locations. My idea is create json file for mapping these urls. However, it seems like cloudfront function not support file access. I also add these mapping urls to the same file with the handler but it fails because the file is so big. What can I do now?

Can AWS Parameter Store variables or secrets be used in CloudFront functions?

I'm trying to build CSP for a moderately large infrastructure in several environments.

I can copy/paste to hard-code the values already in the parameter store, though am curious to learn if the CloudFront functions can reference AWS Parameter Store variables, as if so it makes transferring the code between environments easier.

Redirect preserve query string

This relates to issue #7 . I've used the code from there and made it more generic and fixed a couple of edge-cases that wouldn't have worked. Please add this to sample library as it's a very common use-case with a non-obvious solution (for those of us not js experts).

function objectToQueryString(obj) {
    var str = [];
    for (var param in obj)
        if (obj[param].value == '') 
            str.push(encodeURIComponent(param));
        else 
            str.push(encodeURIComponent(param) + "=" + encodeURIComponent(obj[param].value));   
        
    return str.join("&");
}

function handler(event) {
    var request = event.request;
    var uri = request.uri;
    var loc = "";
    var newdomain = newdomain.com;

    if (Object.keys(request.querystring).length) 
        loc = `https://${newdomain}${uri}?${objectToQueryString(request.querystring)}`
    else 
        loc = `https://${newdomain}${uri}`

    var response = {
        statusCode: 302,
        statusDescription: 'Found',
        headers: {
            'location': { value: `${loc}` }      
        }
    };
    return response;
}

Unable to get clientIP

I am using the example "Add true clientIP to request". I have followed the example and deployed a cloudfront example but I am not able to see the ip as part of the request.

function handler(event) {
var request = event.request;
var clientIP = event.viewer.ip;

console.log("test");
//Add the true-client-ip header to the incoming request
request.headers['true-client-ip'] = {value: clientIP};

return request;

}
image

Additional "s" in the folder path in the following command

The file path results into an error, it would be great if this can be updated:
fileb://add-cache-control-headers/index.js --> fileb://add-cache-control-header/index.js

aws cloudfront create-function
--name add-cache-control-headers
--function-config Comment="Function to add cache-control headers",Runtime=cloudfront-js-1.0
--function-code fileb://add-cache-control-headers/index.js

url redirect adding multiple path

I have this simple function to route traffic equally to two APIGW as origin. I see few requests works but after that it starts giving me 403. Looks this function is adding same literal multiple times or in some way function cache is messing it up.

function handler(event) {
    var randomnumber = Math.floor(Math.random() * 100)
    if (randomnumber < 50) {
        var reg = 'east'
        console.log({
            statusCode: 302,
            statusDescription: 'Found',
            headers: {
                "location": {
                    "value": `https://${event.request.headers.host.value}//${reg}${event.request.uri}`
                }
            }
        })
        return {
            statusCode: 302,
            statusDescription: 'Found',
            headers: {
                "location": {
                    "value": `https://${event.request.headers.host.value}//${reg}${event.request.uri}`
                }
            }
        };
    }
    return event.request
}

Correct redirect url would be something like this -
https://XXXXXXXXXX.cloudfront.net//east/p1/p2/p3/p4

But when it gives 403 and i check function log, i see these as return - (essentially "east" multiple times in path, which explains why i am getting 403). But I am unable to figure out what i am doing wrong. This function is associated with distribution as "Viewer request".
https://XXXXXXXXXX.cloudfront.net//east//east/p1/p2/p3/p4
https://XXXXXXXXXX.cloudfront.net//east//east//east/p1/p2/p3/p4

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.