AWS code-library high security documentation change
Summary
Updated VPC Lattice tutorial script with security enhancements including input validation, secure permissions for log files, command injection prevention, and automated cleanup. Replaced manual user input with auto-selection for VPC and security groups.
Security assessment
The changes add concrete security features: 1) Input validation against command injection patterns using regex, 2) Secure log file permissions (chmod 600), 3) Safer variable handling with quotes, 4) Added jq parsing to prevent output manipulation vulnerabilities. These directly mitigate security risks like command injection and unauthorized log access.
Diff
diff --git a/code-library/latest/ug/bash_2_vpc-lattice_code_examples.md b/code-library/latest/ug/bash_2_vpc-lattice_code_examples.md index 3c506f4a2..7cfbad243 100644 --- a//code-library/latest/ug/bash_2_vpc-lattice_code_examples.md +++ b//code-library/latest/ug/bash_2_vpc-lattice_code_examples.md @@ -60 +60,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 @@ -62 +64,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" @@ -66,3 +70,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]}" @@ -73,2 +78,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" @@ -76 +81,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 @@ -79,0 +93,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 + } + @@ -82,4 +114,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" @@ -90 +122,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 @@ -92,2 +126,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" @@ -96,2 +132,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" @@ -99 +135 @@ 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 @@ -103 +139 @@ 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" @@ -108,2 +144,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" @@ -112 +148 @@ 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" @@ -115 +151 @@ 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" @@ -120 +156 @@ 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" @@ -125 +161 @@ 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" @@ -128,0 +165,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 + @@ -135 +183 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - CREATED_RESOURCES=() + declare -a CREATED_RESOURCES @@ -137,2 +185,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" @@ -141,2 +189,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" @@ -144 +192 @@ 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") @@ -147,2 +195,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) @@ -150 +198 @@ 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" @@ -154 +202,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" @@ -158 +208 @@ 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" @@ -162,2 +212,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" @@ -165 +215 @@ 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") @@ -168,2 +218,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) @@ -171 +221 @@ 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" @@ -175 +225,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" @@ -179 +231 @@ 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" @@ -183 +235 @@ 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" @@ -185 +237 @@ 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") @@ -188,2 +240,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) @@ -191 +243 @@ 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" @@ -195 +247,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" @@ -199 +253 @@ 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" @@ -203 +257 @@ 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