Python · The language, not just syntax
Which security practices matter most in Python services?
Short answer
Validate untrusted input, use parameterised queries, keep secrets out of code and logs, hash passwords with a modern algorithm, avoid unsafe deserialisation, and pin and scan dependencies.
Most Python security bugs come from trusting input or using a powerful API on untrusted data. The mitigations are usually well-known patterns rather than exotic techniques, so consistency and review matter more than cleverness.
import hmac
import sqlite3
def find_user(connection, username):
cursor = connection.execute(
"select id, username from users where username = ?",
(username,),
)
return cursor.fetchone()
def tokens_match(provided, expected):
return hmac.compare_digest(provided, expected)The high-value checklist
- SQL: always use driver parameters, never string formatting into queries
- Passwords: use Argon2id or bcrypt with a per-user salt, never raw SHA-256
- Deserialisation: avoid pickle and yaml.load on untrusted data; use JSON and yaml.safe_load
- Processes: prefer shell=False with an argument list, and validate any path input
- Secrets: load from a secret manager or environment, never commit them or log them
Dependency risk is part of your attack surface. Pin versions, review lock-file changes, run a vulnerability scanner in CI, and remove unused packages. Typosquatted packages and compromised maintainer accounts are common supply-chain attacks.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Why are parameterised queries safer than escaping strings?
- 2Which password hashing algorithms would you choose and why?
- 3Why is pickle unsafe for untrusted data?
- 4How do you manage secrets across environments?
Say it in the interview
I treat all external input as untrusted and use parameterised queries, strict schema validation and safe parsers. Passwords go through Argon2id or bcrypt, secrets come from a manager and never appear in code or logs, and token comparisons use compare_digest. I avoid pickle and unsafe YAML loading, run subprocesses without a shell, and scan pinned dependencies in CI. Security checks fail closed, because silently allowing access is worse than an outage.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Python mock interview and get scored feedback on depth, clarity and confidence.