Skip to content

Commit dd029d0

Browse files
committed
[PRM-747] Block invalid URL calls to CloudFront
1 parent 2d99b47 commit dd029d0

2 files changed

Lines changed: 40 additions & 0 deletions

File tree

infrastructure/cloudfront.tf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ resource "aws_cloudfront_distribution" "s3_presign_mask" {
4242
cache_policy_id = local.cloudfront_cache_policy_id
4343
origin_request_policy_id = local.cloudfront_viewer_policy_id
4444

45+
function_association {
46+
event_type = "viewer-request"
47+
function_arn = aws_cloudfront_function.block_invalid_urls.arn
48+
}
49+
4550
lambda_function_association {
4651
event_type = "origin-request"
4752
lambda_arn = module.edge-presign-lambda.qualified_arn
@@ -107,6 +112,14 @@ resource "aws_cloudfront_distribution" "s3_presign_mask" {
107112
depends_on = [aws_acm_certificate_validation.cloudfront]
108113
}
109114

115+
resource "aws_cloudfront_function" "block_invalid_urls" {
116+
name = "block-invalid-urls"
117+
runtime = "cloudfront-js-2.0"
118+
comment = "Blocks invalid URL requests"
119+
publish = true
120+
code = file("${path.module}/code/block-invalid-urls.js")
121+
}
122+
110123
resource "aws_cloudfront_origin_request_policy" "viewer" {
111124
count = local.is_sandbox ? 0 : 1
112125
name = "${terraform.workspace}_BlockQueriesAndAllowViewer"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
function handler(event) {
2+
var request = event.request;
3+
var uri = request.uri;
4+
5+
// Regular expression to match:
6+
// 1. ^\/ -> Starts with a forward slash
7+
// 2. (review\/|upload\/)? -> Optionally followed by "review/" OR "upload/"
8+
// 3. [0-9a-f]{8}-... -> Followed by a standard 36-character UUID
9+
// 4. $ -> End of the string (prevents trailing slashes or extra paths)
10+
var allowedPattern = /^\/(review\/|upload\/)?[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$/;
11+
12+
if (allowedPattern.test(uri)) {
13+
// The URI matches the allowed patterns.
14+
// Returning the request object lets it proceed to the cache/origin.
15+
return request;
16+
}
17+
18+
// The URI does not match. Block the request immediately.
19+
return {
20+
statusCode: 403,
21+
statusDescription: 'Forbidden',
22+
headers: {
23+
'content-type': { value: 'text/plain' }
24+
},
25+
body: 'Access Denied: Invalid Path'
26+
};
27+
}

0 commit comments

Comments
 (0)