Yappuccino Security Measures Configured for Production Deployment: A Complete Guide

Yappuccino implements Django security best practices by disabling debug mode, enforcing HTTPS via HSTS and SSL redirect, securing cookies, validating hosts, and isolating media storage to AWS S3.

The jafarbekyusupov/yappuccino repository demonstrates how to harden a Django blog application for production environments. These security measures configured for production deployment protect against common web vulnerabilities including session hijacking, man-in-the-middle attacks, and host header poisoning. The configuration splits sensitive settings between base configuration files and production-specific overrides to minimize attack surface.

Production-Only Security Overrides

The blogpost/production.py file contains settings that activate only when the application runs in production mode. These overrides ensure the application rejects insecure connections and validates incoming requests strictly.

Debug Mode Disabled

Setting DEBUG = False in blogpost/production.py prevents Django from exposing detailed error pages and stack traces to end users. This eliminates a major information disclosure vulnerability where attackers could view source code paths and system configuration through debug error pages.

Host Header Validation

The ALLOWED_HOSTS setting in blogpost/production.py restricts which hostnames Django will serve:


# blogpost/production.py

ALLOWED_HOSTS = ['.onrender.com', 'localhost', '127.0.0.1']

This prevents host header attacks where malicious actors send fake Host headers to bypass security controls or poison caches. The configuration specifically allows Render's domain pattern and local development addresses.

HTTPS Enforcement and Secure Proxies

Production traffic forces encrypted connections through multiple complementary settings in blogpost/production.py:

  • SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') — Tells Django to trust the X-Forwarded-Proto header when running behind a load balancer or proxy
  • SECURE_SSL_REDIRECT = True — Automatically redirects all HTTP requests to HTTPS before they reach view logic

Session and CSRF tokens receive secure flag protection:


# blogpost/production.py

SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

These settings ensure browsers transmit cookies only over encrypted HTTPS connections, preventing session hijacking via man-in-the-middle attacks on unsecured networks.

Base Configuration Security in blogpost/settings.py

Core security middleware and transport layer protections reside in blogpost/settings.py, applying to all environments while supporting production hardening.

HTTP Strict Transport Security (HSTS)

The configuration instructs browsers to enforce HTTPS for extended periods:


# blogpost/settings.py

SECURE_HSTS_SECONDS = 31536000  # 1 year

SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True

The 31536000-second duration (one year) combined with sub-domain inclusion and preload eligibility protects against SSL stripping attacks by ensuring browsers never connect via HTTP.

Security Middleware Stack

The MIDDLEWARE definition in blogpost/settings.py includes django.middleware.security.SecurityMiddleware, which automatically injects security headers:

  • X-Content-Type-Options: nosniff — Prevents MIME-type sniffing attacks
  • X-Frame-Options: SAMEORIGIN — Blocks clickjacking attempts via iframe embedding
  • X-XSS-Protection — Enables browser-side XSS filters

Email Transport Security

Outbound email configuration uses TLS encryption:


# blogpost/settings.py

EMAIL_USE_TLS = True

This ensures password reset emails and administrative notifications transmit securely to Gmail's SMTP servers without credential exposure.

Static and Media File Security

File handling configurations prevent directory traversal attacks and information leakage through improperly served assets.

WhiteNoise Static File Handling

The middleware stack includes whitenoise.middleware.WhiteNoiseMiddleware in blogpost/settings.py to serve static files securely without relying on Nginx or Apache in containerized deployments. The storage backend uses:


# blogpost/settings.py

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

This configuration enables compression and cache-busting hash manifests, preventing outdated or tampered static files from being served.

AWS S3 Media Storage Isolation

User-uploaded files bypass the application server entirely through production-specific storage configuration in blogpost/production.py:


# blogpost/production.py

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_S3_ADDRESSING_STYLE = "virtual"
AWS_S3_SIGNATURE_VERSION = "s3v4"
AWS_QUERYSTRING_AUTH = False

Storing media in S3 with query string authentication disabled prevents temporary credential leakage in URLs, while the virtual addressing style ensures proper bucket isolation.

Deployment Container Security

The repository includes containerization safeguards through Dockerfile configurations that run the application as a non-root user and expose only necessary ports. This reduces privilege escalation risks if the Django process becomes compromised.

Summary

  • Debug disabled: DEBUG = False in blogpost/production.py prevents information disclosure through error pages
  • HTTPS enforced: SECURE_SSL_REDIRECT, HSTS with 1-year duration, and secure proxy headers ensure encrypted transport
  • Cookies secured: SESSION_COOKIE_SECURE and CSRF_COOKIE_SECURE prevent transmission over HTTP
  • Host validation: ALLOWED_HOSTS restricts serving to specific domains, blocking header poisoning
  • Middleware protection: SecurityMiddleware adds XSS, clickjacking, and MIME-sniffing defenses
  • File isolation: WhiteNoise serves static files safely while S3 handles user media off-site

Frequently Asked Questions

How does Yappuccino prevent session hijacking on public Wi-Fi networks?

Yappuccino marks session and CSRF cookies as secure in blogpost/production.py using SESSION_COOKIE_SECURE = True and CSRF_COOKIE_SECURE = True. This ensures browsers transmit authentication tokens only over HTTPS connections, preventing attackers on unsecured networks from intercepting session data through packet sniffing.

What protects Yappuccino from host header poisoning attacks?

The ALLOWED_HOSTS setting in blogpost/production.py explicitly lists permitted domains including .onrender.com patterns. Django rejects any request with a Host header not matching this list, preventing attackers from using fake hostnames to bypass security checks or poison downstream caches.

Why does the production configuration disable query string authentication for S3?

Setting AWS_QUERYSTRING_AUTH = False in blogpost/production.py prevents S3 from generating pre-signed URLs that embed temporary AWS credentials in query parameters. This eliminates the risk of credential leakage through access logs, browser history, or referrer headers while relying on bucket-level access controls for security.

How does Yappuccino enforce HTTPS connections for all users?

The application implements three complementary controls: SECURE_SSL_REDIRECT = True redirects HTTP traffic to HTTPS at the application layer, SECURE_PROXY_SSL_HEADER trusts proxy forwarding headers when behind load balancers, and HSTS headers with SECURE_HSTS_SECONDS = 31536000 instruct browsers to automatically use HTTPS for one year without checking HTTP first.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →