Skip to main content

CloudFront Distribution Has a Default Root Object Configured

Overview

This check verifies that your Amazon CloudFront distributions have a default root object configured. When someone visits your CloudFront URL without specifying a file (e.g., https://d123.cloudfront.net/), CloudFront needs to know which file to serve. The default root object tells CloudFront to return a specific file like index.html instead of forwarding the raw request to your origin.

Risk

Without a default root object configured:

  • Data exposure: Root requests may reveal directory listings or unintended files from your origin, exposing sensitive information
  • Reconnaissance aid: Attackers can learn about your origin structure and find files to target
  • Availability issues: Users may receive error messages instead of your intended landing page
  • Content integrity: Unpredictable routing could deliver incorrect or unexpected content

Severity: High

Remediation Steps

Prerequisites

You need:

  • AWS Console access with permissions to modify CloudFront distributions
  • The CloudFront distribution ID you want to update
Required IAM permissions

Your IAM user or role needs these permissions:

  • cloudfront:GetDistribution
  • cloudfront:GetDistributionConfig
  • cloudfront:UpdateDistribution

AWS Console Method

  1. Open the CloudFront console
  2. Select the distribution you want to update
  3. Choose the General tab
  4. In the Settings section, click Edit
  5. In the Default root object field, enter index.html (without a leading slash)
  6. Click Save changes
  7. Wait for the distribution status to change from "Deploying" to "Deployed" (this typically takes a few minutes)

Important: The default root object only applies to the root of your distribution (/). It does not apply to subdirectories. For example, if a user requests https://d123.cloudfront.net/photos/, CloudFront will not automatically serve index.html from the photos directory.

AWS CLI

The simplest approach uses the --default-root-object flag:

# Set the default root object to index.html
aws cloudfront update-distribution \
--id EDFDVBD6EXAMPLE \
--default-root-object index.html \
--region us-east-1

Replace EDFDVBD6EXAMPLE with your actual distribution ID.

Alternative method (for complex updates):

If you need to make multiple changes at once, use the full configuration approach:

# Step 1: Get the current configuration
aws cloudfront get-distribution-config \
--id EDFDVBD6EXAMPLE \
--region us-east-1 \
--output json > dist-config.json

# Step 2: Note the ETag value from the output (you'll need it)
# Step 3: Edit dist-config.json:
# - Remove the "ETag" field
# - Rename "DistributionConfig" to just the config contents
# - Set "DefaultRootObject": "index.html"

# Step 4: Update with the modified config
aws cloudfront update-distribution \
--id EDFDVBD6EXAMPLE \
--distribution-config file://dist-config.json \
--if-match E2QWRUHEXAMPLE \
--region us-east-1

Replace E2QWRUHEXAMPLE with the ETag value from step 1.

CloudFormation

Set the DefaultRootObject property in your AWS::CloudFront::Distribution resource:

AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFront distribution with default root object configured

Parameters:
DomainName:
Type: String
Description: The S3 bucket domain name or custom origin domain
OriginAccessControlId:
Type: String
Description: Origin Access Control ID for S3 origins
Default: ''

Conditions:
HasOAC: !Not [!Equals [!Ref OriginAccessControlId, '']]

Resources:
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
DefaultRootObject: index.html
Origins:
- Id: PrimaryOrigin
DomainName: !Ref DomainName
OriginAccessControlId: !If [HasOAC, !Ref OriginAccessControlId, !Ref 'AWS::NoValue']
S3OriginConfig:
OriginAccessIdentity: ''
DefaultCacheBehavior:
TargetOriginId: PrimaryOrigin
ViewerProtocolPolicy: redirect-to-https
CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6
CustomErrorResponses:
- ErrorCode: 403
ResponseCode: 404
ResponsePagePath: /404.html
ErrorCachingMinTTL: 60
- ErrorCode: 404
ResponseCode: 404
ResponsePagePath: /404.html
ErrorCachingMinTTL: 60

Outputs:
DistributionId:
Description: CloudFront Distribution ID
Value: !Ref CloudFrontDistribution
DistributionDomainName:
Description: CloudFront Distribution Domain Name
Value: !GetAtt CloudFrontDistribution.DomainName

The key line is DefaultRootObject: index.html under DistributionConfig.

Terraform

Set the default_root_object argument in your aws_cloudfront_distribution resource:

resource "aws_cloudfront_distribution" "main" {
enabled = true
default_root_object = "index.html"

origin {
domain_name = var.origin_domain_name
origin_id = "primary-origin"
origin_access_control_id = var.origin_access_control_id
}

default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "primary-origin"
viewer_protocol_policy = "redirect-to-https"

forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
}

custom_error_response {
error_code = 403
response_code = 404
response_page_path = "/404.html"
}

custom_error_response {
error_code = 404
response_code = 404
response_page_path = "/404.html"
}

restrictions {
geo_restriction {
restriction_type = "none"
}
}

viewer_certificate {
cloudfront_default_certificate = true
}
}

The key line is default_root_object = "index.html".

Verification

After making changes, verify the fix:

  1. Open the CloudFront console
  2. Select your distribution
  3. On the General tab, confirm the Default root object field shows index.html
  4. Test by visiting your CloudFront URL without a path (e.g., https://d123.cloudfront.net/)
  5. You should see your index.html content instead of an error or directory listing
CLI verification
# Check the current default root object setting
aws cloudfront get-distribution-config \
--id EDFDVBD6EXAMPLE \
--region us-east-1 \
--query "DistributionConfig.DefaultRootObject" \
--output text

This should return index.html (or your configured default root object).

Additional Resources

Notes

  • Subdirectories: The default root object only works for the root path (/). Requests to subdirectories like /photos/ will not automatically serve index.html from that subdirectory. For single-page applications (SPAs), consider using CloudFront Functions or Lambda@Edge to handle subdirectory routing.

  • File must exist: Make sure the file you specify (e.g., index.html) actually exists at the root of your origin. If it does not exist, users will receive an error.

  • No leading slash: Do not include a leading slash in the default root object value. Use index.html, not /index.html.

  • Defense in depth: In addition to setting a default root object, consider:

    • Using Origin Access Control (OAC) to prevent direct access to your S3 bucket
    • Configuring custom error pages for 403 and 404 errors
    • Implementing proper bucket policies that follow least privilege principles
  • Propagation time: Changes to CloudFront distributions typically take a few minutes to propagate globally. The distribution status will show "Deploying" until complete.