Skip to content

Insecure transport and weak TLS

CWE-319OWASP A02:2021Updated August 31, 20266 min read

Insecure transport is the vulnerability where traffic crosses the network unencrypted or with outdated encryption, so anyone on the path can read and rewrite it. Plain HTTP, a missing HSTS header, TLS 1.0 or 1.1 and cookies without the Secure flag are the usual shapes it takes. The fix is HTTPS on every hostname, HSTS with preload, and TLS 1.2 and 1.3 only.

Installing a certificate takes minutes these days, and yet traffic still crosses the network in the clear: a forgotten subdomain on port 80, an API that keeps accepting HTTP, a cookie without the Secure flag. Insecure transport walks around your other controls rather than breaking through them.

What is insecure transport?

Insecure transport is the vulnerability where data travels between client and server unencrypted or with outdated encryption, allowing anyone on the network path to read and rewrite it. TLS, short for Transport Layer Security, is the protocol meant to protect that connection; HTTPS is nothing more than ordinary HTTP carried inside a TLS connection.

Think of postal mail. A request over plain HTTP is a postcard: everyone who handles it, from the Wi-Fi access point on the train to an intermediate provider, reads along and can pencil something in. HTTPS is the same text in a sealed envelope.

In practice it takes a handful of familiar shapes. Plain HTTP still listening alongside HTTPS. A missing HSTS header, leaving the browser to knock in cleartext on its first visit. Support for TLS 1.0 and TLS 1.1, protocols formally deprecated by RFC 8996. Weak cipher suites built on RC4 or 3DES, or suites without forward secrecy. Mixed content: an HTTPS page that fetches a script over HTTP. And cookies without the Secure flag, which the browser cheerfully sends over plain HTTP.

How does an attack on unencrypted traffic work?

The attacker needs a position on the network path: an access point in a cafe, a hijacked home router, an infected workstation on the office network. Take an application that listens on port 80 next to HTTPS and sets its session cookie without Secure.

Vulnerable:

const express = require("express");
const app = express();

app.post("/login", (req, res) => {
  const token = createSession(req.body.user);

  // No Secure flag: the browser sends this cookie over plain HTTP too
  res.cookie("session", token, { httpOnly: true });
  res.redirect("/dashboard");
});

// Also listening on port 80, and without HSTS that stays an open door
app.listen(80);

Your user types app.example.com into the address bar with no scheme, so the browser fills in http:// and sends that first request in the clear. The attacker intercepts it, talks to your server over HTTPS himself, and serves the user a plain HTTP copy of the site with every https:// link rewritten. The technique is called SSL stripping: everything the user types from then on passes the attacker in readable form.

Even without that interception, the cookie without a Secure flag is enough on its own: one request to an image or an old bookmark over HTTP will do, and this crosses the wire in cleartext:

GET /dashboard HTTP/1.1
Host: app.example.com
Cookie: session=eyJhbGciOiJIUzI1NiJ9.9f3c2ae1

Whoever captures that pastes the cookie into their own browser and is logged in as your user: no password, no second factor, no trace in your logs.

The fix combines three things: a permanent redirect, an HSTS header, and the Secure flag.

Secure:

const express = require("express");
const app = express();

const CANONICAL_HOST = "app.example.com";

app.use((req, res, next) => {
  // Behind a reverse proxy, this header shows what the client really used
  if (req.headers["x-forwarded-proto"] !== "https") {
    return res.redirect(308, "https://" + CANONICAL_HOST + req.originalUrl);
  }

  res.setHeader(
    "Strict-Transport-Security",
    "max-age=63072000; includeSubDomains; preload"
  );
  next();
});

app.post("/login", (req, res) => {
  const token = createSession(req.body.user);

  res.cookie("session", token, {
    httpOnly: true,
    secure: true,
    sameSite: "lax"
  });
  res.redirect("/dashboard");
});

The redirect uses a fixed hostname rather than the Host header, so a manipulated header cannot send visitors elsewhere. The HSTS header tells the browser, for two years: use HTTPS only for this hostname and its subdomains. From the second visit onwards http:// becomes https:// inside the browser, before a packet leaves; with preload the hostname also sits in a list shipped with the browser, covering the first visit too. TLS settings belong on the layer that terminates TLS, usually your reverse proxy: TLS 1.2 and 1.3 only, with forward-secrecy cipher suites.

Preload is a commitment, not a checkbox. Once your domain is on the list, every hostname beneath it must speak valid HTTPS, including that internal dashboard on port 80, and removal takes months because the list travels with browser releases. Start with a short max-age.

What is the impact of insecure transport?

Technically the immediate prize is session takeover, plus credentials, API keys and tokens in Authorization headers. Because the attacker writes as well as reads, they can also alter the response: inject a script, replace a download link. Insecure transport therefore neutralises controls that look sound on paper, since multi-factor authentication achieves little if the session cookie then travels in the clear.

In business terms it starts with the duty to protect personal data in transit; a breach along this route is reportable. PCI DSS requires strong cryptography over open networks, and browsers show a warning on plain HTTP that deters visitors.

The classification runs from medium to high, and that difference is real. A brochure page with no input fields over HTTP is bad for trust but not directly damaging; a login form, an API carrying bearer tokens, or an admin panel on the same channel certainly is. What limits the impact is that the attacker needs a position on the network path; what raises it again is how often users sit on networks nobody controls.

How do you detect insecure transport and weak TLS?

Start with the inventory: the flaw is rarely on the main website and almost always on what surrounds it, in staging, old subdomains, mail interfaces, a mobile app backend. Certificate Transparency logs give a fairly complete list of hostnames. For each one, request http:// explicitly and confirm you get a permanent redirect over HTTPS, not a page that simply works.

Then look at the response headers. If Strict-Transport-Security is absent, or its max-age is a few minutes, the policy exists on paper but not in practice. In developer tools, check the Secure, HttpOnly and SameSite flags on every cookie and watch the console for mixed content warnings. Probe the TLS configuration with standard tooling:

# Does the server still accept TLS 1.0?
openssl s_client -connect app.example.com:443 -tls1

# Full inventory of protocols, cipher suites and certificate
nmap --script ssl-enum-ciphers -p 443 app.example.com

Scanners handle weak protocol versions and expired certificates well. What they miss is the forgotten subdomain never in scope, the internal traffic between two services with no TLS, and the single endpoint that skips the redirect. AssistSec covers the whole transport layer in a penetration test, including hostnames that were not on the first list.

How do you prevent insecure transport?

  • Enforce HTTPS on every hostname. Answer port 80 with nothing but a permanent redirect to the same host over HTTPS, with no exception for health checks or legacy integrations.
  • Turn on HSTS and grow into preload. Start with a short max-age, verify all your subdomains, then raise it to a year or more with includeSubDomains before submitting.
  • Restrict yourself to TLS 1.2 and TLS 1.3. Disable SSL 3.0, TLS 1.0 and TLS 1.1 and pick cipher suites with forward secrecy and AEAD, preferably via Mozilla’s SSL Configuration Generator.
  • Mark every cookie as Secure. Combine it with HttpOnly and a suitable SameSite value, and use the __Host- prefix for session cookies where you can.
  • Clean up mixed content. Load scripts, stylesheets, images and fonts over HTTPS only; upgrade-insecure-requests is a temporary safety net at best.
  • Encrypt internal traffic too. Between load balancer and application, between services, and to the database; that network is not a trusted zone either.
  • Automate certificates and monitor expiry. Renew through ACME and include the TLS configuration in your recurring reviews.

Sources

Frequently asked questions

Is HTTPS enough, or do I also need HSTS?

HTTPS protects a connection that is already established over TLS, but not the very first request. Someone who types a domain name into the address bar without a scheme makes the browser send a plain HTTP request first, and an attacker on the network path can intercept it before your redirect ever reaches the user. HSTS tells the browser to switch to HTTPS on its own from then on, before a packet leaves the machine. Only preload protects that very first visit as well.

Should I disable TLS 1.0 and TLS 1.1?

Yes. Both protocols are formally deprecated by RFC 8996 and modern browsers no longer accept them; they rely on outdated hash functions and cipher constructions with practical attacks against them. TLS 1.2 with modern cipher suites and TLS 1.3 are sufficient. Check first which older clients or integrations still connect, so you do not lock anyone out without warning.

What is mixed content and why does it matter?

Mixed content is a page loaded over HTTPS that pulls in parts of itself over HTTP: a script, a stylesheet, an image. An active element such as a script arriving in cleartext can be swapped out in transit and then runs with the full privileges of your page. Browsers therefore block active mixed content by default and warn about passive mixed content.

Do I need HTTPS on an internal application?

Yes. The internal network is not a trusted zone: an infected workstation, an unattended network port or an attacker who is already inside can read that traffic just as easily. Session cookies and API tokens travel over internal links exactly as they do over external ones. Use an internal certificate authority or ACME with your own issuer when public certificates are not an option.

Related articles

Press / to search · Esc