Over the years i've lost count of how many times I have seen people stack a hundred layers of protection in front of a CloudFront endpoint, only to still allow traffic via the ALB.
Today, we explore two approaches to address this:
Historically, as an option to secure communication between CloudFront and Application Load Balancers, developers would implement custom header validation. This method, while functional, required careful implementation and maintenance. Here's how it typically works:
// CloudFront Origin Custom Headers Configuration
{
"Quantity": 1,
"Items": [
{
"HeaderName": "X-Origin-Verify",
"HeaderValue": "your-secret-value-here"
}
]
}
app.use((req, res, next) => {
const originVerifyHeader = req.header('X-Origin-Verify');
if (originVerifyHeader !== process.env.EXPECTED_HEADER_VALUE) {
// Reject requests without the correct header
return res.status(403).send('Access Denied');
}
next();
});
This works because the user is never privvy to this injected secret, so you know that it had to have originated from a route that was secured.
While this method certainly works, it comes with several drawbacks:
Secrets Management: You need to securely store and distribute the header value across your infrastructure.
Security Risks: The secret header could potentially be leaked, requiring regular rotation and monitoring.
Maintenance Overhead: You must implement the validation logic in your application code and maintain it across all services.
Network Complexity: Your ALB still needs to be internet-accessible, requiring public subnets and careful security group configuration.
Amazon's new CloudFront VPC origins feature represents a massive shift in how we secure origin access. Now, instead of relying on application level validation, security can be handled at the infrastructure level.
True Private Origins: Your ALB can now reside in a private subnet with no internet accessibility, dramatically reducing your attack surface.
Simplified Configuration: No need for custom headers, validation logic, or complex networking rules (If you remember having to set up the rotating of CF's valid IP addresses, you're a real one). The security is now built into the infrastructure.
Cost Optimization: Eliminate the need for public IP addresses and NAT gateways, potentially reducing your AWS bill (it's $50/mo per NAT gateway).
Reduced Complexity: Remove the need for maintaining custom security code in your application.
The setup process is straightforward:
That's it! No additional code, secrets management, complex networking or arcane rituals required.
Let's consider your typical microservices architecture with multiple ALBs. Under the previous approach, you would need:
With VPC origins, you simply:
While VPC origins provides excellent infrastructure-level security, remember to maintain defence in depth:
I cant tell you how often I have implemented the header based approach, and it certainly had its benefits. However for projects new & old, VPC origins should be the default choice for securing CloudFront to ALB communication. If you have existing projects using custom header validation, and you need a hand migrating over please get in touch!
For help with any other security related assistance reach out to us for a security assessment - we're always around to give you a hand!