{"title":"Hardcoded Symmetric Key Exposure in Fernet Encryption","language":"Python","severity":"Critical","cwe":"CWE-798","source_lines":[5],"flow_lines":[5],"sink_lines":[5],"vulnerable_code":"from cryptography.fernet import Fernet\nimport boto3\n\ndef encrypt_iot_telemetry(device_id, sensor_data):\n    DEVICE_MASTER_KEY = b'zK8vN2pQrT9xL4mW6hF3jD5sA7cE1bY0uI8oP6gH2nM='\n    cipher = Fernet(DEVICE_MASTER_KEY)\n    payload = f\"{device_id}|{sensor_data['temp']}|{sensor_data['humidity']}\"\n    encrypted_payload = cipher.encrypt(payload.encode())\n    s3_client = boto3.client('s3')\n    s3_client.put_object(Bucket='iot-telemetry-encrypted', Key=f'device_{device_id}.enc', Body=encrypted_payload)\n    return {'status': 'uploaded', 'device': device_id}","explanation":"The code contains a hardcoded Fernet symmetric encryption key (DEVICE_MASTER_KEY) directly embedded in the source code. This key is used to encrypt sensitive IoT telemetry data, but since it's hardcoded, anyone with access to the source code or decompiled binary can decrypt all encrypted data, rendering the encryption useless.","remediation":"The fix removes the hardcoded encryption key and instead retrieves it securely at runtime from AWS Secrets Manager using a per-device secret path. This ensures the key is never exposed in source code, version control, or compiled artifacts, and allows for per-device key rotation without code changes.","secure_code":"from cryptography.fernet import Fernet\nimport boto3\nimport os\n\n\ndef get_device_encryption_key(device_id):\n    \"\"\"Retrieve the encryption key from AWS Secrets Manager.\"\"\"\n    session = boto3.session.Session()\n    secrets_client = session.client(service_name='secretsmanager')\n    secret_response = secrets_client.get_secret_value(SecretId=f'iot/device-master-key/{device_id}')\n    return secret_response['SecretString'].encode()\n\n\ndef encrypt_iot_telemetry(device_id, sensor_data):\n    device_key = get_device_encryption_key(device_id)\n    cipher = Fernet(device_key)\n    payload = f\"{device_id}|{sensor_data['temp']}|{sensor_data['humidity']}\"\n    encrypted_payload = cipher.encrypt(payload.encode())\n    s3_client = boto3.client('s3')\n    s3_client.put_object(Bucket='iot-telemetry-encrypted', Key=f'device_{device_id}.enc', Body=encrypted_payload)\n    return {'status': 'uploaded', 'device': device_id}"}