TLS certificates and HTTPS redirects: keep certificates valid and users on HTTPS
Expired certificates and missing HTTPS redirects expose users and train them to ignore warnings. How to check and fix both.
Typical severity: High · Checked by NovaPentest module: SSL/TLS
What it is
A TLS certificate lets a browser confirm that it is talking to your server and not an impostor, and it anchors the encryption that protects everything exchanged over HTTPS. A certificate is issued by a certificate authority that browsers trust, lists the domain names it covers, and is valid for a limited period that the industry has been steadily shortening.
When the certificate is valid, the connection shows no warning and the user never thinks about it. When it has expired, is self-signed, or names a different domain, the browser stops and shows a full-page security warning before the site loads.
The second half of this topic is the redirect from HTTP to HTTPS. Having a certificate does not by itself move users onto HTTPS. People type bare domain names and follow old links and bookmarks, and many of those start with http://. The server has to answer those requests with a permanent redirect to the HTTPS address, and HSTS then keeps the browser on HTTPS for later visits.
Together, a trusted, current certificate and an enforced redirect mean every visitor ends up on an encrypted connection to the real site without any action on their part. Both are operational controls rather than code: they fail because a renewal job stopped running, a new subdomain went live without a certificate, or a server was rebuilt without the redirect rule.
How it is exploited
An expired certificate breaks the site for everyone at once. Browsers show a full-page warning, API clients and mobile apps refuse to connect, and webhooks from payment or email providers start failing. The less obvious cost is behavioral: users who are shown certificate warnings on a site they trust learn to click past them, and a user who has learned that habit will also click past the warning on the day someone on their network is actually impersonating the site.
A self-signed certificate produces the same warning on every visit, with the same effect on user habits, and gives the browser no way to tell your server apart from anyone else's.
A site that does not redirect HTTP to HTTPS leaves the first request of many visits unencrypted. On public Wi-Fi, or any network someone else controls, that request can be answered by the network operator instead of your server, keeping the user on a plain HTTP version of the site where logins, form data and cookies without the Secure flag travel in clear text. The user sees your site's content and has no reason to look for the padlock.
None of this requires a flaw in your application. The failures are in configuration and upkeep, which is why they often appear suddenly on a site that has worked fine for months.
How to detect it
NovaPentest's SSL/TLS module behaves differently depending on the target URL. For an https:// target it completes a TLS connection, reads the certificate the server presents, and reports an expired certificate as Critical, expiry in less than 7 days as Critical, expiry in less than 30 days as High, and a certificate whose issuer equals its subject (self-signed) as High. For an http:// target it requests the URL without following redirects and reports High if the response lacks a Location header pointing to an https:// address. It runs in the free passive scanner at novapentest.com/scan.
The limits are worth knowing. The module accepts any certificate in order to read it, so it does not report a hostname mismatch, an incomplete or untrusted chain, or a certificate from an unknown authority unless it is self-signed. It does not test protocol versions or cipher suites. And because the redirect check runs only for http:// targets, while the free scanner picks HTTPS whenever the site answers on it, a missing redirect will usually not be reported there. The redirect check also accepts a first-hop redirect to any HTTPS URL without checking the host.
To verify by hand, inspect the certificate with openssl s_client -connect example.com:443 -servername example.com </dev/null | openssl x509 -noout -subject -issuer -dates and read the notAfter date. Check the redirect with curl -sI http://example.com: the answer should be 301 or 308 with Location: https://example.com/. Repeat for the www variant and every other hostname you serve.
How to fix it
1. Automate renewal. Use an ACME client such as certbot or acme.sh, or the built-in automation of Caddy, your cloud load balancer or your Kubernetes ingress (cert-manager). Confirm the scheduled renewal works with a dry run, for example certbot renew --dry-run.
2. Make sure the renewed certificate is actually served. Many outages happen because the file was renewed but the web server was never reloaded. Add a hook such as certbot renew --deploy-hook "systemctl reload nginx".
3. Monitor expiry independently of the renewal job, and alert at 30 days and again at 14. If renewal is broken, the monitor is the only thing that will tell you.
4. Replace self-signed certificates on anything public with one from a trusted authority. Let's Encrypt certificates are free.
5. Serve the full chain. In nginx, ssl_certificate should point to the fullchain file, not only the leaf certificate, or some clients will fail to validate it.
6. Cover every hostname you publish, including www and API subdomains, either with one certificate that lists them all or with separate certificates.
7. Redirect all HTTP traffic with a permanent redirect. In nginx: server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; } In Apache: RewriteEngine On, RewriteCond %{HTTPS} off, RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]. In IIS, use the URL Rewrite module with a rule matching {HTTPS} off. In ASP.NET Core, call app.UseHttpsRedirection(). Behind a load balancer that terminates TLS, redirect at the load balancer or check the X-Forwarded-Proto header.
8. Add HSTS once the redirect works everywhere, so returning browsers skip the unencrypted request entirely.
9. Restrict protocols to TLS 1.2 and 1.3, for example ssl_protocols TLSv1.2 TLSv1.3; in nginx.
Check your own site
Start with the free passive scan: no account needed, and you get an A to F grade covering headers, TLS, cookies, DNS and other configuration a visitor can observe. It does not send attack payloads, so it will not confirm every class of flaw. The full scan, available with a free account, runs the active checks, including the one described on this page.