AWS AmazonCloudWatch high security documentation change
Summary
Enhanced example script with security hardening: added sensitive data sanitization in logs, secure file permissions, input validation, resource cleanup automation, and security best practices
Security assessment
Changes explicitly add security measures: 1) Sanitization of credentials in logs (--password*/--secret* redaction), 2) Account ID masking in output, 3) Restrictive umask (0077) and file permissions (chmod 600), 4) Secure temporary file deletion (shred), 5) Input validation to prevent malformed resources, 6) Removal of interactive cleanup that could leave resources exposed. These directly mitigate risks of credential leakage, unauthorized file access, and residual resource exposure.
Diff
diff --git a/AmazonCloudWatch/latest/monitoring/example_iam_GettingStarted_032_section.md b/AmazonCloudWatch/latest/monitoring/example_iam_GettingStarted_032_section.md index 78c0b205e..91543daba 100644 --- a//AmazonCloudWatch/latest/monitoring/example_iam_GettingStarted_032_section.md +++ b//AmazonCloudWatch/latest/monitoring/example_iam_GettingStarted_032_section.md @@ -38 +38,6 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Set up logging + set -euo pipefail + + # Security: Set restrictive umask + umask 0077 + + # Set up logging with secure permissions @@ -40 +45,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "Starting script execution at $(date)" > "$LOG_FILE" + touch "$LOG_FILE" + chmod 600 "$LOG_FILE" + echo "Starting script execution at $(date)" >> "$LOG_FILE" @@ -42 +49 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Function to log commands and their output + # Function to log commands and their output (with sensitive data sanitization) @@ -44,2 +51,5 @@ 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" + local cmd="$1" + local sanitized_cmd="${cmd//--password*/--password [REDACTED]}" + sanitized_cmd="${sanitized_cmd//--secret*/--secret [REDACTED]}" + echo "$(date): Running command: $sanitized_cmd" >> "$LOG_FILE" + eval "$cmd" 2>&1 | tee -a "$LOG_FILE" @@ -55 +65 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ $cmd_status -ne 0 ] || echo "$cmd_output" | grep -i "error" > /dev/null; then + if [ $cmd_status -ne 0 ] || echo "$cmd_output" | grep -qi "error"; then @@ -57 +67,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "Command output: $cmd_output" | tee -a "$LOG_FILE" + # Sanitize output before logging + local sanitized_output="${cmd_output//arn:aws:iam::[0-9]*/arn:aws:iam::ACCOUNT_ID}" + echo "Command output: $sanitized_output" | tee -a "$LOG_FILE" @@ -62,0 +75,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + # Trap errors and cleanup + trap 'cleanup_resources' EXIT ERR INT TERM + @@ -64,0 +80,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + local exit_code=$? + @@ -70 +87 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ -n "$DASHBOARD_NAME" ]; then + if [ -n "${DASHBOARD_NAME:-}" ]; then @@ -72 +89 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - log_cmd "aws cloudwatch delete-dashboards --dashboard-names \"$DASHBOARD_NAME\"" + aws cloudwatch delete-dashboards --dashboard-names "$DASHBOARD_NAME" 2>&1 >> "$LOG_FILE" || true @@ -75 +92 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ -n "$LAMBDA_FUNCTION1" ]; then + if [ -n "${LAMBDA_FUNCTION1:-}" ]; then @@ -77 +94 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - log_cmd "aws lambda delete-function --function-name \"$LAMBDA_FUNCTION1\"" + aws lambda delete-function --function-name "$LAMBDA_FUNCTION1" 2>&1 >> "$LOG_FILE" || true @@ -80 +97 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ -n "$LAMBDA_FUNCTION2" ]; then + if [ -n "${LAMBDA_FUNCTION2:-}" ]; then @@ -82 +99 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - log_cmd "aws lambda delete-function --function-name \"$LAMBDA_FUNCTION2\"" + aws lambda delete-function --function-name "$LAMBDA_FUNCTION2" 2>&1 >> "$LOG_FILE" || true @@ -85 +102 @@ 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 @@ -87 +104 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - log_cmd "aws iam detach-role-policy --role-name \"$ROLE_NAME\" --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + aws iam detach-role-policy --role-name "$ROLE_NAME" --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole 2>&1 >> "$LOG_FILE" || true @@ -90 +107 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - log_cmd "aws iam delete-role --role-name \"$ROLE_NAME\"" + aws iam delete-role --role-name "$ROLE_NAME" 2>&1 >> "$LOG_FILE" || true @@ -93,2 +110,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "Cleanup completed." | tee -a "$LOG_FILE" - } + # Clean up temporary files securely + shred -vfz -n 3 trust-policy.json lambda_function.py lambda_function.zip 2>/dev/null || rm -f trust-policy.json lambda_function.py lambda_function.zip @@ -96,12 +113 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Function to prompt for cleanup confirmation - confirm_cleanup() { - echo "" | tee -a "$LOG_FILE" - echo "==========================================" | tee -a "$LOG_FILE" - echo "CLEANUP CONFIRMATION" | tee -a "$LOG_FILE" - echo "==========================================" | tee -a "$LOG_FILE" - echo "The following resources were created:" | tee -a "$LOG_FILE" - echo "- CloudWatch Dashboard: $DASHBOARD_NAME" | tee -a "$LOG_FILE" - - if [ -n "$LAMBDA_FUNCTION1" ]; then - echo "- Lambda Function: $LAMBDA_FUNCTION1" | tee -a "$LOG_FILE" - fi + echo "Cleanup completed." | tee -a "$LOG_FILE" @@ -109,3 +115,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ -n "$LAMBDA_FUNCTION2" ]; then - echo "- Lambda Function: $LAMBDA_FUNCTION2" | tee -a "$LOG_FILE" - fi + return $exit_code + } @@ -113,2 +118,4 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - if [ -n "$ROLE_NAME" ]; then - echo "- IAM Role: $ROLE_NAME" | tee -a "$LOG_FILE" + # Validate AWS CLI is installed and authenticated + if ! command -v aws &> /dev/null; then + echo "ERROR: AWS CLI is not installed" | tee -a "$LOG_FILE" + exit 1 @@ -117,8 +124,3 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - echo "" | tee -a "$LOG_FILE" - echo "Do you want to clean up all created resources? (y/n): " | tee -a "$LOG_FILE" - read -r CLEANUP_CHOICE - - if [[ "$CLEANUP_CHOICE" =~ ^[Yy]$ ]]; then - cleanup_resources - else - echo "Resources were not cleaned up. You can manually delete them later." | tee -a "$LOG_FILE" + if ! aws sts get-caller-identity &> /dev/null; then + echo "ERROR: AWS CLI is not properly authenticated" | tee -a "$LOG_FILE" + exit 1 @@ -126 +127,0 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - } @@ -128,2 +129,2 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Get AWS region - AWS_REGION=$(aws configure get region) + # Get AWS region with validation + AWS_REGION=$(aws configure get region 2>/dev/null || echo "") @@ -137 +138,7 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Generate unique identifiers + # Validate region format + if ! [[ "$AWS_REGION" =~ ^[a-z]{2}-[a-z]+-[0-9]$ ]]; then + echo "ERROR: Invalid AWS region format: $AWS_REGION" | tee -a "$LOG_FILE" + exit 1 + fi + + # Generate unique identifiers using secure random with validation @@ -138,0 +146,5 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + if [ -z "$RANDOM_ID" ] || [ ${#RANDOM_ID} -ne 12 ]; then + echo "ERROR: Failed to generate valid random identifier" | tee -a "$LOG_FILE" + exit 1 + fi + @@ -143,0 +156,6 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + # Validate resource names don't exceed AWS limits + if [ ${#DASHBOARD_NAME} -gt 128 ] || [ ${#LAMBDA_FUNCTION1} -gt 64 ] || [ ${#ROLE_NAME} -gt 64 ]; then + echo "ERROR: Generated resource names exceed AWS limits" | tee -a "$LOG_FILE" + exit 1 + fi + @@ -164,0 +183,7 @@ There's more on GitHub. Find the complete example and learn how to set up and ru + chmod 600 trust-policy.json + + # Validate JSON before use + if ! python3 -m json.tool trust-policy.json > /dev/null 2>&1; then + echo "ERROR: Invalid trust policy JSON" | tee -a "$LOG_FILE" + exit 1 + fi @@ -166 +191 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - ROLE_OUTPUT=$(log_cmd "aws iam create-role --role-name \"$ROLE_NAME\" --assume-role-policy-document file://trust-policy.json --output json") + ROLE_OUTPUT=$(log_cmd "aws iam create-role --role-name '$ROLE_NAME' --assume-role-policy-document file://trust-policy.json --tags Key=project,Value=doc-smith Key=tutorial,Value=cloudwatch-streams --output json") @@ -169 +194,5 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - ROLE_ARN=$(echo "$ROLE_OUTPUT" | grep -o '"Arn": "[^"]*' | cut -d'"' -f4) + ROLE_ARN=$(echo "$ROLE_OUTPUT" | python3 -c "import sys, json; print(json.load(sys.stdin)['Role']['Arn'])" 2>/dev/null) + if [ -z "$ROLE_ARN" ]; then + echo "ERROR: Failed to extract Role ARN" | tee -a "$LOG_FILE" + exit 1 + fi @@ -174 +203 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - POLICY_OUTPUT=$(log_cmd "aws iam attach-role-policy --role-name \"$ROLE_NAME\" --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole") + POLICY_OUTPUT=$(log_cmd "aws iam attach-role-policy --role-name '$ROLE_NAME' --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole") @@ -181 +210 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - # Create simple Python Lambda function code + # Create simple Python Lambda function code with security validation @@ -183 +212 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - cat > lambda_function.py << 'EOF' + cat > lambda_function.py << 'LAMBDA_EOF' @@ -190 +219,9 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - EOF + LAMBDA_EOF + + chmod 600 lambda_function.py + + # Validate Python syntax + if ! python3 -m py_compile lambda_function.py 2>/dev/null; then + echo "ERROR: Invalid Python syntax in Lambda function" | tee -a "$LOG_FILE" + exit 1 + fi @@ -193 +230,12 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - log_cmd "zip -j lambda_function.zip lambda_function.py" + zip -j -q lambda_function.zip lambda_function.py + if [ ! -f lambda_function.zip ]; then + echo "ERROR: Failed to create lambda_function.zip" | tee -a "$LOG_FILE" + exit 1 + fi + chmod 600 lambda_function.zip + + # Validate zip file integrity + if ! unzip -t lambda_function.zip > /dev/null 2>&1; then + echo "ERROR: Created zip file is corrupted" | tee -a "$LOG_FILE" + exit 1 + fi @@ -197 +245 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - LAMBDA1_OUTPUT=$(log_cmd "aws lambda create-function --function-name \"$LAMBDA_FUNCTION1\" --runtime python3.9 --role \"$ROLE_ARN\" --handler lambda_function.handler --zip-file fileb://lambda_function.zip") + LAMBDA1_OUTPUT=$(log_cmd "aws lambda create-function --function-name '$LAMBDA_FUNCTION1' --runtime python3.11 --role '$ROLE_ARN' --handler lambda_function.handler --zip-file fileb://lambda_function.zip --timeout 30 --memory-size 128 --tags project=doc-smith,tutorial=cloudwatch-streams") @@ -202 +250 @@ There's more on GitHub. Find the complete example and learn how to set up and ru - LAMBDA2_OUTPUT=$(log_cmd "aws lambda create-function --function-name \"$LAMBDA_FUNCTION2\" --runtime python3.9 --role \"$ROLE_ARN\" --handler lambda_function.handler --zip-file fileb://lambda_function.zip")