Do not use assert
ID |
python.no_use_assert |
Severity |
low |
Resource |
Risky Values |
Language |
Python |
Tags |
CWE:617, CWE:703, NIST.SP.800-53, PCI-DSS:6.5.1 |
Description
Avoid using the assert
statement in production code as it can be disabled with optimization flags, leading to skipped security checks or critical validations.
Rationale
The assert
statement in Python is typically used for debugging purposes and is not intended for validating user inputs or enforcing runtime checks in production environments. When Python is run with the -O
(optimize) flag, all assert statements are stripped out and not executed. This means any logic relying on asserts for critical validation will be silently bypassed, which can lead to significant security vulnerabilities, especially when assertions are used to check authentication, authorization, or other security-critical conditions.
Using assert
for validation introduces a dangerous behavior disparity between development and production environments. A condition that fails in development could pass unnoticed in production due to the assertion being skipped entirely.
def transfer_funds(account_from, account_to, amount):
assert amount > 0, "Transfer amount must be positive"
account_from.withdraw(amount)
account_to.deposit(amount)
If the above code is run with Python optimizations (python -O
), the assertion will be removed and negative amounts could be transferred, potentially enabling account abuse.
Remediation
Replace assert
statements with proper conditional checks that are always executed, regardless of the interpreter flags. Raise appropriate exceptions or handle errors using control flow that cannot be bypassed.
def transfer_funds(account_from, account_to, amount):
if amount <= 0:
raise ValueError("Transfer amount must be positive")
account_from.withdraw(amount)
account_to.deposit(amount)
This ensures that the check is enforced consistently in all environments and cannot be disabled. Use standard exception handling (ValueError
, TypeError
, or custom exceptions) for validation and input checking.
Adopting this pattern helps maintain robust, predictable, and secure behavior across both development and production deployments.