AWS Security ChangesHomeSearch

AWS code-library medium security documentation change

Service: code-library · 2026-05-01 · Security-related medium

File: code-library/latest/ug/bash_2_cloudformation_code_examples.md

Summary

Enhanced security hardening in CloudFormation example script: added input validation, secure logging, IMDSv2 enforcement, least-privilege IAM roles, secure file deletion, and automated cleanup.

Security assessment

Changes include concrete security improvements: 1) Input validation for IP/AWS region prevents injection/misconfiguration 2) 'chmod 600' on logs restricts access 3) 'shred' ensures secure file deletion 4) IMDSv2 enforcement (HttpTokens:required) mitigates SSRF risks 5) IAM roles implement least privilege 6) Automatic cleanup prevents resource leakage.

Diff

diff --git a/code-library/latest/ug/bash_2_cloudformation_code_examples.md b/code-library/latest/ug/bash_2_cloudformation_code_examples.md
index 277d7a752..94554db6d 100644
--- a//code-library/latest/ug/bash_2_cloudformation_code_examples.md
+++ b//code-library/latest/ug/bash_2_cloudformation_code_examples.md
@@ -53 +53,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Set up logging
+    set -euo pipefail
+    
+    # Set up logging with secure permissions
@@ -54,0 +57,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    touch "$LOG_FILE"
+    chmod 600 "$LOG_FILE"
@@ -66,0 +71,17 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    # Function to validate IP address format
+    validate_ip() {
+        local ip=$1
+        if ! [[ "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
+            return 1
+        fi
+        
+        local IFS=.
+        local -a octets=($ip)
+        for octet in "${octets[@]}"; do
+            if ((octet > 255)); then
+                return 1
+            fi
+        done
+        return 0
+    }
+    
@@ -74 +95 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$STACK_NAME" ]; then
+        if [ -n "${STACK_NAME:-}" ]; then
@@ -76 +97 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            aws cloudformation delete-stack --stack-name "$STACK_NAME"
+            aws cloudformation delete-stack --stack-name "$STACK_NAME" --region "${AWS_REGION:-us-east-1}" || true
@@ -79 +100 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            aws cloudformation wait stack-delete-complete --stack-name "$STACK_NAME"
+            aws cloudformation wait stack-delete-complete --stack-name "$STACK_NAME" --region "${AWS_REGION:-us-east-1}" 2>/dev/null || true
@@ -84 +105 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -f "$TEMPLATE_FILE" ]; then
+        if [ -f "${TEMPLATE_FILE:-}" ]; then
@@ -86 +107 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            rm -f "$TEMPLATE_FILE"
+            shred -vfz -n 3 "$TEMPLATE_FILE" 2>/dev/null || rm -f "$TEMPLATE_FILE"
@@ -99 +120 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$STACK_NAME" ]; then
+        if [ -n "${STACK_NAME:-}" ]; then
@@ -104,4 +125 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        echo "Would you like to clean up these resources? (y/n): "
-        read -r CLEANUP_CHOICE
-        
-        if [[ "$CLEANUP_CHOICE" =~ ^[Yy]$ ]]; then
+        echo "Cleaning up resources automatically..."
@@ -109,3 +126,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        else
-            echo "Resources were not cleaned up. You may need to delete them manually."
-        fi
@@ -117,0 +133,7 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    trap 'cleanup' EXIT
+    
+    # Validate AWS region
+    AWS_REGION="${AWS_REGION:-us-east-1}"
+    if ! [[ "$AWS_REGION" =~ ^[a-z]{2}-[a-z]+-[0-9]{1}$ ]]; then
+        handle_error "Invalid AWS_REGION format: $AWS_REGION"
+    fi
@@ -119,3 +141,19 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Generate a unique stack name
-    STACK_NAME="MyTestStack"
-    TEMPLATE_FILE="webserver-template.yaml"
+    # Generate a unique stack name with timestamp
+    TIMESTAMP=$(date +%s)
+    STACK_NAME="MyTestStack-${TIMESTAMP}"
+    TEMPLATE_FILE="webserver-template-${TIMESTAMP}.yaml"
+    
+    # Verify AWS CLI is installed
+    if ! command -v aws &> /dev/null; then
+        handle_error "AWS CLI is not installed or not in PATH"
+    fi
+    
+    # Verify curl is installed
+    if ! command -v curl &> /dev/null; then
+        handle_error "curl is not installed or not in PATH"
+    fi
+    
+    # Verify AWS credentials are configured
+    if ! aws sts get-caller-identity --region "$AWS_REGION" &> /dev/null; then
+        handle_error "AWS credentials not configured or invalid"
+    fi
@@ -128,0 +167,12 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    Metadata:
+      AWS::CloudFormation::Init:
+        config:
+          packages:
+            yum:
+              httpd: []
+          services:
+            sysvinit:
+              httpd:
+                enabled: true
+                ensureRunning: true
+    
@@ -145 +195 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        Description: Your IP address in CIDR format (e.g. 203.0.113.1/32).
+        Description: Your IP address in CIDR format (e.g 203.0.113.1/32).
@@ -149 +198,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        Default: 0.0.0.0/0
@@ -153,0 +203,19 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+      WebServerRole:
+        Type: AWS::IAM::Role
+        Properties:
+          AssumeRolePolicyDocument:
+            Version: '2012-10-17'
+            Statement:
+              - Effect: Allow
+                Principal:
+                  Service: ec2.amazonaws.com
+                Action: 'sts:AssumeRole'
+          ManagedPolicyArns:
+            - 'arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy'
+    
+      WebServerInstanceProfile:
+        Type: AWS::IAM::InstanceProfile
+        Properties:
+          Roles:
+            - !Ref WebServerRole
+    
@@ -157 +225,12 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-          GroupDescription: Allow HTTP access via my IP address
+          GroupDescription: Allow HTTP access via specified IP address
+          SecurityGroupEgress:
+            - IpProtocol: tcp
+              FromPort: 80
+              ToPort: 80
+              CidrIp: 0.0.0.0/0
+              Description: Allow HTTP outbound
+            - IpProtocol: tcp
+              FromPort: 443
+              ToPort: 443
+              CidrIp: 0.0.0.0/0
+              Description: Allow HTTPS outbound for package updates
@@ -162,0 +242 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+              Description: HTTP access from specified IP
@@ -168,0 +249 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+          IamInstanceProfile: !Ref WebServerInstanceProfile
@@ -170,0 +252,5 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+          Monitoring: true
+          MetadataOptions:
+            HttpEndpoint: enabled
+            HttpTokens: required
+            HttpPutResponseHopLimit: 1
@@ -172,0 +259,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+            set -euo pipefail
+            exec > >(tee /var/log/user-data.log)
+            exec 2>&1
@@ -177,0 +267 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+            chmod 644 /var/www/html/index.html
@@ -185,0 +276,6 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+      InstanceId:
+        Value: !Ref WebServer
+        Description: EC2 Instance ID
+      SecurityGroupId:
+        Value: !Ref WebServerSecurityGroup
+        Description: Security Group ID
@@ -187,0 +284,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    chmod 600 "$TEMPLATE_FILE"
+    
@@ -195,2 +293,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    VALIDATION_RESULT=$(aws cloudformation validate-template --template-body "file://$TEMPLATE_FILE" 2>&1)
-    if [ $? -ne 0 ]; then
+    if ! VALIDATION_RESULT=$(aws cloudformation validate-template \
+        --template-body "file://$TEMPLATE_FILE" \
+        --region "$AWS_REGION" 2>&1); then
@@ -204 +303,12 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    MY_IP=$(curl -s https://checkip.amazonaws.com)
+    
+    MY_IP=""
+    for endpoint in "https://checkip.amazonaws.com" "https://api.ipify.org" "https://icanhazip.com"; do
+        if MY_IP=$(curl -s --max-time 5 "$endpoint" 2>/dev/null); then
+            MY_IP="${MY_IP//[[:space:]]/}"
+            if validate_ip "$MY_IP"; then
+                break
+            fi
+            MY_IP=""
+        fi
+    done
+    
@@ -206 +316 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        handle_error "Failed to retrieve public IP address"
+        handle_error "Failed to retrieve public IP address from multiple sources"
@@ -208,2 +318,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    MY_IP="${MY_IP}/32"
-    echo "Your public IP address: $MY_IP"
+    
+    MY_IP_CIDR="${MY_IP}/32"
+    echo "Your public IP address: $MY_IP_CIDR"
@@ -215 +326 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    CREATE_RESULT=$(aws cloudformation create-stack \
+    if ! CREATE_RESULT=$(aws cloudformation create-stack \
@@ -220,4 +331,4 @@ There's more on GitHub. Find the complete example and learn how to set up and ru