Junior 3 min · March 06, 2026

Missing HTTP Redirect — 12% of Login Credentials Exposed

12% of login requests over HTTP due to missing redirect — session hijacking spikes.

N
Naren · Founder
Plain-English first. Then code. Then the interview question.
About
 ● Production Incident 🔎 Debug Guide
Quick Answer
  • 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.
Plain-English First

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.

io/thecodeforge/network/http_request_demo.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import socket

# io.thecodeforge: Manually craft an HTTP/1.1 request using a raw TCP socket.
# This is exactly what your browser does under the hood (minus all the modern complexity).

HOST = "example.com"
PORT = 80

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((HOST, PORT))

http_request = (
    "GET / HTTP/1.1\r\n"
    "Host: example.com\r\n"
    "Connection: close\r\n"
    "User-Agent: TheCodeForge-Debug/2026\r\n"
    "\r\n"
)

client_socket.sendall(http_request.encode("utf-8"))

response_parts = []
while True:
    chunk = client_socket.recv(4096)
    if not chunk:
        break
    response_parts.append(chunk)

client_socket.close()

full_response = b"".join(response_parts).decode("utf-8", errors="replace")
header_section, _, body_section = full_response.partition("\r\n\r\n")

print("=== HTTP RESPONSE HEADERS ===")
print(header_section)
print("\n=== FIRST 300 CHARS OF BODY ===")
print(body_section[:300])
Output
=== HTTP RESPONSE HEADERS ===
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 1256
Connection: close
=== FIRST 300 CHARS OF BODY ===
<!doctype html>
<html>
<head>
<title>Example Domain</title>
The HTTP Request Lifecycle
  • 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
Production Insight
HTTP plaintext means any network intermediary can read passwords, tokens, and API keys in transit. I've seen this bite teams on 'internal' tools that suddenly became reachable from coffee shops or via VPN leaks. Rule of thumb I give every team: never send credentials, tokens, or PII over HTTP — even on networks you control. The cost of enabling TLS is negligible compared to the incident you will eventually have.
Key Takeaway
HTTP is plaintext — every byte is readable by anyone on the network path. Every asset on a page is a separate request-response cycle on port 80. Never send sensitive data over it. The digital equivalent of sending your passwords on a postcard.
HTTP Request Method Selection
IfRetrieving data without side effects
UseUse GET — cacheable, idempotent, no request body
IfCreating a new resource
UseUse POST — not idempotent, request body contains the new data
IfReplacing an entire resource
UseUse PUT — idempotent, request body is the complete replacement
IfUpdating part of a resource
UseUse PATCH — request body contains only the fields to update
IfRemoving a resource
UseUse DELETE — idempotent, no request body typically

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.

io/thecodeforge/network/mitm_illustration.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# io.thecodeforge: Illustrates what an attacker sees with HTTP vs HTTPS
# This is conceptual — no actual packet sniffing.

import os

# === ATTACKER'S VIEW: Plain HTTP ===
http_login_visible = """
POST /login HTTP/1.1
Host: mybank.com
Content-Type: application/x-www-form-urlencoded

username=alice&password=SuperSecret123&token=abc123
"""

print("=== ATTACKER'S VIEW: Plain HTTP ===")
print("Intercepted request (fully readable):")
print(http_login_visible.strip())

print("\n" + "-" * 60)

# === ATTACKER'S VIEW: HTTPS (TLS encrypted) ===
print("=== ATTACKER'S VIEW: HTTPS (TLS encrypted) ===")
print("Intercepted bytes look like random garbage.")
print("They can see destination IP, port 443, and approximate data size.")
print("They cannot read credentials, tokens, or response bodies.")
Output
=== ATTACKER'S VIEW: Plain HTTP ===
Intercepted request (fully readable):
username=alice&password=SuperSecret123&token=abc123
------------------------------------------------------------
=== ATTACKER'S VIEW: HTTPS (TLS encrypted) ===
Intercepted bytes look like random garbage.
They can see destination IP, port 443, and approximate data size.
They cannot read credentials, tokens, or response bodies.
Watch Out — HTTPS Is Not a Magic Shield
HTTPS only protects data in transit. Once it reaches your servers, its job is done. If you store passwords in plaintext, have broken access control, or ship vulnerable frontend code, HTTPS won't save you. It secures the tunnel. The endpoints and your application logic are still your responsibility.
Production Insight
MITM attacks on HTTP are trivial on shared networks — airports, hotels, conferences, even some corporate guest WiFi. Session cookies sent over HTTP can be stolen and used to impersonate users without ever knowing their password. The rule I enforce on every project: set the Secure flag on all cookies and use __Host- prefix where possible. I've cleaned up too many incidents where this was missed.
Key Takeaway
HTTP has no privacy, no integrity, and no authentication — three fatal flaws for anything exposed to the public internet. MITM attacks are not theoretical. HTTPS via TLS solves all three problems with one protocol. Treat plain HTTP as legacy infrastructure in 2026.

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.

io/thecodeforge/network/https_connection_demo.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import ssl
import socket
import json

# io.thecodeforge: Manual HTTPS connection with proper TLS verification
# Demonstrates what browsers do automatically.

HOST = "httpbin.org"
PORT = 443

raw_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

tls_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
tls_context.check_hostname = True
tls_context.verify_mode = ssl.CERT_REQUIRED
# In production you'd also pin or check Certificate Transparency logs

secure_socket = tls_context.wrap_socket(raw_socket, server_hostname=HOST)
secure_socket.connect((HOST, PORT))

print("=== SERVER CERTIFICATE INFO ===")
print(f"Issued to:  {secure_socket.getpeercert().get('subject')}")
print(f"TLS version negotiated: {secure_socket.version()}")

# Send an HTTP request over the now-encrypted channel
http_request = (
    "GET /get HTTP/1.1\r\n"
    f"Host: {HOST}\r\n"
    "Connection: close\r\n"
    "User-Agent: TheCodeForge-Debug/2026\r\n"
    "\r\n"
)
secure_socket.sendall(http_request.encode("utf-8"))

response_chunks = []
while True:
    chunk = secure_socket.recv(4096)
    if not chunk:
        break
    response_chunks.append(chunk)

secure_socket.close()

full_response = b"".join(response_chunks).decode("utf-8", errors="replace")
header_section, _, body_section = full_response.partition("\r\n\r\n")

print("\n=== HTTP RESPONSE STATUS ===")
print(header_section.split("\r\n")[0])
Output
=== SERVER CERTIFICATE INFO ===
Issued to: ((('commonName', 'httpbin.org'),),)
TLS version negotiated: TLSv1.3
=== HTTP RESPONSE STATUS ===
HTTP/1.1 200 OK
The TLS Handshake in 4 Steps
  • 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
Production Insight
TLS 1.2 handshakes with 2 round trips added real latency on high-latency networks. TLS 1.3 is now the default everywhere that matters and cuts that overhead significantly. The gotcha that still bites teams is old load balancers or middleboxes that don't support TLS 1.3 or modern ciphers. Verify with openssl s_client -tls1_3 and monitor your TLS handshake success rate.
Key Takeaway
TLS gives you encryption, authentication via certificates, and integrity — exactly what plain HTTP lacked. The handshake is asymmetric to safely exchange a key; the actual data transfer is symmetric for performance. In 2026 you should be on TLS 1.3, HTTP/3 where possible, and treating port 443 as the only port that matters for public services.

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.

io/thecodeforge/network/http_methods_demo.pyPYTHON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import urllib.request
import urllib.error
import json

# io.thecodeforge: Demonstrating HTTP methods with httpbin.org

BASE_URL = "https://httpbin.org"

def make_request(method: str, path: str, payload: dict = None) -> None:
    url = f"{BASE_URL}{path}"
    body_bytes = json.dumps(payload).encode("utf-8") if payload else None

    request = urllib.request.Request(
        url,
        data=body_bytes,
        method=method,
        headers={
            "Content-Type": "application/json",
            "Accept": "application/json",
            "User-Agent": "TheCodeForge-Debug/2026"
        }
    )

    try:
        with urllib.request.urlopen(request) as response:
            status_code = response.status
            response_body = json.loads(response.read().decode("utf-8"))
            print(f"[{method}] {url} → {status_code}")
            if "json" in response_body:
                print(f"  Received: {response_body['json']}")
            else:
                ua = response_body.get('headers', {}).get('User-Agent')
                print(f"  User-Agent seen: {ua}")
    except urllib.error.HTTPError as error:
        print(f"[{method}] {url} → {error.code} {error.reason}")
    print()

make_request("GET", "/get")
make_request("POST", "/post", payload={"name": "Alice", "role": "staff-engineer"})
make_request("PUT", "/put", payload={"name": "Alice Chen", "role": "staff-engineer"})
make_request("DELETE", "/delete")
make_request("GET", "/status/404")
Output
[GET] https://httpbin.org/get → 200
User-Agent seen: TheCodeForge-Debug/2026
[POST] https://httpbin.org/post → 200
Received: {'name': 'Alice', 'role': 'staff-engineer'}
[PUT] https://httpbin.org/put → 200
Received: {'name': 'Alice Chen', 'role': 'staff-engineer'}
[DELETE] https://httpbin.org/delete → 200
[GET] https://httpbin.org/status/404 → 404 NOT FOUND
401 vs 403 Is a Classic Interview Trap
401 Unauthorized means 'I don't recognize you — please authenticate.' 403 Forbidden means 'I know exactly who you are, and you are not allowed to do this.' Using 401 when you should use 403 leaks whether an account exists. I've seen security auditors flag this exact pattern.
Production Insight
Misusing 401 vs 403 doesn't just confuse developers — it can leak information about valid usernames. Returning 500 for obvious client errors hides real server bugs in monitoring. Map your auth and authorization failures precisely. The status code is the first thing every client, monitoring system, and future developer will see.
Key Takeaway
Methods define intent. Status codes report outcome. Headers carry the metadata that makes the modern web work. 401 vs 403 is not interchangeable. Status code families are your first debugging signal. Get these right and everything downstream becomes easier.
HTTP Status Code Selection
IfRequest succeeded and returning data
UseUse 200 OK
IfResource created successfully
UseUse 201 Created with Location header
IfClient sent bad data or missing required fields
UseUse 400 Bad Request with error details in body
IfUser not authenticated (no token or invalid token)
UseUse 401 Unauthorized
IfUser authenticated but lacks permission
UseUse 403 Forbidden
IfServer crashed or unhandled exception
UseUse 500 Internal Server Error — log the stack trace, return generic message to client
● Production incidentPOST-MORTEMseverity: high

Missing HTTP-to-HTTPS Redirect Exposes Login Credentials on Public Wi-Fi

Symptom
Security audit found 12% of login requests arriving over HTTP. Session hijacking incidents spiked on public networks. Support tickets showed unauthorized purchases from unfamiliar devices and locations.
Assumption
The team assumed all traffic was HTTPS because the site displayed a valid certificate and the padlock in testing. They never realized that typing 'example.com' or clicking a plain link defaults to http:// in the browser.
Root cause
No HTTP-to-HTTPS redirect was configured at the edge. The load balancer and web servers listened on port 80 and happily served the full application. No Strict-Transport-Security header was present, so browsers had no memory of preferring HTTPS on future visits. Certificate Transparency logs were being monitored, but that doesn't help if the initial request never uses TLS.
Fix
Implemented a clean 301 redirect from HTTP to HTTPS on all routes at the load balancer level. Added Strict-Transport-Security header with max-age=31536000; includeSubDomains; preload. Submitted the domain to the HSTS preload list. Added monitoring for any HTTP traffic reaching the application servers.
Key lesson
  • 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.
Production debug guideSymptom-driven diagnosis for connection and protocol failures5 entries
Symptom · 01
NET::ERR_CERT_DATE_INVALID or similar expiry errors in browser
Fix
Certificate has expired or is about to. Use openssl s_client or the far more readable ssl-cert-check script to inspect. Renew with certbot renew --force-renewal and reload your services. In 2026 you should have short-lived certs (90 days or less) and automated renewal that alerts at least 7 days early.
Symptom · 02
Mixed content warnings after HTTPS migration
Fix
Some resources (images, scripts, iframes) are still loading via http://. Search your entire codebase and build output. Add Content-Security-Policy: upgrade-insecure-requests as a quick band-aid while you fix the references. Check your CDN configuration too — easy to miss.
Symptom · 03
CORS errors on API calls between HTTP and HTTPS origins
Fix
Browsers treat http://example.com and https://example.com as completely different origins. Standardize on HTTPS everywhere in development and production. The fix is almost always 'use the same protocol as the frontend'.
Symptom · 04
Secure cookies not sent on local development
Fix
Cookies with the Secure flag are ignored over plain HTTP. Stop using plain HTTP for localhost. Use mkcert to generate locally trusted certificates. Your dev environment should match prod behavior as closely as possible.
Symptom · 05
HTTP/2 or HTTP/3 not working despite server support
Fix
Both require HTTPS in all major browsers. Verify with curl --http2 or --http3. Check ALPN negotiation and make sure you're not accidentally falling back due to old cipher configuration or missing TLS 1.3 support.
★ HTTP/HTTPS Quick DebugImmediate actions when HTTP connections or TLS fail
Certificate expired or expiring soon
Immediate action
Check certificate expiry and renew immediately
Commands
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -enddate
certbot renew --force-renewal --dry-run
Fix now
Set cron: 0 3 * certbot renew --quiet && systemctl reload nginx || kill -HUP $(pgrep nginx)
HTTP-to-HTTPS redirect not working+
Immediate action
Test both protocols and verify redirect configuration
Commands
curl -sI http://yourdomain.com | head -5
curl -sI http://yourdomain.com | grep -i 'location\|strict-transport'
Fix now
Add to Nginx: return 301 https://$host$request_uri; (or equivalent at your CDN/load balancer)
Mixed content blocking page elements+
Immediate action
Find all insecure resource references in source and build output
Commands
grep -rn 'http://' . --include='*.html' --include='*.js' --include='*.css' --include='*.json' | grep -v 'https://'
curl -sI https://yourdomain.com | grep -i content-security-policy
Fix now
Replace http:// references with https:// or protocol-relative URLs. Add CSP header with upgrade-insecure-requests while you clean up.
HTTP vs HTTPS
Feature / AspectHTTPHTTPS
Full nameHyperText Transfer ProtocolHTTP Secure (HTTP over TLS)
Default port80443
Data in transitPlain text — readable by anyone on the networkEncrypted — unreadable without the session key
Server authenticationNone — you can't verify who you're talking toYes — via TLS certificate signed by a trusted CA and checked against Certificate Transparency logs
Data integrityNone — data can be modified in transit silentlyGuaranteed — tampering is detected and rejected
Browser indicatorNo padlock; prominent 'Not Secure' warning in 2026 browsersPadlock icon; URL shown as https://
SEO impactGoogle ranks HTTP sites lowerGoogle uses HTTPS as a positive ranking signal
PerformanceSlightly faster with no handshake (but stuck on HTTP/1.1 behavior)TLS 1.3 + HTTP/3 (QUIC) delivers excellent performance; required for modern features
Certificate costN/AFree via Let's Encrypt with automated renewal; paid options for extended validation or specific use cases
Use case todayInternal development, localhost, or air-gapped networks onlyEverything on the public internet — no exceptions in 2026

Key takeaways

1
HTTP is plain text. Every single byte of the conversation can be read by anyone on the network path. Never use it for sensitive data on the public internet in 2026.
2
HTTPS = HTTP + TLS. It simultaneously provides encryption, certificate-based authentication, and integrity. The padlock only proves the first two.
3
The TLS handshake uses asymmetric crypto to safely negotiate a session key, then switches to fast symmetric encryption. This hybrid model is why modern HTTPS has excellent performance, especially with HTTP/3.
4
Status codes, request method semantics, 401 vs 403, and proper HSTS configuration are daily tools, not trivia. The teams that get these details right have dramatically fewer production incidents.

Common mistakes to avoid

4 patterns
×

Using HTTP for localhost and assuming production HTTPS will behave the same

Symptom
Secure cookies don't get sent, mixed-content errors appear in production, CORS and credential behavior differ between dev and prod, leading to late surprises.
Fix
Use mkcert (or equivalent) to create locally trusted certificates. Your development environment should mirror production HTTPS behavior as closely as possible. This catches protocol-specific bugs early instead of in production.
×

Thinking the padlock means the website is safe or trustworthy

Symptom
Users (and sometimes engineers) treat the padlock as a seal of approval. Attackers obtain valid certificates for convincing fake domains with relative ease.
Fix
The padlock only means the connection is encrypted and the domain is authenticated. It does not vouch for the business, the code, or the people behind it. Train your users (and your team) to check the actual domain name first.
×

Not redirecting HTTP to HTTPS — leaving both protocols active

Symptom
Site works on both http:// and https://. Users who omit https:// or follow old links send credentials in plaintext. HSTS is missing so browsers don't remember to upgrade.
Fix
Add a 301 redirect from HTTP to HTTPS at the edge. Send Strict-Transport-Security with a long max-age on every response. Test relentlessly with curl. Submit to the HSTS preload list once stable.
×

Serving mixed content — loading some resources over HTTP on an HTTPS page

Symptom
Padlock disappears or shows warnings. Console flooded with mixed content errors. Active content (scripts, iframes) may be blocked entirely by default in modern browsers.
Fix
Hunt down every http:// reference in your codebase, build pipeline, and third-party integrations. Use CSP upgrade-insecure-requests as a safety net while you fix root causes. This mistake still ships surprisingly often.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
Can you walk me through exactly what happens when a user types 'https://...
Q02SENIOR
What's the difference between symmetric and asymmetric encryption, and w...
Q03JUNIOR
If a site is served over HTTPS, does that mean it's secure? What are the...
Q04SENIOR
What is HSTS (HTTP Strict Transport Security), and why is it critical fo...
Q05JUNIOR
What happens if a browser encounters a certificate where the Common Name...
Q01 of 05SENIOR

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?

ANSWER
DNS resolution first — the browser asks for the IP of google.com. Then a TCP connection on port 443, followed by the TLS 1.3 handshake: ClientHello, ServerHello + certificate chain, key exchange via ECDHE, derivation of session keys. The certificate is validated against trusted CAs and Certificate Transparency logs. Once the encrypted channel is up, the browser sends an HTTP/3 or HTTP/2 GET request. The server responds with 200 and the HTML. The browser begins parsing, discovers subresources, and repeats the process (often with session resumption for speed). Each step has failure modes I've debugged in production — DNS hijacking, certificate validation failures, handshake timeouts, and mixed content on subresources.
FAQ · 4 QUESTIONS

Frequently Asked Questions

01
Does HTTPS make my website completely secure?
02
Is HTTP ever acceptable to use in 2026?
03
Why does the browser show a padlock — what has it actually verified?
04
What is the difference between HTTP/1.1, HTTP/2, and HTTP/3?
🔥

That's Computer Networks. Mark it forged?

3 min read · try the examples if you haven't

Previous
TCP vs UDP
5 / 22 · Computer Networks
Next
HTTP/2 and HTTP/3