Skip to content

Help Needed with CloudFront Function for IP and Origin-Based Access Control

0

Hello everyone,

I'm really struggling with a CloudFront function and could use some help. I've attached this function to the viewer request behavior of my distribution (cdn.example.com). The goal is to only allow access from my specific IP address or genuine users of my websites, and redirect everyone else to my main site (https://example.com).

Here's the CloudFront function I'm using:

'use strict';

function handler(event) {
    const allowedIPs = ['192.0.2.1'];
    const domain = 'example.com';
    const protocol = 'https';
    const viewerIp = event.viewer.ip;

    // Ensure response object exists and set CORS header
    event.response = event.response || { headers: {} };
    event.response.headers["access-control-allow-origin"] = { value: `https://${domain}` };

    // Check if the request is from an allowed IP address
    if (allowedIPs.includes(viewerIp)) {
        return requestWithHeaders(event.request, domain);
    }

    const originHeader = event.request.headers.origin;
    const userAgent = event.request.headers['user-agent'] ? event.request.headers['user-agent'].value : '';

    // Function to check user-agent
    const isValidUserAgent = () => {
        const requiredAgents = [
            'Mozilla/5.0',
            'AppleWebKit/537.36',
            'Chrome/126.0.0.0',
            'Safari/537.36'
        ];

        return requiredAgents.every(agent => userAgent.includes(agent));
    };

    // Check if the request is from your domain with a valid user-agent
    if (
        originHeader &&
        originHeader.value.startsWith(`${protocol}://`) &&
        originHeader.value.endsWith(domain) &&
        isValidUserAgent()
    ) {
        return requestWithHeaders(event.request, domain);
    }

    // Redirect all other requests to example.com
    return {
        statusCode: 307,
        statusDescription: 'Temporary Redirect',
        headers: {
            location: { value: `https://${domain}` }
        }
    };
}

// Helper function to return request with updated headers
function requestWithHeaders(request, domain) {
    request.headers = request.headers || {};
    request.headers["access-control-allow-origin"] = { value: `https://${domain}` };
    return request;
}

Issue: When I try to access the distribution from https://www.example.com using Edge Browser (latest version) on Windows from a random IP address (not whitelisted), it redirects me to https://example.com instead of allowing access. This should work because the request is coming from my domain.

[N.B.: To keep the post genuine for the community, I have redacted the IP Address and Domain Name]

Edit 1: Requests from the allowed IP addresses are successfully accessing the resource. The issue occurs when a user with a different IP address (not in the allowed list) tries to access resources from https://www.example.com. The site is making the request from Microsoft Edge (an allowed user-agent), so the origin value should match https://*.example.com, which meets the conditions. Instead, the response redirects to https://example.com.

I also don’t know how to enable logs for a CloudFront function attached to a distribution. Despite my search, I couldn't find a way. Any resources or guidance on this would be incredibly helpful.

I'm really at a loss and any help or suggestions would be greatly appreciated. Thank you so much for taking the time to read this and help me out.

1 Answer
2

Hello.

Does "access-control-allow-origin" include the correct domain?
It also appears to be doing something like checking the user agent, is this necessary?

First of all, I think it would be a good idea to create a process for only allowed IP addresses and try it out for troubleshooting purposes.
Once you've done that, try adding a process to determine the domain of the request source.

Logging is possible using "console.log".
I think the logs are saved in a log group named "/aws/cloudfront/function/function name" in CloudWatch Logs in the us-east-1 region.
https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/edge-functions-logs.html#cloudfront-function-logs

console.log()
EXPERT
answered 2 years ago
EXPERT
reviewed 2 years ago
EXPERT
reviewed 2 years ago
    1. Yes, "access-control-allow-origin" is redirecting to correct domain
    2. Yes, user agent checking is important, just to make sure that requests are coming from valid browser, and not anyone is randomly making any request from bots
    3. The process was already working perfectly for IP Addresses

    Thanks for sharing the information of logging, it really helped me out. The issue in my case was that the distribution wasn't getting the origin header in the request at all, so while checking it was empty string.

    But the distribution was getting referer header which was also containing the full domain, so instead of checking on origin header, I applied the check on referer header, and the logic worked perfectly

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.