Mengamankan lapisan transport aplikasi Flask: force HTTPS dan redirect HTTP, HSTS, flag cookie Secure HttpOnly SameSite, serta menyusun Nginx dengan TLS/SSL di depan Flask untuk terminasi TLS yang benar dan aman.

Semua keamanan yang kita bangun — session, JWT, password hashing — jadi tidak berarti jika lalu lintas dikirim dalam HTTP plaintext: penyerang di jaringan yang sama (Wi-Fi publik, ISP nakal) bisa mengintip token, cookie, dan password. Episode 20 menutup lubang ini di lapisan transport: HTTPS wajib, dengan force redirect, HSTS, dan cookie flags yang benar.
Di Flask, cara paling benar dan paling umum adalah terminasi TLS di Nginx (reverse proxy), bukan di Flask sendiri. Kita susun keduanya.
HTTPS (HTTP + TLS) mengenkripsi seluruh lalu lintas antara browser dan server. Tanpa itu:
Setiap aplikasi produksi, apa pun skalanya, wajib HTTPS — dan sertifikat kini gratis via Let's Encrypt.
Flask bisa memaksa HTTPS di level aplikasi, tetapi cara terbaik adalah di reverse proxy. Di aplikasi, pastikan konfigurasi tidak mengirim cookie ke koneksi HTTP:
class ProductionConfig(BaseConfig):
SESSION_COOKIE_SECURE = True # cookie hanya lewat HTTPS
SESSION_COOKIE_HTTPONLY = True # tidak bisa dibaca JavaScript
SESSION_COOKIE_SAMESITE = "Lax" # mitigasi CSRF tambahanTiga flag ini krusial: Secure (hanya HTTPS), HttpOnly (JS tidak bisa membaca — melawan XSS pencuri cookie), SameSite=Lax (browser tidak mengirim cookie pada request lintas-situs — menambah pertahanan CSRF).
Dengan Flask-Talisman (episode 17), force HTTPS bisa sekaligus:
talisman = Talisman(
app,
force_https=True,
strict_transport_security=True,
session_cookie_secure=True,
)HSTS (HTTP Strict Transport Security) memberi tahu browser: "jangan pernah konek ke domain ini lewat HTTP, selalu HTTPS." Ini mencegah serangan downgrade dan percobaan sniffing awal:
Strict-Transport-Security: max-age=63072000; includeSubDomainsmax-age=63072000 (2 tahun) dan includeSubDomains membuat semua subdomain juga wajib HTTPS. Talisman mengirim header ini otomatis saat strict_transport_security=True. Peringatan: karena browser mengingatnya, jangan aktifkan HSTS sebelum semua subdomain benar-benar mendukung HTTPS.
Warning
HSTS adalah pengaturan yang "diingat" browser dalam jangka panjang. Aktifkan hanya setelah yakin seluruh situs dan subdomain berjalan HTTPS — kalau tidak, browser akan menolak koneksi HTTP ke subdomain yang belum punya sertifikat, dan pengguna kalian terkunci.
Praktik standar: Nginx duduk di depan Flask, melakukan TLS, dan meneruskan request ke aplikasi. Strukturnya:
Nginx menangani yang berat (TLS, kompresi, static files, rate limit di level koneksi), Flask fokus pada logika aplikasi. Konfigurasi server block:
server {
listen 80;
server_name flask.example.com;
# semua HTTP diarahkan ke HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name flask.example.com;
ssl_certificate /etc/letsencrypt/live/flask.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/flask.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Bagian penting untuk Flask:
proxy_pass http://127.0.0.1:8000 — meneruskan ke Gunicorn yang berjalan di port 8000 (episode 22).X-Forwarded-Proto — memberi tahu Flask bahwa koneksi asli adalah HTTPS. Tanpa ini, url_for akan menghasilkan URL http:// yang salah.Karena request melewati proxy, Flask harus mempercayai header proxy. Aktifkan ProxyFix:
from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1)ProxyFix membaca X-Forwarded-For dan X-Forwarded-Proto sehingga Flask tahu IP asli client dan bahwa request berjalan HTTPS — krusial untuk url_for, rate limit per-IP (episode 15), dan session cookie Secure.
Setelah di-deploy, verifikasi:
curl -I https://flask.example.com
curl -sI http://flask.example.com | head -1 # harus 301Cek juga header keamanan:
HTTP/2 200
strict-transport-security: max-age=63072000; includeSubDomains
x-content-type-options: nosniff
content-security-policy: default-src 'self'
x-frame-options: DENYUntuk audit menyeluruh, tools seperti SSL Labs dan securityheaders.com membantu memeriksa skor header.
X-Forwarded-Proto: url_for menghasilkan http:// — redirect loop atau tautan rusak.ProxyFix: rate limit per-IP salah karena semua terlihat dari 127.0.0.1.Secure: cookie dikirim lewat HTTP — hilang saat redirect atau disadap.Pada episode 20 ini, kalian telah mengamankan transport aplikasi dari ujung ke ujung.
Inti yang harus dibawa pulang:
Secure + HttpOnly + SameSite=Lax.X-Forwarded-Proto) + ProxyFix agar Flask paham konteks HTTPS.return 301).Di episode 21 selanjutnya, kita memastikan semua yang dibangun bisa diuji: testing dengan pytest — Flask test client, fixtures, coverage, dan pola pengujian view serta API yang andal. Sampai jumpa di episode 21!