Password hashing in Django: why a hand-hashed SHA-1 column falls to one offline pass, and how set_password() and a wrapped hasher fix it. OWASP A04.
Read more →
OAuth2 in Django: why a callback that finds the user by the ID token's email lets an attacker in as the victim, and why iss + sub fixes it. OWASP A07.
Read more →
JWT in Django: why alg:none no longer works, why simplejwt signs with your SECRET_KEY, and why logout leaves the access token alive. OWASP A07.
Read more →
MFA in Django: why @login_required cannot see a second factor, how one path that skips it undoes the whole rollout, and what otp_required fixes. OWASP A07.
Read more →
Django password reset flaws: a stored token that never expires or retires, why leaked links stay live, and the one call that fixes both. OWASP A07.
Read more →
Weak passwords in Django: why the four default validators accept Password123!, what NIST 800-63B-4 now forbids, and how to check a breach list. OWASP A07.
Read more →
Session hijacking and fixation in Django: why login() rotates the session key, a hand-rolled flow undoes it, plus cookie flags. OWASP A07.
Read more →
Brute force in Django: why auth never throttles logins, how django-axes and rate limiting close the gap, and why IP-keyed limits fail. OWASP A07.
Read more →
Mass assignment in Django: how fields='__all__' lets attackers over-post fields like status or owner, and how explicit field lists stop it. OWASP A08.
Read more →
Path traversal in Django: how os.path.join lets attackers escape MEDIA_ROOT, why safe_join stops it, and when FileField eliminates the risk. OWASP A01.
Read more →