How Python's str.lower() Can Quietly Become a Security Bug
A blog post by security engineer Seth Larson highlights a subtle but real risk in Python code: using str.lower() to normalize strings before comparing them, such as checking usernames, domains, or access tokens.
The problem stems from Unicode. Because str.lower() follows full Unicode case-folding rules rather than simple ASCII lowercasing, certain characters can transform in unexpected ways. Some Unicode characters lowercase into multiple characters, while others from entirely different scripts can collapse into the same lowercase form. That means two strings that look distinct to a human reviewer, or that should be treated as different, can become identical after calling .lower(), potentially bypassing authentication checks, filters, or deduplication logic.
Larson recommends using str.casefold() with caution too, and more importantly, restricting comparisons to ASCII-only contexts when the input space is meant to be constrained, or using explicit Unicode normalization libraries when true internationalization is required.