Belajar Flask - HTTPS & Deployment Security
Episode 20 of 27

Belajar Flask - HTTPS & Deployment Security

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.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

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.

Mengapa HTTPS Wajib

HTTPS (HTTP + TLS) mengenkripsi seluruh lalu lintas antara browser dan server. Tanpa itu:

  • Session cookie dan JWT bisa disadap (sniffing) lalu dipakai meniru user.
  • Password login dikirim sebagai teks terang — sekali disadap, akun terbobol.
  • Konten dimodifikasi di tengah jalan (man-in-the-middle) — halaman kalian bisa diganti.

Setiap aplikasi produksi, apa pun skalanya, wajib HTTPS — dan sertifikat kini gratis via Let's Encrypt.

Force HTTPS: Redirect Semua HTTP

Flask bisa memaksa HTTPS di level aplikasi, tetapi cara terbaik adalah di reverse proxy. Di aplikasi, pastikan konfigurasi tidak mengirim cookie ke koneksi HTTP:

PythonCookie flags di Flask
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 tambahan

Tiga 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:

PythonTalisman dengan force HTTPS
talisman = Talisman(
    app,
    force_https=True,
    strict_transport_security=True,
    session_cookie_secure=True,
)

HSTS: Mencegah Downgrade

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:

Header HSTS yang dikirim server
Strict-Transport-Security: max-age=63072000; includeSubDomains

max-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.

Terminasi TLS di Nginx

Praktik standar: Nginx duduk di depan Flask, melakukan TLS, dan meneruskan request ke aplikasi. Strukturnya:

100%

Nginx menangani yang berat (TLS, kompresi, static files, rate limit di level koneksi), Flask fokus pada logika aplikasi. Konfigurasi server block:

/etc/nginx/sites-available/flask-app.conf
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:

PythonProxyFix - percayai Nginx
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.

Menguji Konfigurasi HTTPS

Setelah di-deploy, verifikasi:

Verifikasi HTTPS dan header
curl -I https://flask.example.com
curl -sI http://flask.example.com | head -1    # harus 301

Cek juga header keamanan:

Header yang diharapkan
HTTP/2 200
strict-transport-security: max-age=63072000; includeSubDomains
x-content-type-options: nosniff
content-security-policy: default-src 'self'
x-frame-options: DENY

Untuk audit menyeluruh, tools seperti SSL Labs dan securityheaders.com membantu memeriksa skor header.

Common Pitfalls HTTPS & Deployment

  • HTTPS di Flask tanpa proxy: Flask sendiri bukan server TLS yang baik — biarkan Nginx/Caddy yang menangani.
  • Lupa X-Forwarded-Proto: url_for menghasilkan http:// — redirect loop atau tautan rusak.
  • Lupa ProxyFix: rate limit per-IP salah karena semua terlihat dari 127.0.0.1.
  • Cookie tanpa Secure: cookie dikirim lewat HTTP — hilang saat redirect atau disadap.
  • HSTS premature: subdomain belum HTTPS → pengguna terkunci.

Penutup

Pada episode 20 ini, kalian telah mengamankan transport aplikasi dari ujung ke ujung.

Inti yang harus dibawa pulang:

  • HTTPS wajib; terminasi TLS di Nginx, bukan di Flask.
  • Cookie flags: Secure + HttpOnly + SameSite=Lax.
  • HSTS (via Talisman) mencegah downgrade — aktifkan setelah semua subdomain siap.
  • Proxy headers (X-Forwarded-Proto) + ProxyFix agar Flask paham konteks HTTPS.
  • Redirect HTTP → HTTPS di level Nginx (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!

Belajar Flask - HTTPS & Deployment Security | Belajar Flask