{"title":"Insecure Key Derivation via Low PBKDF2 Iteration Count","language":"Python","severity":"High","cwe":"CWE-916","source_lines":[4],"flow_lines":[4,6,7],"sink_lines":[7],"vulnerable_code":"import hashlib\nimport os\nfrom base64 import b64encode\n\ndef secure_iot_device_pairing(device_mac, owner_pin):\n    salt = os.urandom(16)\n    iterations = 100\n    derived_key = hashlib.pbkdf2_hmac('sha256', owner_pin.encode(), salt, iterations, dklen=32)\n    pairing_token = b64encode(salt + derived_key).decode('utf-8')\n    store_device_credential(device_mac, pairing_token)\n    return {'device_id': device_mac, 'pairing_token': pairing_token, 'status': 'paired'}\n\ndef store_device_credential(mac, token):\n    with open(f'/var/iot/devices/{mac}.cred', 'w') as f:\n        f.write(token)","explanation":"The code uses only 100 PBKDF2 iterations to derive cryptographic keys from PIN codes, which is far below the recommended minimum of 600,000 iterations for PBKDF2-HMAC-SHA256 (OWASP 2023). This makes the derived keys extremely vulnerable to brute-force and GPU-accelerated attacks, allowing attackers who capture pairing tokens to rapidly crack the owner PINs and compromise device security.","remediation":"The fix increases the PBKDF2 iteration count from 100 to 600,000, which is the OWASP 2023 recommended minimum for PBKDF2-HMAC-SHA256. This makes brute-force and GPU-accelerated attacks computationally infeasible, even against short PIN codes, by dramatically increasing the time required to test each candidate password.","secure_code":"import hashlib\nimport os\nfrom base64 import b64encode\n\ndef secure_iot_device_pairing(device_mac, owner_pin):\n    salt = os.urandom(16)\n    iterations = 600000\n    derived_key = hashlib.pbkdf2_hmac('sha256', owner_pin.encode(), salt, iterations, dklen=32)\n    pairing_token = b64encode(salt + derived_key).decode('utf-8')\n    store_device_credential(device_mac, pairing_token)\n    return {'device_id': device_mac, 'pairing_token': pairing_token, 'status': 'paired'}\n\ndef store_device_credential(mac, token):\n    with open(f'/var/iot/devices/{mac}.cred', 'w') as f:\n        f.write(token)"}