Missing HTTP Redirect — 12% of Login Credentials Exposed
12% of login requests over HTTP due to missing redirect — session hijacking spikes.
20+ years shipping production systems from the metal up. Notes here come from systems that actually shipped.
- ✓Basic programming fundamentals
- ✓A computer with internet access
- ✓Willingness to follow along with examples
- HTTP is plaintext on port 80. Anyone on the path — coffee shop WiFi, ISP, corporate proxy, or nation-state — can read your users' passwords, tokens, and credit cards in cleartext.
- HTTPS is HTTP inside TLS. It gives you encryption, server authentication, and integrity checks in one package.
- The TLS handshake uses asymmetric crypto (public/private keys, usually ECDHE) to safely negotiate a session key, then flips to fast symmetric encryption — AES-GCM or ChaCha20 in practice.
- Port 443 is default for HTTPS. Modern browsers shame HTTP pages with big "Not Secure" warnings, Google continues to downgrade them in search, and features like Service Workers, geolocation, camera access, and Private Access Tokens simply refuse to work on insecure contexts.
- HTTP/2 and especially HTTP/3 (over QUIC) are HTTPS-only in practice. If you're not on TLS, you're stuck with 20-year-old performance characteristics and head-of-line blocking.
- The biggest production foot-gun: the padlock only means the pipe is encrypted and the certificate validated for that domain. It says nothing about whether the site is legitimate, the backend is secure, or the code isn't leaking data.
Picture sliding a note across the table in a busy café. With HTTP, it's written in plain ink — the waiter, the person at the next table, or anyone who snatches it mid-air can read your PIN, your secrets, everything. HTTPS is the same note, but now it's in a locked briefcase that only you and your friend have the key for. The briefcase still travels the same route through the café. The path hasn't changed. But the contents are now private, can't be altered without detection, and you have high confidence it's actually going to your friend, not an impostor pretending to be them. That's the entire game.
Every single time a user opens your site or calls your API, their browser and your server are having a very specific conversation using HTTP or HTTPS. Get this wrong and passwords leak, sessions get hijacked, Google buries you in search, and half your fancy new browser features stop working.
HTTP dates back to 1991. Tim Berners-Lee designed it for simplicity and speed when the web was mostly academic pages. Privacy wasn't even on the radar. Everything travels in plain text. Passwords, session cookies, API keys, credit card details — all completely readable by anyone with a packet sniffer on the same network path.
HTTPS is simply HTTP sent over TLS. The TLS layer adds the three things the original protocol never had: confidentiality through encryption, authentication through certificates, and integrity so tampering is detectable.
By April 2026 this isn't optional theater. Chrome, Firefox, and Safari actively mark HTTP pages as 'Not Secure' with increasingly aggressive UI. Google has been using HTTPS as a ranking signal for years and only gets stricter. Features like geolocation, camera access, service workers, and the newer Private Access Tokens flat-out refuse to work on insecure origins. The real failures I've seen in production aren't usually dramatic MITM attacks — they're the subtle ones: certificates expiring at 3am on a Friday, mixed content quietly breaking payment flows after a frontend change, missing HSTS headers allowing downgrade attacks on public networks, or developers testing exclusively on plain HTTP localhost and getting surprised when prod behaves differently.
Most teams treat HTTPS as a checkbox. The engineers who ship reliably are the ones who understand the handshake, certificate validation chains, Certificate Transparency logs, and the exact guarantees (and limitations) TLS actually provides.
What HTTP Is and How a Browser Actually Fetches a Page
HTTP stands for HyperText Transfer Protocol — the agreed-upon set of rules browsers and web servers follow when talking to each other. When you type a URL and hit Enter, the browser does a DNS lookup, opens a TCP connection on port 80, sends a structured text request, and receives a structured text response containing HTML (and eventually CSS, JS, images, etc.).
A typical modern page still triggers dozens of these request-response cycles. Every asset is its own conversation. The critical reality in 2026 is that all of this is still plain text when using HTTP. Anyone on the network path can read it with trivial tools. This is why HTTP-only sites belong only in controlled internal environments or local development.
- DNS resolves the domain to an IP address — the phone book of the internet
- TCP connection on port 80 is the 'phone line' between browser and server
- The request is structured text: request line, headers, blank line, optional body
- The response is also structured text: status line, headers, blank line, body (HTML/CSS/JS)
- Every asset (image, script, CSS, font) triggers its own request-response cycle
Why HTTP Alone Is Dangerous — The Man in the Middle
A Man-in-the-Middle (MITM) attack happens when an attacker inserts themselves between you and the server and can read or modify everything. On plain HTTP this is trivial. Tools like Wireshark, tcpdump, or bettercap make it almost boring. The attacker doesn't need to break any cryptography because there is none.
HTTP has three fatal weaknesses on the public internet: no privacy (everything readable), no integrity (data can be changed silently), and no authentication (you have no proof you're talking to the real server). HTTPS, via TLS, solves all three at once.
How HTTPS Works — TLS, Certificates, and the Handshake Explained
HTTPS is not 'HTTP with encryption bolted on.' It is HTTP transported over TLS (Transport Layer Security). TLS delivers the three properties HTTP lacked: privacy (encryption), authentication (certificates), and integrity (message authentication codes).
The TLS handshake lets the client and server agree on a shared session key using asymmetric cryptography without ever sending the key itself. Once established, they switch to fast symmetric encryption for the actual HTTP traffic. The server proves its identity with a certificate signed by a trusted Certificate Authority. In 2026, that certificate is almost always from Let's Encrypt, and browsers expect TLS 1.3 with modern cipher suites.
- Client sends ClientHello with supported versions, cipher suites, and key share
- Server replies with ServerHello, its certificate chain, and its own key share
- Both sides independently compute the same session key (usually via ECDHE)
- All subsequent data — including the HTTP request — is encrypted with symmetric AES (or ChaCha20) using that key
- TLS 1.3 does this in 1 round-trip in most cases. 0-RTT is possible but has tradeoffs
HTTP Status Codes, Request Methods, and Headers You'll Use Daily
Every HTTP conversation consists of a request and a response, both with strict formatting. Methods describe intent. Status codes tell you what happened. Headers carry metadata that makes the whole system work — caching, authentication, content negotiation, security policies.
GET should be safe and idempotent. POST is the workhorse for mutations. PUT and DELETE are idempotent. PATCH is for partial updates. Knowing the difference isn't academic — it affects caching, retry logic, and whether your API is pleasant to use. Status code families (2xx success, 3xx redirection, 4xx client error, 5xx server error) are the first signal when something breaks.
HTTP/2 and HTTP/3 — Why Your API Calls Are Faster (and Why They Break Differently)
HTTP/1.1 handles one request per TCP connection. That means head-of-line blocking: one slow asset stalls everything after it. HTTP/2 fixed this with multiplexing — multiple streams over a single connection. No more queueing for CSS while your JSON response sits idle. But TCP itself still has a problem: if a packet drops, all streams pause while TCP retransmits. HTTP/3 throws TCP away entirely. It runs over QUIC on top of UDP. Connections establish in one round trip, not three. Packet loss only affects a single stream, not the whole session. You see this in production when mobile clients lose signal briefly — HTTP/3 resumes without renegotiation. The cost: middleboxes like firewalls and load balancers often block or degrade QUIC traffic. You'll need to test your infrastructure before enabling it. For now, start with HTTP/2 on your CDN and API gateways. It's backward-compatible and gives you most of the speed gain with none of the protocol drama.
HTTP Caching — Why Your "Fresh" Data Is Actually Stale and Your Server Is About to Melt
Caching is not an optimization — it's an SLA requirement. Every uncached request hits your database, your compute, or someone else's API. The right HTTP cache headers tell browsers and proxies how long to hold a response before asking again. You control this with Cache-Control: max-age=3600 says "use this response for one hour." The gotcha: cache invalidation is hard. If you set max-age too high, users see stale data. Too low, your server takes the hit anyway. Use ETag headers for validation: the client sends the ETag with an If-None-Match conditional request. If the resource hasn't changed, your server returns 304 Not Modified with zero body. That's a round-trip saved. Never cache user-specific responses with a public directive — that leaks data across tenants. Use private, max-age=0 for authenticated endpoints. For static assets (JS, CSS, images), set max-age to one year and version the URL. If you change the file, change the URL. That breaks the cache cleanly without any invalidation headaches.
TLS 1.3 Handshake: What Changed
TLS 1.3, standardized in 2018, revolutionized the handshake process by reducing latency and improving security. Unlike TLS 1.2, which required two round trips (2-RTT) for a full handshake, TLS 1.3 achieves a 1-RTT handshake in most cases, and even 0-RTT for returning clients. This is accomplished by eliminating obsolete cryptographic algorithms and simplifying the handshake flow.
In TLS 1.2, the handshake involved: ClientHello → ServerHello + Certificate + ServerHelloDone → ClientKeyExchange + ChangeCipherSpec + Finished → Server ChangeCipherSpec + Finished. TLS 1.3 combines key exchange and authentication into a single round trip. The client sends its supported key shares (e.g., from Diffie-Hellman parameters) in the initial ClientHello. The server responds with its chosen key share, certificate, and a Finished message, all in one go. This cuts the handshake time in half.
For returning clients, TLS 1.3 supports 0-RTT (early data). The client can send application data immediately after the ClientHello, using a pre-shared key (PSK) from a previous session. However, 0-RTT is vulnerable to replay attacks, so it should only be used for idempotent requests (e.g., GET, but not POST).
Practical example: When a user revisits a website, TLS 1.3 can resume the session with 0-RTT, making page loads feel instant. For APIs, this reduces latency significantly, especially for mobile clients with high latency networks.
Security improvements include removal of weak ciphers (e.g., RC4, 3DES, static RSA) and mandatory forward secrecy via ephemeral Diffie-Hellman. The handshake is also encrypted earlier, hiding the server certificate from eavesdroppers.
HTTP/3 and QUIC: The Modern Web Protocol
HTTP/3 is the latest version of HTTP, built on top of QUIC (Quick UDP Internet Connections) instead of TCP. QUIC is a transport protocol developed by Google, standardized as RFC 9000 in 2021. It uses UDP and integrates TLS 1.3 natively, providing encryption by default.
- Reduced connection establishment: QUIC combines the cryptographic and transport handshakes into a single 1-RTT (or 0-RTT with a cached connection). HTTP/2 over TCP requires a TCP handshake (1-RTT) followed by TLS 1.3 (1-RTT), totaling 2-RTT.
- No head-of-line blocking: HTTP/2 multiplexes streams over a single TCP connection, but a lost packet blocks all streams (TCP head-of-line blocking). QUIC runs over UDP and handles packet loss independently per stream, so a lost packet only affects that stream.
- Connection migration: QUIC connections are identified by a Connection ID, not by IP/port. This allows seamless migration across network changes (e.g., switching from Wi-Fi to cellular) without reconnection.
Practical example: A video streaming service using HTTP/3 can deliver multiple video segments in parallel without one lost packet stalling the entire video. Mobile users switching networks experience no interruption.
HTTP/3 is supported by major browsers (Chrome, Firefox, Safari, Edge) and servers (nginx, LiteSpeed, Cloudflare). However, some corporate firewalls block UDP, so fallback to HTTP/2 is necessary.
Implementation: Use a library like aioquic (Python) or nginx with the quiche module. Clients can use cURL with --http3 flag.
Certificate Transparency and ACME Protocol
Certificate Transparency (CT) is a framework for publicly logging TLS certificates, enabling anyone to audit Certificate Authorities (CAs). It helps detect misissued or fraudulent certificates. When a CA issues a certificate, it must submit it to multiple public logs. Browsers require certificates to have Signed Certificate Timestamps (SCTs) from these logs to be trusted.
How CT works: The CA sends the certificate to a log server, which returns an SCT (a promise to include the certificate in the log within a Maximum Merge Delay, typically 24 hours). The SCT is embedded in the certificate (via an X.509v3 extension) or delivered via TLS handshake (OCSP stapling). Browsers verify SCTs during TLS handshake; if missing, the connection may be rejected.
ACME (Automatic Certificate Management Environment) protocol automates certificate issuance and renewal, most famously used by Let's Encrypt. ACME allows a server to prove domain control via HTTP challenge (placing a token at a well-known URL) or DNS challenge (adding a TXT record). Once validated, the CA issues a certificate.
Practical example: Using Certbot (ACME client) to obtain a Let's Encrypt certificate: ``bash sudo certbot --nginx -d example.com -d www.example.com `` This automates the entire process: domain validation, certificate issuance, and nginx configuration.
ACME v2 supports wildcard certificates via DNS challenge. Combined with CT, it ensures certificates are publicly logged and automatically renewed before expiry.
Production insight: Set up automated renewal with a cron job or systemd timer. Monitor CT logs for unexpected certificates for your domains using tools like crt.sh.
Missing HTTP-to-HTTPS Redirect Exposes Login Credentials on Public Wi-Fi
- Always redirect HTTP to HTTPS at the earliest possible point — never serve real application content on both protocols simultaneously. The redirect itself should be the only thing that ever lives on port 80.
- HSTS is your memory enforcement layer. Set it with a long max-age on every response (not just the homepage), includeSubDomains, and eventually preload. I've seen teams get burned by setting it only on the root path.
- Test your setup the way real users and attackers do: curl -I http://yoursite.com should return 301 with a Location header pointing to HTTPS. If you see 200, you're still exposed.
- HSTS preload protects first-time visitors and removes the initial HTTP window entirely. Submit to the preload list once you're confident in your redirect strategy — it is not easily reversible.
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -enddatecertbot renew --force-renewal --dry-run| File | Command / Code | Purpose |
|---|---|---|
| io | HOST = "example.com" | What HTTP Is and How a Browser Actually Fetches a Page |
| io | http_login_visible = """ | Why HTTP Alone Is Dangerous |
| io | HOST = "httpbin.org" | How HTTPS Works |
| io | BASE_URL = "https://httpbin.org" | HTTP Status Codes, Request Methods, and Headers You'll Use D |
| Http2Check.java | public class Http2Check { | HTTP/2 and HTTP/3 |
| CacheHeaders.java | @RestController | HTTP Caching |
| tls13_handshake.py | context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) | TLS 1.3 Handshake |
| http3_request.py | async def fetch_http3(url): | HTTP/3 and QUIC |
| acme_certbot.sh | sudo apt update && sudo apt install certbot python3-certbot-nginx | Certificate Transparency and ACME Protocol |
Key takeaways
Interview Questions on This Topic
Can you walk me through exactly what happens when a user types 'https://google.com' in their browser and presses Enter — from DNS lookup through to the page rendering?
Frequently Asked Questions
20+ years shipping production systems from the metal up. Notes here come from systems that actually shipped.
That's Computer Networks. Mark it forged?
6 min read · try the examples if you haven't