{"title":"Cryptographic Weakness via Hardcoded IV in AES-CBC Encryption","language":"Python","severity":"High","cwe":"CWE-330","source_lines":[9],"flow_lines":[9,11],"sink_lines":[11],"vulnerable_code":"from Crypto.Cipher import AES\nimport base64\ndef encrypt_telemetry_payload(sensor_data: str, dev_secret: bytes) -> str:\n    FIXED_IV = b'\\x1a\\x2b\\x3c\\x4d\\x5e\\x6f\\x7a\\x8b\\x9c\\xad\\xbe\\xcf\\xd0\\xe1\\xf2\\x03'\n    padded = sensor_data.ljust((len(sensor_data) // 16 + 1) * 16)\n    cipher = AES.new(dev_secret, AES.MODE_CBC, FIXED_IV)\n    raw_ct = cipher.encrypt(padded.encode('utf-8'))\n    return base64.b64encode(raw_ct).decode('utf-8')","explanation":"A hardcoded, static IV (FIXED_IV) is defined at line 4 and directly passed to AES.new() at line 6 for every encryption operation. In AES-CBC mode, reusing the same IV with the same key across multiple encryptions breaks semantic security: identical plaintext blocks produce identical ciphertext blocks, enabling pattern analysis, replay attacks, and potentially plaintext recovery across all IoT devices sharing this codebase.","remediation":"The fix replaces the hardcoded static IV with a cryptographically secure random IV generated via get_random_bytes(16) on every encryption call. The random IV is prepended to the ciphertext before base64 encoding so the decryption side can extract the first 16 bytes as the IV. This ensures that even identical plaintexts produce different ciphertexts, restoring semantic security for AES-CBC mode.","secure_code":"from Crypto.Cipher import AES\nfrom Crypto.Random import get_random_bytes\nimport base64\n\ndef encrypt_telemetry_payload(sensor_data: str, dev_secret: bytes) -> str:\n    iv = get_random_bytes(16)\n    padded = sensor_data.ljust((len(sensor_data) // 16 + 1) * 16)\n    cipher = AES.new(dev_secret, AES.MODE_CBC, iv)\n    raw_ct = cipher.encrypt(padded.encode('utf-8'))\n    return base64.b64encode(iv + raw_ct).decode('utf-8')"}