SQL Injection Explained: How to Secure Your Python Code
It is the oldest trick in the book, yet it still destroys companies in 2026. If you are using f-strings to build your database queries, you are holding the door open for hackers.
We all love Python's f-strings. They are clean, readable, and fast. `f"Hello {name}"` is much nicer than the old `.format()` method. But when it comes to Database Queries (SQL), f-strings are deadly.
This vulnerability is called SQL Injection (SQLi). It happens when untrusted user input is treated as code instead of data. If an attacker knows you are doing this, they can trick your database into revealing passwords, deleting tables, or granting them admin access.
The Vulnerability: Anatomy of a Hack
Imagine you have a simple login script. You take a `username` from a form and check if it exists.
If the user enters `John`, the query becomes:
SELECT * FROM users WHERE username = 'John'
This works fine.
But what if the user enters this as their username?
admin' --
The query now becomes:
SELECT * FROM users WHERE username = 'admin' --'
In SQL, -- means "Comment." It tells the database to ignore everything that comes after it. The attacker just tricked your database into running a query for the admin user without needing a password. They are logged in as Admin.
The Fix: Parameterized Queries
The solution is not to "clean" or "sanitize" the input yourself (you will miss something). The solution is to use Parameterized Queries.
This technique sends the SQL logic and the user data separately. The database compiles the SQL command first, and then inserts the user data safely. Even if the data contains malicious SQL commands, the database treats it as just a harmless text string.
How to do it in Python (SQLite/PostgreSQL)
Instead of f-strings, use placeholders like `?` (for SQLite) or `%s` (for PostgreSQL/MySQL).
Now, if the user types `admin' --`, the database searches for a user whose literal username is "admin' --". It finds nothing. The hack fails.
Comparison: Vulnerable vs. Secure
| Feature | F-Strings (Vulnerable) | Parameterized (Secure) |
|---|---|---|
| Execution Logic | Compiles data AND code together | Compiles code first, then adds data |
| Hacking Risk | High (Easy to exploit) | Near Zero (Architecture prevents it) |
| Performance | Slower (Re-compiles every query) | Faster (Caches the query plan) |
| Syntax | f"SELECT {var}" |
"SELECT ?", (var,) |
Conclusion
Security is not an "advanced" topic; it is a fundamental responsibility. Writing secure code is just as important as writing working code.
Go check your codebase right now. Ctrl + F for `f"SELECT` or `f"INSERT`. If you find any, fix them immediately.

Comments
Post a Comment