AWS Security ChangesHomeSearch

AWS code-library medium security documentation change

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

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

Summary

Enhanced AWS Step Functions example script with security best practices including strict file permissions, input validation, least privilege IAM policies, secure credential checks, and improved resource cleanup mechanisms.

Security assessment

Changes explicitly address security weaknesses: added umask 077 to prevent insecure file permissions, implemented chmod 600 for log files, added AWS credential validation to prevent unauthorized access, introduced least privilege IAM policies (restricting Step Functions actions/resources), added JSON input validation to prevent injection attacks, and implemented secure file deletion with shred. These mitigate risks of credential exposure, privilege escalation, and data leakage.

Diff

diff --git a/code-library/latest/ug/sfn_example_iam_GettingStarted_080_section.md b/code-library/latest/ug/sfn_example_iam_GettingStarted_080_section.md
index d51b7bf5d..290ff3b68 100644
--- a//code-library/latest/ug/sfn_example_iam_GettingStarted_080_section.md
+++ b//code-library/latest/ug/sfn_example_iam_GettingStarted_080_section.md
@@ -39,0 +40,5 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    set -euo pipefail
+    
+    # Security: Restrict umask to prevent unintended file permissions
+    umask 077
+    
@@ -41 +46 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    AUTO_CLEANUP=false
+    AUTO_CLEANUP=true
@@ -62 +67 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Set up logging
+    # Set up logging with secure permissions
@@ -63,0 +69,5 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    touch "$LOG_FILE"
+    chmod 600 "$LOG_FILE"
+    
+    # Security: Use process substitution with explicit FD cleanup
+    exec 3>&1 4>&2
@@ -64,0 +75 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    trap 'exec 1>&3 2>&4 3>&- 4>&-' EXIT
@@ -68,0 +80,12 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    # Verify AWS CLI is installed and configured
+    if ! command -v aws &> /dev/null; then
+        echo "ERROR: AWS CLI is not installed"
+        exit 1
+    fi
+    
+    # Verify AWS credentials are configured
+    if ! aws sts get-caller-identity &> /dev/null; then
+        echo "ERROR: AWS credentials are not configured or invalid"
+        exit 1
+    fi
+    
@@ -83,0 +107 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    export AWS_REGION="$CURRENT_REGION"
@@ -89 +113,30 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Function to check for API errors in JSON response
+    # Security: Initialize all resource variables
+    STATE_MACHINE_ARN=""
+    ROLE_NAME=""
+    ROLE_ARN=""
+    POLICY_ARN=""
+    STEPFUNCTIONS_POLICY_ARN=""
+    EXECUTION_ARN=""
+    EXECUTION2_ARN=""
+    EXECUTION3_ARN=""
+    
+    # Performance: Cache for AWS API calls to reduce redundant requests
+    declare -A API_CACHE
+    
+    # Function to make cached AWS CLI calls
+    aws_call_cached() {
+        local cache_key="$1"
+        shift
+        
+        if [[ -v API_CACHE["$cache_key"] ]]; then
+            echo "${API_CACHE[$cache_key]}"
+            return 0
+        fi
+        
+        local result
+        result=$(aws "$@" 2>&1) || return $?
+        API_CACHE["$cache_key"]="$result"
+        echo "$result"
+    }
+    
+    # Function to check for API errors in JSON response with optimized jq usage
@@ -95,3 +148,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            # Use jq for more reliable JSON parsing
-            if echo "$response" | jq -e '.Error' > /dev/null 2>&1; then
-                local error_message=$(echo "$response" | jq -r '.Error.Message // .Error.Code // "Unknown error"')
+            # Use jq for more reliable JSON parsing with efficient error detection
+            if echo "$response" | jq -e '.Error // .error // empty' > /dev/null 2>&1; then
+                local error_message=$(echo "$response" | jq -r '.Error.Message // .Error.Code // .error // "Unknown error"' 2>/dev/null)
@@ -101,2 +154,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            # Fallback to grep-based detection
-            if echo "$response" | grep -q '"Error":\|"error":'; then
+            # Fallback to grep-based detection with optimized pattern
+            if echo "$response" | grep -qE '"[Ee]rror":|"error":'; then
@@ -108 +161,13 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Function to wait for resource propagation with exponential backoff
+    # Function to extract JSON field efficiently
+    extract_json_field() {
+        local json="$1"
+        local field="$2"
+        
+        if [[ "$USE_JQ" == "true" ]]; then
+            echo "$json" | jq -r "$field" 2>/dev/null
+        else
+            echo "$json" | grep -oP "\"${field}\":\s*\"\K[^\"]+|\"${field}\":\s*\K[^,}]+" | head -1
+        fi
+    }
+    
+    # Function to securely wait for resource propagation with exponential backoff
@@ -112,0 +178,6 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+        # Validate wait_time is a positive integer
+        if ! [[ "$wait_time" =~ ^[0-9]+$ ]] || [ "$wait_time" -lt 1 ] || [ "$wait_time" -gt 300 ]; then
+            echo "WARNING: Invalid wait time $wait_time, using default 10 seconds"
+            wait_time=10
+        fi
+        
@@ -116,0 +188,11 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+    # Function to validate JSON file efficiently
+    validate_json_file() {
+        local file="$1"
+        
+        if [[ "$USE_JQ" == "true" ]]; then
+            if ! jq empty "$file" 2>/dev/null; then
+                handle_error "Invalid JSON in $file"
+            fi
+        fi
+    }
+    
@@ -121 +203 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$STATE_MACHINE_ARN" ]; then
+        if [ -n "${STATE_MACHINE_ARN:-}" ]; then
@@ -124 +206 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$ROLE_NAME" ]; then
+        if [ -n "${ROLE_NAME:-}" ]; then
@@ -127 +209 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$POLICY_ARN" ]; then
+        if [ -n "${POLICY_ARN:-}" ]; then
@@ -130 +212 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$STEPFUNCTIONS_POLICY_ARN" ]; then
+        if [ -n "${STEPFUNCTIONS_POLICY_ARN:-}" ]; then
@@ -139 +221 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-    # Function to clean up resources
+    # Function to securely clean up resources with parallel deletion
@@ -144 +226 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$STATE_MACHINE_ARN" ]; then
+        if [ -n "${STATE_MACHINE_ARN:-}" ]; then
@@ -146 +228 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            aws stepfunctions delete-state-machine --state-machine-arn "$STATE_MACHINE_ARN" || echo "Failed to delete state machine"
+            aws stepfunctions delete-state-machine --state-machine-arn "$STATE_MACHINE_ARN" 2>/dev/null &
@@ -150 +232 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$POLICY_ARN" ] && [ -n "$ROLE_NAME" ]; then
+        if [ -n "${POLICY_ARN:-}" ] && [ -n "${ROLE_NAME:-}" ]; then
@@ -152 +234 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            aws iam detach-role-policy --role-name "$ROLE_NAME" --policy-arn "$POLICY_ARN" || echo "Failed to detach Comprehend policy"
+            aws iam detach-role-policy --role-name "$ROLE_NAME" --policy-arn "$POLICY_ARN" 2>/dev/null &
@@ -155 +237 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$STEPFUNCTIONS_POLICY_ARN" ] && [ -n "$ROLE_NAME" ]; then
+        if [ -n "${STEPFUNCTIONS_POLICY_ARN:-}" ] && [ -n "${ROLE_NAME:-}" ]; then
@@ -157 +239 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            aws iam detach-role-policy --role-name "$ROLE_NAME" --policy-arn "$STEPFUNCTIONS_POLICY_ARN" || echo "Failed to detach Step Functions policy"
+            aws iam detach-role-policy --role-name "$ROLE_NAME" --policy-arn "$STEPFUNCTIONS_POLICY_ARN" 2>/dev/null &
@@ -159,0 +242,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+        # Wait for detach operations to complete
+        wait 2>/dev/null || true
+        
@@ -161 +246 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$POLICY_ARN" ]; then
+        if [ -n "${POLICY_ARN:-}" ]; then
@@ -163 +248 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            aws iam delete-policy --policy-arn "$POLICY_ARN" || echo "Failed to delete Comprehend policy"
+            aws iam delete-policy --policy-arn "$POLICY_ARN" 2>/dev/null &
@@ -166 +251 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$STEPFUNCTIONS_POLICY_ARN" ]; then
+        if [ -n "${STEPFUNCTIONS_POLICY_ARN:-}" ]; then
@@ -168 +253 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            aws iam delete-policy --policy-arn "$STEPFUNCTIONS_POLICY_ARN" || echo "Failed to delete Step Functions policy"
+            aws iam delete-policy --policy-arn "$STEPFUNCTIONS_POLICY_ARN" 2>/dev/null &
@@ -170,0 +256,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
+        # Wait for policy deletion to complete
+        wait 2>/dev/null || true
+        
@@ -172 +260 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        if [ -n "$ROLE_NAME" ]; then
+        if [ -n "${ROLE_NAME:-}" ]; then
@@ -174 +262 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-            aws iam delete-role --role-name "$ROLE_NAME" || echo "Failed to delete role"
+            aws iam delete-role --role-name "$ROLE_NAME" 2>/dev/null || echo "Failed to delete role"
@@ -177 +265 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        # Remove temporary files
+        # Remove temporary files securely
@@ -179 +267,20 @@ There's more on GitHub. Find the complete example and learn how to set up and ru
-        rm -f hello-world.json updated-hello-world.json sentiment-hello-world.json step-functions-trust-policy.json comprehend-policy.json stepfunctions-policy.json input.json sentiment-input.json
+        local temp_files=(
+            "hello-world.json"
+            "updated-hello-world.json"
+            "sentiment-hello-world.json"
+            "step-functions-trust-policy.json"
+            "comprehend-policy.json"
+            "stepfunctions-policy.json"
+            "input.json"
+            "sentiment-input.json"
+        )
+        
+        for file in "${temp_files[@]}"; do
+            if [ -f "$file" ]; then
+                if command -v shred &> /dev/null; then
+                    shred -vfz -n 3 "$file" 2>/dev/null || rm -f "$file"
+                else
+                    rm -f "$file"
+                fi
+            fi