HTTP vs HTTPS: why browsers say 'not secure'

HTTPS is HTTP carried inside an encrypted TLS connection, while plain HTTP travels as readable text. Browsers say 'not secure' because any network on the path can read or change an HTTP page.

Updated 6 min read

Learning objectives

After reading this article you will be able to:

  • Understand what actually changes between HTTP and HTTPS
  • Find out why browsers show 'not secure' and how to fix it
  • Migrate to HTTPS with redirects, HSTS and no mixed content
On this page

You type a site's address and the browser shows "Not secure" next to it. Most of the time the cause is simple: the site was opened over http:// instead of https://. It is one letter in the address, but it changes who can read what travels between you and the server.

Browsers have grown more insistent about that warning, and an HTTP-only site loses visitors. Moving a site or API to HTTPS without breaking links, cookies or images takes four steps, covered below.

HTTPplain textBrowserNot secureServerPublic Wi-Fianyone on the network sees:GET /loginCookie: session=7f3a9cuser=ana&password=1234HTTPSHTTP inside a TLS connectionBrowserpadlockServerPublic Wi-Fianyone on the network sees:server: example.com17 03 03 a7 f3 9c 0e 514b d2 88 1e c6 5a …
With HTTP, any network on the way can read and change everything; with HTTPS, it sees the destination, not the content.

What is the difference between HTTP and HTTPS?#

HTTP is the protocol that defines how a browser and a server exchange requests and responses. It encrypts nothing: the URL, headers, cookies and response body all travel as readable text. HTTPS is the same HTTP, wrapped in a connection protected by TLS. The application still speaks HTTP; TLS handles encryption, tamper detection and proving the server's identity.

HTTP HTTPS
Default port 80 443
Data in transit Readable text Encrypted
Tampering on the path Goes unnoticed Detected
Server identity Not verified Verified by certificate
Certificate Not used Required
HTTP/2 and HTTP/3 in browsers No Yes
Browser warning "Not secure" Padlock, no warning

Browsers only use HTTP/2 and HTTP/3 over TLS. In practice HTTPS is usually as fast as HTTP, and often faster.

Why do browsers say "not secure"?#

Because on an HTTP connection any device on the path can see and change the page: the coffee shop Wi-Fi, a hotel router, the internet provider. That makes it possible to steal a session cookie, swap a download link or inject ads and scripts into your page without you knowing.

In October 2025, Google announced that Chrome 154 would turn on "Always Use Secure Connections" by default for public sites. With the setting on, Chrome asks the user for permission before the first visit to a public site without HTTPS. The warning does not repeat for sites the person visits regularly, and private addresses (local IPs and intranet hostnames) are excluded. Users can still turn the setting off. In practice, an HTTP-only site scares off new visitors before the page even loads.

What does HTTPS protect, and what does it not?#

It protects three things in transit:

  • Confidentiality: anyone intercepting the traffic sees meaningless bytes, including the URL path and headers.
  • Integrity: any change along the way is detected.
  • Authentication: the certificate confirms you are talking to the server for that domain.

It does not protect what happens outside the connection. HTTPS does not fix SQL injection, weak passwords or a compromised server, and the padlock does not prove a site is honest: a scam site can have a valid certificate too. The domain name and destination IP usually remain visible to anyone watching the network.

How do you migrate a site from HTTP to HTTPS?#

Migration takes four steps, in this order.

  1. Get a valid certificate for the domain. Authorities such as Let's Encrypt issue DV certificates at no cost, and renewal is automatic on most platforms.
  2. Redirect all HTTP to HTTPS with a permanent redirect (301 or 308).
  3. Enable HSTS once you have confirmed HTTPS works.
  4. Fix mixed content, covered in a later section.

An example in Node.js with Express 5, behind a proxy that terminates TLS (the most common case on hosting):

js
import express from "express";

const app = express();
const HOST = process.env.PUBLIC_HOST ?? "example.com"; // your canonical domain

// Trust the first proxy so X-Forwarded-Proto is honored
app.set("trust proxy", 1);

app.use((req, res, next) => {
  if (!req.secure) {
    // Fixed host: never build the redirect from a header the client controls
    return res.redirect(308, `https://${HOST}${req.originalUrl}`);
  }
  // 1 year; only sent on HTTPS responses
  res.set("Strict-Transport-Security", "max-age=31536000");
  next();
});

app.get("/", (req, res) => res.send("Hello over HTTPS"));

app.listen(process.env.PORT || 3000);

Without trust proxy, the app sees the proxy's local connection (plain HTTP) and req.secure is always false, which causes a redirect loop. The reason is explained in reverse proxy. The redirect uses a fixed domain because, with trust proxy on, req.hostname comes from the X-Forwarded-Host header, and building the URL from it could send visitors to another site.

Check the result with curl:

bash
curl -sI http://example.com | head -n 3
curl -sI https://example.com | grep -i strict-transport-security

The first command should show a redirect to https://, and the second should show the HSTS header.

What is HSTS and when should you enable it?#

HSTS (HTTP Strict Transport Security) is a header that tells the browser: "this host must only be accessed over HTTPS". After receiving it, the browser automatically rewrites any http:// to https:// for the max-age period, in seconds, and the user cannot click through certificate errors. This closes the gap of the very first HTTP request, which a redirect alone leaves open.

http
Strict-Transport-Security: max-age=31536000; includeSubDomains

Browsers ignore the header on HTTP responses, so it only counts when sent over HTTPS. To get on the browsers' preload list, the domain needs a max-age of at least 31536000 (1 year), includeSubDomains and preload, and you submit it at hstspreload.org.

Be careful: includeSubDomains requires every subdomain to have working HTTPS. Start with a short max-age (for example 300) and raise it gradually. Leaving the preload list later is slow, because it depends on new browser releases.

What is mixed content and how do you fix it?#

Mixed content happens when a page loaded over HTTPS requests resources over http://. It is the most common reason a site with a valid certificate still looks broken.

Browsers treat two groups differently. Images, video and audio are automatically upgraded to HTTPS. Everything else, such as scripts, stylesheets, iframes, fetch() and fonts, is blocked. If the resource's host is an IP address instead of a domain name, even images are blocked.

To fix it:

  • Change http:// to https:// in your templates, or use relative URLs for your own resources.
  • Update URLs stored in the database (blog content, image fields).
  • Confirm the external resource exists over HTTPS: changing only the scheme does not help if the target server does not answer over TLS.
  • As a safety net, the Content-Security-Policy: upgrade-insecure-requests header asks the browser to rewrite every request to HTTPS.

The browser console (Console tab in developer tools) lists each blocked or upgraded resource. If the warning persists with no mixed content, the problem may be the certificate: see SSL certificate errors.

When is plain HTTP still acceptable?#

In local development (http://localhost) and on private internal networks, HTTP is common, and Chrome does not apply the warning to private addresses. For anything reachable from the public internet, HTTPS is the default, including APIs, webhooks and dashboards: bot webhooks, for example, often require an HTTPS URL.

How to do this on Square Cloud#

Every web application on Square Cloud gets a *.squareweb.app subdomain with HTTPS on all plans. TLS is automatic: a DV certificate is issued and renewed on its own, so you never generate or renew certificates.

To use your own domain (available starting with the Standard plan), you create the DNS records the dashboard shows at your registrar and follow the validation status in real time. TLS is provisioned automatically, and the domain stays registered in your name at your registrar.

The network includes an Anycast CDN, HTTP/3 and a WAF, and redirects HTTP to HTTPS. Your application's headers, such as HSTS, pass through intact and stay under your control in code. See the walkthrough in custom domains, how the network behaves in network and CDN and, for several apps on one domain, load balancing.

Network

Custom domains, automatic TLS and a global CDN for your app

Learn more

FAQs

Does HTTPS make a website slower?

Not noticeably. The TLS 1.3 handshake costs one network round trip, and browsers only use HTTP/2 and HTTP/3 over HTTPS, which usually offsets the cost.

Do I need HTTPS if my site has no login or forms?

Yes. Without HTTPS, any network on the path can alter the page, inject ads or code, and the browser may warn visitors before opening the site.

Does the padlock mean a site is safe?

No. It means the connection is encrypted and the certificate is valid for that domain. A malicious site can have HTTPS too.

Why does my HTTPS site still say 'not secure'?

The most common cause is mixed content: the page loads scripts, styles or other resources over http://. Other causes are an expired certificate or one issued for a different domain.

Do HTTP and HTTPS use different ports?

Yes. By default HTTP uses port 80 and HTTPS uses port 443.

Next articleDoes a small website need a CDN?A small site usually benefits from a CDN, but the gain depends on where your visitors are and what the site serves. See the criteria and when to skip one.

More in Networking and domains

See all 27 articles