HTTPS & TLS
Also Known As
TL;DR
Explanation
HTTPS is HTTP transmitted over a TLS (Transport Layer Security) connection. TLS provides: confidentiality (data encrypted in transit — only client and server can read it); integrity (tampering is detected via MAC); authentication (the server's identity is verified via its TLS certificate signed by a trusted Certificate Authority). A TLS certificate contains the domain name, issuer, validity period, and the server's public key. Let's Encrypt provides free, automatically-renewing certificates via the ACME protocol (Certbot, acme.sh). Modern TLS configuration: TLS 1.2+ (1.0 and 1.1 deprecated); strong cipher suites; HSTS header (tells browsers to always use HTTPS); HSTS preloading (browsers ship with a list of HTTPS-only domains). In PHP, all cookies should have the Secure flag (HTTPS-only); sessions should set session.cookie_secure = true; API tokens and credentials must only be transmitted over HTTPS.
Common Misconception
Why It Matters
Common Mistakes
- Not setting the Secure flag on cookies — PHP session cookies and authentication cookies must have Secure=true to prevent transmission over HTTP.
- Not configuring HSTS — without it, browsers may make the first request over HTTP before being redirected; HSTS eliminates this window.
- Using self-signed certificates in production — self-signed certs cause browser warnings and are rejected by API clients; use Let's Encrypt.
- Not renewing certificates — Let's Encrypt certificates expire after 90 days; automate renewal with certbot renew in a cron job.
Code Examples
// Cookie without Secure flag — sent over HTTP
setcookie('session', $sessionId, [
'httponly' => true,
// 'secure' => true -- missing! sent over HTTP too
]);
// No HSTS — first request vulnerable
// header('Strict-Transport-Security: ...'); -- missing
// All security flags on session cookie
setcookie('session', $sessionId, [
'expires' => time() + 3600,
'path' => '/',
'secure' => true, // HTTPS only
'httponly' => true, // no JS access
'samesite' => 'Lax', // CSRF protection
]);
// HSTS header — browsers remember HTTPS-only for 1 year
header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload');
// Redirect HTTP to HTTPS in nginx:
// server { listen 80; return 301 https://$host$request_uri; }