Skip to content

Security

Overview

SpeedPy includes several security features out of the box: reCAPTCHA for bot protection, Django's password validators, CSRF protection, clickjacking prevention, SSL proxy support, and encrypted model fields.

reCAPTCHA

SpeedPy uses django-recaptcha (Google reCAPTCHA v3) for bot protection on forms.

RECAPTCHA_PUBLIC_KEY = env("RECAPTCHA_PUBLIC_KEY", default="")
RECAPTCHA_PRIVATE_KEY = env("RECAPTCHA_PRIVATE_KEY", default="")
RECAPTCHA_REQUIRED_SCORE = env.float("RECAPTCHA_REQUIRED_SCORE", default=0.5)

When the keys are empty, reCAPTCHA runs in test mode (always passes). Set your keys in production.

Password Validators

All four of Django's built-in password validators are enabled:

  • UserAttributeSimilarityValidator — prevents passwords similar to user attributes
  • MinimumLengthValidator — enforces minimum password length
  • CommonPasswordValidator — blocks common passwords
  • NumericPasswordValidator — prevents all-numeric passwords

CSRF Protection

Django's CSRF middleware is enabled by default:

MIDDLEWARE = [
    ...
    "django.middleware.csrf.CsrfViewMiddleware",
    ...
]

Clickjacking Protection

The XFrameOptionsMiddleware prevents your site from being embedded in iframes:

MIDDLEWARE = [
    ...
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    ...
]

SSL Proxy Header

For deployments behind a reverse proxy (Nginx, load balancer), SpeedPy trusts the X-Forwarded-Proto header to detect HTTPS:

SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

Encrypted Fields

SpeedPy includes django-fernet-encrypted-fields for encrypting sensitive model fields at rest. The encryption key is derived from SALT_KEY:

SALT_KEY = env("SALT_KEY", default="changeme")

Warning

Change the SALT_KEY before deploying to production. If you change it after data is encrypted, that data will become unreadable.

Admin URL

The admin URL is configurable to make it harder to find:

ADMIN_URL = env.str("ADMIN_URL", default="admin/")

Set ADMIN_URL to something unique in production (e.g., "my-secret-admin/").

Account Security

  • Email verification is mandatory — users must confirm their email before accessing the app
  • "Account already exists" emails are suppressed — prevents information leakage about registered users
  • Two-factor authentication — available via TOTP (see Two-Factor Authentication)

API Token Issuance Gates

SpeedPy enforces conservative security defaults for API token creation:

Gate Applies to Behavior
Verified email JWT + PAT Tokens cannot be issued unless the user's primary email is verified
TOTP MFA JWT Users with TOTP enabled must provide a valid mfa_code in the token request
Recent reauthentication PAT (web UI) Users must have authenticated recently before creating a PAT; allauth's reauthentication flow is used, which requires MFA when enabled

Configuration

All gates are on by default. Override with settings or environment variables:

SPEEDPY_API_TOKEN_REQUIRE_VERIFIED_EMAIL = True   # verified email for JWT + PAT
SPEEDPY_JWT_REQUIRE_MFA = True                     # TOTP for JWT when enrolled
SPEEDPY_PAT_REQUIRE_RECENT_REAUTH = True           # reauth for PAT creation

Email verification sync

User.is_email_confirmed is kept in sync with the allauth EmailAddress model via a post_save signal. When the primary email address is verified or unverified, the user model field is updated automatically.