VNX-1427 – Improper Neutralization of Input Used in an Assertion
Overview
Python’s assert statement is a debugging tool, not a security mechanism. When Python is invoked with -O (optimise) or -OO flags, all assert statements are stripped from the bytecode at compile time — they never execute. Using assert for security checks (length validation of passwords, permission checks, input sanitisation) creates invisible security holes in optimised deployments. Severity: Medium | CWE: CWE-1427 – Improper Neutralization of Input Used in an Assertion
Why This Matters
Flask’s production WSGI servers (gunicorn, uWSGI) sometimes run with optimisation. WSGI deployment documentation occasionally recommends -O for performance. Any assert in request-handling code will be silently bypassed. The Python documentation explicitly warns: “assert statements are disabled when the Python interpreter is started in optimised mode”.
What Gets Flagged
# FLAGGED: assert used for password length check
def set_password(password):
assert len(password) >= 8, "Password too short" # disabled with -O
save_password(hash(password))
# FLAGGED: assert for authentication check
def get_user_data(user_id, current_user):
assert current_user.is_authenticated # disabled with -O — always passes
return User.objects.get(id=user_id)
# FLAGGED: assert on request data
def create_item(request):
assert request.user.is_admin # disabled with -O
Item.objects.create(**request.POST)
Remediation
Replace assert with explicit if/raise statements for all security-critical checks:
# SAFE: Explicit validation that cannot be disabled
def set_password(password):
if len(password) < 8:
raise ValueError("Password must be at least 8 characters")
save_password(hash_password(password))
# SAFE: Explicit authentication check
def get_user_data(user_id, current_user):
if not current_user.is_authenticated:
raise PermissionDenied("Authentication required")
return User.objects.get(id=user_id)
# SAFE: Django @login_required decorator (cannot be disabled)
from django.contrib.auth.decorators import login_required, permission_required
@login_required
@permission_required('myapp.add_item')
def create_item(request):
Item.objects.create(**request.POST)
For input validation in Django, use form validation or serializer validation which runs unconditionally.