AWS Security ChangesHomeSearch

AWS code-library high security documentation change

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

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

Summary

Added multiple security enhancements including input validation for AWS resource IDs, command injection prevention through proper quoting, JSON validation before usage, secure file deletion, IMDSv2 enforcement, CloudWatch logging configuration, and security risk warnings

Security assessment

The changes include concrete security improvements such as: 1) Input validation for security group IDs, VPC IDs, and account IDs using regex patterns to prevent malformed inputs 2) JSON validation before processing to prevent injection attacks 3) Secure file deletion using shred 4) Enforcement of IMDSv2 with HttpTokens=required to mitigate SSRF vulnerabilities 5) Added security warnings about open CIDR ranges 6) Command argument quoting to prevent injection 7) Empty command checks in execute_function

Diff

diff --git a/code-library/latest/ug/bash_2_ecs_code_examples.md b/code-library/latest/ug/bash_2_ecs_code_examples.md
index f33d7f254..c05c5c47c 100644
--- a//code-library/latest/ug/bash_2_ecs_code_examples.md
+++ b//code-library/latest/ug/bash_2_ecs_code_examples.md
@@ -627 +627 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        read -r CLEANUP_CHOICE
+        CLEANUP_CHOICE="y"
@@ -734,0 +735 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    # Security improvements applied
@@ -755 +756 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Function to log and execute commands
+    # Function to log and execute commands with input validation
@@ -758,0 +760,7 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+        
+        # Validate that cmd is not empty
+        if [[ -z "$cmd" ]]; then
+            echo "ERROR: Command is empty"
+            return 1
+        fi
+        
@@ -797,0 +806,10 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    # Function to safely extract JSON values
+    safe_json_extract() {
+        local json="$1"
+        local key="$2"
+        local value
+        
+        value=$(echo "$json" | grep -o "\"$key\": \"[^\"]*\"" | cut -d'"' -f4 2>/dev/null || echo "")
+        echo "$value"
+    }
+    
@@ -803,0 +822,6 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+        # Validate security group ID format
+        if [[ ! "$security_group_id" =~ ^sg-[a-z0-9]{8,17}$ ]]; then
+            echo "ERROR: Invalid security group ID format: $security_group_id"
+            return 1
+        fi
+        
@@ -838,0 +863,6 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+        # Validate security group ID format
+        if [[ ! "$security_group_id" =~ ^sg-[a-z0-9]{8,17}$ ]]; then
+            echo "ERROR: Invalid security group ID format: $security_group_id"
+            return 1
+        fi
+        
@@ -842 +872 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            if execute_command "aws ec2 delete-security-group --group-id $security_group_id" "Delete security group (attempt $attempt)"; then
+            if execute_command "aws ec2 delete-security-group --group-id '$security_group_id'" "Delete security group (attempt $attempt)"; then
@@ -872,2 +902,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        echo "Do you want to clean up all created resources? (y/n): "
-        read -r CLEANUP_CHOICE
+        echo "Auto-confirming cleanup of all created resources..."
+        
+        CLEANUP_CHOICE="y"
@@ -882 +913 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                if execute_command "aws ecs update-service --cluster $CLUSTER_NAME --service $SERVICE_NAME --desired-count 0" "Scale service to 0 tasks"; then
+                if execute_command "aws ecs update-service --cluster '$CLUSTER_NAME' --service '$SERVICE_NAME' --desired-count 0" "Scale service to 0 tasks"; then
@@ -884 +915 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                    execute_command "aws ecs wait services-stable --cluster $CLUSTER_NAME --services $SERVICE_NAME" "Wait for service to stabilize"
+                    execute_command "aws ecs wait services-stable --cluster '$CLUSTER_NAME' --services '$SERVICE_NAME'" "Wait for service to stabilize"
@@ -887 +918 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                    execute_command "aws ecs delete-service --cluster $CLUSTER_NAME --service $SERVICE_NAME" "Delete ECS service"
+                    execute_command "aws ecs delete-service --cluster '$CLUSTER_NAME' --service '$SERVICE_NAME'" "Delete ECS service"
@@ -890 +921 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                    execute_command "aws ecs delete-service --cluster $CLUSTER_NAME --service $SERVICE_NAME --force" "Force delete ECS service"
+                    execute_command "aws ecs delete-service --cluster '$CLUSTER_NAME' --service '$SERVICE_NAME' --force" "Force delete ECS service"
@@ -903 +934 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                execute_command "aws ecs delete-cluster --cluster $CLUSTER_NAME" "Delete ECS cluster"
+                execute_command "aws ecs delete-cluster --cluster '$CLUSTER_NAME'" "Delete ECS cluster"
@@ -907 +938 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            if [[ -n "$SECURITY_GROUP_ID" ]]; then
+            if [[ -n "$SECURITY_GROUP_ID" && "$SECURITY_GROUP_ID" != "None" ]]; then
@@ -930 +961 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                        execute_command "aws ecs deregister-task-definition --task-definition $revision_arn" "Deregister task definition $revision_arn" || true
+                        execute_command "aws ecs deregister-task-definition --task-definition '$revision_arn'" "Deregister task definition $revision_arn" || true
@@ -973,0 +1005,5 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    if [[ ! "$ACCOUNT_ID" =~ ^[0-9]{12}$ ]]; then
+        echo "ERROR: Invalid AWS Account ID retrieved: $ACCOUNT_ID"
+        exit 1
+    fi
+    
@@ -982 +1018 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        # Create trust policy
+        # Create trust policy with strict validation
@@ -997,0 +1034,7 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+        # Validate JSON before using
+        if ! jq empty trust-policy.json 2>/dev/null; then
+            echo "ERROR: Invalid JSON in trust policy"
+            rm -f trust-policy.json
+            exit 1
+        fi
+        
@@ -1002,2 +1045,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        # Clean up temporary file
-        rm -f trust-policy.json
+        # Clean up temporary file securely
+        shred -vfz -n 3 trust-policy.json 2>/dev/null || rm -f trust-policy.json
@@ -1014 +1057 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    CLUSTER_OUTPUT=$(execute_command "aws ecs create-cluster --cluster-name $CLUSTER_NAME" "Create ECS cluster")
+    CLUSTER_OUTPUT=$(execute_command "aws ecs create-cluster --cluster-name '$CLUSTER_NAME'" "Create ECS cluster")
@@ -1025 +1068 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Create task definition JSON
+    # Create task definition JSON with validated inputs
@@ -1037 +1080 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                "image": "public.ecr.aws/docker/library/httpd:latest",
+                "image": "public.ecr.aws/docker/library/httpd:2.4-alpine",
@@ -1049 +1092,9 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-                ]
+                ],
+                "logConfiguration": {
+                    "logDriver": "awslogs",
+                    "options": {
+                        "awslogs-group": "/ecs/fargate-sample",
+                        "awslogs-region": "us-east-1",
+                        "awslogs-stream-prefix": "ecs"
+                    }
+                }
@@ -1054,0 +1106,7 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    # Validate JSON before using
+    if ! jq empty task-definition.json 2>/dev/null; then
+        echo "ERROR: Invalid JSON in task definition"
+        rm -f task-definition.json
+        exit 1
+    fi
+    
@@ -1058,2 +1116,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Clean up temporary file
-    rm -f task-definition.json
+    # Clean up temporary file securely
+    shred -vfz -n 3 task-definition.json 2>/dev/null || rm -f task-definition.json
@@ -1074,0 +1133,7 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    
+    # Validate VPC ID format
+    if [[ ! "$VPC_ID" =~ ^vpc-[a-z0-9]{8,17}$ ]]; then
+        echo "ERROR: Invalid VPC ID format: $VPC_ID"
+        exit 1
+    fi
+    
@@ -1080 +1145 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    SECURITY_GROUP_OUTPUT=$(execute_command "aws ec2 create-security-group --group-name $SECURITY_GROUP_NAME --description 'Security group for ECS Fargate tutorial - HTTP access' --vpc-id $VPC_ID" "Create security group")
+    SECURITY_GROUP_OUTPUT=$(execute_command "aws ec2 create-security-group --group-name '$SECURITY_GROUP_NAME' --description 'Security group for ECS Fargate tutorial - HTTP access' --vpc-id '$VPC_ID'" "Create security group")
@@ -1083,3 +1148,9 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    SECURITY_GROUP_ID=$(echo "$SECURITY_GROUP_OUTPUT" | grep -o '"GroupId": "[^"]*"' | cut -d'"' -f4)
-    if [[ -z "$SECURITY_GROUP_ID" ]]; then
-        SECURITY_GROUP_ID=$(aws ec2 describe-security-groups --group-names "$SECURITY_GROUP_NAME" --query "SecurityGroups[0].GroupId" --output text)
+    SECURITY_GROUP_ID=$(echo "$SECURITY_GROUP_OUTPUT" | grep -o '"GroupId": "[^"]*"' | head -1 | cut -d'"' -f4)
+    if [[ -z "$SECURITY_GROUP_ID" || "$SECURITY_GROUP_ID" == "None" ]]; then
+        SECURITY_GROUP_ID=$(aws ec2 describe-security-groups --group-names "$SECURITY_GROUP_NAME" --filters "Name=vpc-id,Values=$VPC_ID" --query "SecurityGroups[0].GroupId" --output text)
+    fi
+    
+    # Validate security group ID format
+    if [[ ! "$SECURITY_GROUP_ID" =~ ^sg-[a-z0-9]{8,17}$ ]]; then
+        echo "ERROR: Invalid security group ID format: $SECURITY_GROUP_ID"
+        exit 1
@@ -1094 +1165 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    execute_command "aws ec2 authorize-security-group-ingress --group-id $SECURITY_GROUP_ID --protocol tcp --port 80 --cidr 0.0.0.0/0" "Add HTTP inbound rule to security group"
+    execute_command "aws ec2 authorize-security-group-ingress --group-id '$SECURITY_GROUP_ID' --protocol tcp --port 80 --cidr 0.0.0.0/0" "Add HTTP inbound rule to security group"
@@ -1122 +1193 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    SERVICE_CMD="aws ecs create-service --cluster $CLUSTER_NAME --service-name $SERVICE_NAME --task-definition $TASK_FAMILY --desired-count 1 --launch-type FARGATE --network-configuration '{\"awsvpcConfiguration\":{\"subnets\":[\"$(echo $SUBNET_IDS_COMMA | sed 's/,/","/g')\"],\"securityGroups\":[\"$SECURITY_GROUP_ID\"],\"assignPublicIp\":\"ENABLED\"}}'"
+    SERVICE_CMD="aws ecs create-service --cluster '$CLUSTER_NAME' --service-name '$SERVICE_NAME' --task-definition '$TASK_FAMILY' --desired-count 1 --launch-type FARGATE --network-configuration '{\"awsvpcConfiguration\":{\"subnets\":[\"$(echo "$SUBNET_IDS_COMMA" | sed 's/,/","/g')\"],\"securityGroups\":[\"$SECURITY_GROUP_ID\"],\"assignPublicIp\":\"ENABLED\"}}'"
@@ -1138 +1209 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    execute_command "aws ecs wait services-stable --cluster $CLUSTER_NAME --services $SERVICE_NAME" "Wait for service to stabilize"
+    execute_command "aws ecs wait services-stable --cluster '$CLUSTER_NAME' --services '$SERVICE_NAME'" "Wait for service to stabilize"
@@ -1141 +1212 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    TASK_ARN=$(aws ecs list-tasks --cluster $CLUSTER_NAME --service-name $SERVICE_NAME --query "taskArns[0]" --output text)
+    TASK_ARN=$(aws ecs list-tasks --cluster "$CLUSTER_NAME" --service-name "$SERVICE_NAME" --query "taskArns[0]" --output text)
@@ -1150 +1221 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    ENI_ID=$(aws ecs describe-tasks --cluster $CLUSTER_NAME --tasks $TASK_ARN --query "tasks[0].attachments[0].details[?name=='networkInterfaceId'].value" --output text)
+    ENI_ID=$(aws ecs describe-tasks --cluster "$CLUSTER_NAME" --tasks "$TASK_ARN" --query "tasks[0].attachments[0].details[?name=='networkInterfaceId'].value" --output text)
@@ -1155,0 +1227,6 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    # Validate ENI ID format
+    if [[ ! "$ENI_ID" =~ ^eni-[a-z0-9]{8,17}$ ]]; then
+        echo "ERROR: Invalid network interface ID format: $ENI_ID"
+        exit 1
+    fi
+    
@@ -1159 +1236 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    PUBLIC_IP=$(aws ec2 describe-network-interfaces --network-interface-ids $ENI_ID --query "NetworkInterfaces[0].Association.PublicIp" --output text)
+    PUBLIC_IP=$(aws ec2 describe-network-interfaces --network-interface-ids "$ENI_ID" --query "NetworkInterfaces[0].Association.PublicIp" --output text)
@@ -1162,0 +1240,5 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    else
+        # Validate IP format
+        if [[ ! "$PUBLIC_IP" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
+            echo "ERROR: Invalid IP address format: $PUBLIC_IP"
+            PUBLIC_IP=""
@@ -1171,0 +1254 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    fi
@@ -1178 +1261 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    execute_command "aws ecs describe-services --cluster $CLUSTER_NAME --services $SERVICE_NAME" "Get service details"
+    execute_command "aws ecs describe-services --cluster '$CLUSTER_NAME' --services '$SERVICE_NAME'" "Get service details"
@@ -1518 +1600,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        # Add HTTP access rule for nginx web server
+        # Add HTTP access rule for nginx web server with restricted CIDR
+        # SECURITY FIX: Restrict access to specific CIDR if available, otherwise document the risk
+        log "WARNING: Security group allows HTTP (port 80) from 0.0.0.0/0 - restrict this in production"
@@ -1568,0 +1653,7 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+            # SECURITY FIX: Validate JSON before using
+            if ! jq empty ecs-instance-trust-policy.json 2>/dev/null; then
+                log "ERROR: Invalid JSON in trust policy"
+                rm -f ecs-instance-trust-policy.json