AWS ec2 documentation change
Summary
Updated VPC Lattice tutorial script with security hardening improvements including input validation, secure logging, safer command execution, and automated resource selection
Security assessment
The changes add security best practices to the tutorial script but don't address a specific security vulnerability. Improvements include: 1) Input validation function that checks for shell injection characters (; $ ` | & < > () {}), 2) Secure log file permissions (chmod 600), 3) Safer command execution with proper quoting and variable handling, 4) Use of jq for safer JSON parsing instead of grep/cut, 5) Automatic cleanup without user confirmation to prevent resource leakage. These are proactive security improvements rather than fixes for reported vulnerabilities.
Diff
diff --git a/ec2/latest/devguide/example_vpc_lattice_GettingStarted_055_section.md b/ec2/latest/devguide/example_vpc_lattice_GettingStarted_055_section.md index 07c087d83..39ccd7651 100644 --- a//ec2/latest/devguide/example_vpc_lattice_GettingStarted_055_section.md +++ b//ec2/latest/devguide/example_vpc_lattice_GettingStarted_055_section.md @@ -44 +44,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 @@ -46 +48,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "Starting VPC Lattice tutorial script at $(date)" > $LOG_FILE + touch "$LOG_FILE" + chmod 600 "$LOG_FILE" + echo "Starting VPC Lattice tutorial script at $(date)" > "$LOG_FILE" @@ -50,3 +54,4 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "$(date): Running command: $1" >> $LOG_FILE - eval "$1" 2>&1 | tee -a $LOG_FILE - return ${PIPESTATUS[0]} + local cmd="$1" + echo "$(date): Running command: $cmd" >> "$LOG_FILE" + eval "$cmd" 2>&1 | tee -a "$LOG_FILE" + return "${PIPESTATUS[0]}" @@ -57,2 +62,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ $1 -ne 0 ]; then - echo "ERROR: Command failed with exit code $1" | tee -a $LOG_FILE + if [ "$1" -ne 0 ]; then + echo "ERROR: Command failed with exit code $1" | tee -a "$LOG_FILE" @@ -60 +65,9 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - exit $1 + exit "$1" + fi + } + + # Function to validate AWS CLI is available + check_aws_cli() { + if ! command -v aws &> /dev/null; then + echo "ERROR: AWS CLI is not installed or not in PATH" | tee -a "$LOG_FILE" + exit 1 @@ -63,0 +77,19 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + # Function to validate input parameters + validate_input() { + local input="$1" + local param_name="$2" + + if [[ -z "$input" ]]; then + echo "ERROR: $param_name is empty" | tee -a "$LOG_FILE" + return 1 + fi + + # Validate against common injection patterns + if [[ "$input" =~ [\;\$\`\|\&\<\>\(\)\{\}] ]]; then + echo "ERROR: $param_name contains invalid characters" | tee -a "$LOG_FILE" + return 1 + fi + + return 0 + } + @@ -66,4 +98,4 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - local resource_type=$1 - local resource_id=$2 - local desired_status=$3 - local command=$4 + local resource_type="$1" + local resource_id="$2" + local desired_status="$3" + local command="$4" @@ -74 +106,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "Waiting for $resource_type $resource_id to be in state $desired_status..." | tee -a $LOG_FILE + validate_input "$resource_type" "resource_type" || return 1 + validate_input "$resource_id" "resource_id" || return 1 + validate_input "$desired_status" "desired_status" || return 1 @@ -76,2 +110,4 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - while [ $attempt -le $max_attempts ]; do - echo "Attempt $attempt of $max_attempts..." >> $LOG_FILE + echo "Waiting for $resource_type $resource_id to be in state $desired_status..." | tee -a "$LOG_FILE" + + while [ "$attempt" -le "$max_attempts" ]; do + echo "Attempt $attempt of $max_attempts..." >> "$LOG_FILE" @@ -80,2 +116,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - status_output=$(eval "$command") - echo "$status_output" >> $LOG_FILE + status_output=$(eval "$command" 2>&1) || true + echo "$status_output" >> "$LOG_FILE" @@ -83 +119 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # For service networks, they don't have a status field in the output + # For service networks, they do not have a status field in the output @@ -87 +123 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "$resource_type $resource_id is now active" | tee -a $LOG_FILE + echo "$resource_type $resource_id is now active" | tee -a "$LOG_FILE" @@ -92,2 +128,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - status=$(echo "$status_output" | grep -i "status" | awk -F'"' '{print $4}') - echo "Current status: $status" >> $LOG_FILE + status=$(echo "$status_output" | grep -i "status" | awk -F'"' '{print $4}' || true) + echo "Current status: $status" >> "$LOG_FILE" @@ -96 +132 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "$resource_type $resource_id is now in state $desired_status" | tee -a $LOG_FILE + echo "$resource_type $resource_id is now in state $desired_status" | tee -a "$LOG_FILE" @@ -99 +135 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "ERROR: $resource_type $resource_id failed to reach desired state. Current status: $status" | tee -a $LOG_FILE + echo "ERROR: $resource_type $resource_id failed to reach desired state. Current status: $status" | tee -a "$LOG_FILE" @@ -104 +140 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "Waiting for status change... (attempt $attempt/$max_attempts)" >> $LOG_FILE + echo "Waiting for status change... (attempt $attempt/$max_attempts)" >> "$LOG_FILE" @@ -109 +145 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "ERROR: Timed out waiting for $resource_type $resource_id to reach state $desired_status" | tee -a $LOG_FILE + echo "ERROR: Timed out waiting for $resource_type $resource_id to reach state $desired_status" | tee -a "$LOG_FILE" @@ -112,0 +149,12 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + # Cleanup function for trap + cleanup() { + local exit_code=$? + echo "Script interrupted or failed. Cleaning up..." | tee -a "$LOG_FILE" + exit "$exit_code" + } + + trap cleanup EXIT INT TERM + + # Check prerequisites + check_aws_cli + @@ -119 +167 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - CREATED_RESOURCES=() + declare -a CREATED_RESOURCES @@ -121,2 +169,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "=== VPC Lattice Service Network Tutorial ===" | tee -a $LOG_FILE - echo "Random ID for this session: ${RANDOM_ID}" | tee -a $LOG_FILE + echo "=== VPC Lattice Service Network Tutorial ===" | tee -a "$LOG_FILE" + echo "Random ID for this session: ${RANDOM_ID}" | tee -a "$LOG_FILE" @@ -125,2 +173,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo -e "\n=== Step 1: Creating a VPC Lattice service network ===" | tee -a $LOG_FILE - echo "Creating service network: $SERVICE_NETWORK_NAME" | tee -a $LOG_FILE + echo -e "\n=== Step 1: Creating a VPC Lattice service network ===" | tee -a "$LOG_FILE" + echo "Creating service network: $SERVICE_NETWORK_NAME" | tee -a "$LOG_FILE" @@ -128 +176 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - SERVICE_NETWORK_OUTPUT=$(log_command "aws vpc-lattice create-service-network --name $SERVICE_NETWORK_NAME") + SERVICE_NETWORK_OUTPUT=$(log_command "aws vpc-lattice create-service-network --name '$SERVICE_NETWORK_NAME' --output json") @@ -131,2 +179,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Extract the service network ID - SERVICE_NETWORK_ID=$(echo "$SERVICE_NETWORK_OUTPUT" | grep -o '"id": "[^"]*' | cut -d'"' -f4) + # Extract the service network ID using jq for safety + SERVICE_NETWORK_ID=$(echo "$SERVICE_NETWORK_OUTPUT" | jq -r '.id // empty' 2>/dev/null || true) @@ -134 +182 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "ERROR: Failed to extract service network ID" | tee -a $LOG_FILE + echo "ERROR: Failed to extract service network ID" | tee -a "$LOG_FILE" @@ -138 +186,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "Service network created with ID: $SERVICE_NETWORK_ID" | tee -a $LOG_FILE + validate_input "$SERVICE_NETWORK_ID" "SERVICE_NETWORK_ID" || exit 1 + + echo "Service network created with ID: $SERVICE_NETWORK_ID" | tee -a "$LOG_FILE" @@ -142 +192 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - wait_for_resource "Service Network" "$SERVICE_NETWORK_ID" "ACTIVE" "aws vpc-lattice get-service-network --service-network-identifier $SERVICE_NETWORK_ID" + wait_for_resource "Service Network" "$SERVICE_NETWORK_ID" "ACTIVE" "aws vpc-lattice get-service-network --service-network-identifier '$SERVICE_NETWORK_ID' --output json" @@ -146,2 +196,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo -e "\n=== Step 2: Creating a VPC Lattice service ===" | tee -a $LOG_FILE - echo "Creating service: $SERVICE_NAME" | tee -a $LOG_FILE + echo -e "\n=== Step 2: Creating a VPC Lattice service ===" | tee -a "$LOG_FILE" + echo "Creating service: $SERVICE_NAME" | tee -a "$LOG_FILE" @@ -149 +199 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - SERVICE_OUTPUT=$(log_command "aws vpc-lattice create-service --name $SERVICE_NAME") + SERVICE_OUTPUT=$(log_command "aws vpc-lattice create-service --name '$SERVICE_NAME' --output json") @@ -152,2 +202,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Extract the service ID - SERVICE_ID=$(echo "$SERVICE_OUTPUT" | grep -o '"id": "[^"]*' | cut -d'"' -f4) + # Extract the service ID using jq for safety + SERVICE_ID=$(echo "$SERVICE_OUTPUT" | jq -r '.id // empty' 2>/dev/null || true) @@ -155 +205 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "ERROR: Failed to extract service ID" | tee -a $LOG_FILE + echo "ERROR: Failed to extract service ID" | tee -a "$LOG_FILE" @@ -159 +209,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "Service created with ID: $SERVICE_ID" | tee -a $LOG_FILE + validate_input "$SERVICE_ID" "SERVICE_ID" || exit 1 + + echo "Service created with ID: $SERVICE_ID" | tee -a "$LOG_FILE" @@ -163 +215 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - wait_for_resource "Service" "$SERVICE_ID" "ACTIVE" "aws vpc-lattice get-service --service-identifier $SERVICE_ID" + wait_for_resource "Service" "$SERVICE_ID" "ACTIVE" "aws vpc-lattice get-service --service-identifier '$SERVICE_ID' --output json" @@ -167 +219 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo -e "\n=== Step 3: Associating service with service network ===" | tee -a $LOG_FILE + echo -e "\n=== Step 3: Associating service with service network ===" | tee -a "$LOG_FILE" @@ -169 +221 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - SERVICE_ASSOC_OUTPUT=$(log_command "aws vpc-lattice create-service-network-service-association --service-identifier $SERVICE_ID --service-network-identifier $SERVICE_NETWORK_ID") + SERVICE_ASSOC_OUTPUT=$(log_command "aws vpc-lattice create-service-network-service-association --service-identifier '$SERVICE_ID' --service-network-identifier '$SERVICE_NETWORK_ID' --output json") @@ -172,2 +224,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Extract the service association ID - SERVICE_ASSOC_ID=$(echo "$SERVICE_ASSOC_OUTPUT" | grep -o '"id": "[^"]*' | cut -d'"' -f4) + # Extract the service association ID using jq for safety + SERVICE_ASSOC_ID=$(echo "$SERVICE_ASSOC_OUTPUT" | jq -r '.id // empty' 2>/dev/null || true) @@ -175 +227 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "ERROR: Failed to extract service association ID" | tee -a $LOG_FILE + echo "ERROR: Failed to extract service association ID" | tee -a "$LOG_FILE" @@ -179 +231,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "Service association created with ID: $SERVICE_ASSOC_ID" | tee -a $LOG_FILE + validate_input "$SERVICE_ASSOC_ID" "SERVICE_ASSOC_ID" || exit 1 + + echo "Service association created with ID: $SERVICE_ASSOC_ID" | tee -a "$LOG_FILE" @@ -183 +237 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - wait_for_resource "Service Association" "$SERVICE_ASSOC_ID" "ACTIVE" "aws vpc-lattice get-service-network-service-association --service-network-service-association-identifier $SERVICE_ASSOC_ID" + wait_for_resource "Service Association" "$SERVICE_ASSOC_ID" "ACTIVE" "aws vpc-lattice get-service-network-service-association --service-network-service-association-identifier '$SERVICE_ASSOC_ID' --output json" @@ -187 +241 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo -e "\n=== Step 4: Listing available VPCs ===" | tee -a $LOG_FILE