# Yappuccino Security Measures Configured for Production Deployment: A Complete Guide

> Learn Yappuccino security measures for production deployment. Secure your Django app with HTTPS, HSTS, SSL redirect, host validation, and S3 media isolation.

- Repository: [Ja'farbek Yusupov/yappuccino](https://github.com/jafarbekyusupov/yappuccino)
- Tags: how-to-guide
- Published: 2026-03-04

---

**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`](https://github.com/jafarbekyusupov/yappuccino/blob/main/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`](https://github.com/jafarbekyusupov/yappuccino/blob/main/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`](https://github.com/jafarbekyusupov/yappuccino/blob/main/blogpost/production.py) restricts which hostnames Django will serve:

```python

# 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`](https://github.com/jafarbekyusupov/yappuccino/blob/main/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

### Cookie Security Hardening

Session and CSRF tokens receive secure flag protection:

```python

# 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`](https://github.com/jafarbekyusupov/yappuccino/blob/main/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:

```python

# 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`](https://github.com/jafarbekyusupov/yappuccino/blob/main/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:

```python

# 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`](https://github.com/jafarbekyusupov/yappuccino/blob/main/blogpost/settings.py) to serve static files securely without relying on Nginx or Apache in containerized deployments. The storage backend uses:

```python

# 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`](https://github.com/jafarbekyusupov/yappuccino/blob/main/blogpost/production.py):

```python

# 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`](https://github.com/jafarbekyusupov/yappuccino/blob/main/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`](https://github.com/jafarbekyusupov/yappuccino/blob/main/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`](https://github.com/jafarbekyusupov/yappuccino/blob/main/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`](https://github.com/jafarbekyusupov/yappuccino/blob/main/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.