Self-Signed SSL Certificate Undermines Visitor Trust and Identity Verification

Your website is using a security certificate that you issued yourself, rather than one verified by a trusted third party. Think of it like a business putting up its own 'health and safety approved' sign instead of getting an official inspection — visitors and browsers have no way to confirm the certificate is genuine. Modern browsers will show a security warning to anyone who visits, which can drive customers away.

Business Impact And Actions

medium urgency

Business Impact

Visitors will see browser warnings that label your site as 'Not Secure' or 'Untrusted', which erodes customer confidence and can directly reduce conversions. If your business handles payments or personal data, this finding may flag during compliance audits (such as PCI DSS), since industry standards explicitly discourage self-signed certificates for customer-facing services. There is also a secondary risk: because the certificate cannot be independently verified, it is harder for users to detect if someone is impersonating your site.

What To Do

  1. Ask your developer to replace the self-signed certificate with a free, trusted one from Let's Encrypt — this is a well-documented process that typically takes under an hour.
  2. If your site handles payments or sensitive customer data, prioritise this fix before your next compliance review.
  3. Once replaced, ask your developer to set up automatic certificate renewal so this doesn't lapse again.
  4. If this certificate is on an internal tool (not customer-facing), ask your IT team whether a private internal certificate authority is appropriate instead.

Self-Signed SSL Certificate — Missing CA Trust Chain

medium severity CVSS 5.3-6.5

Vulnerability Explanation

The server is presenting a TLS certificate that is signed by its own private key rather than by a publicly trusted Certificate Authority (CA). Because the certificate is not anchored to a trusted root in browser and OS trust stores, clients cannot independently verify the server's identity. This eliminates the authentication guarantee that TLS is designed to provide. Without CA validation, a network-positioned attacker can present their own self-signed certificate and clients have no reliable mechanism to distinguish it from the legitimate server certificate, enabling man-in-the-middle (MITM) interception. Additionally, self-signed certificates cannot be revoked through standard mechanisms (OCSP/CRL), meaning a compromised private key cannot be invalidated.

Root Cause

A self-signed certificate was generated locally (e.g., via OpenSSL) and deployed without obtaining a CA-signed certificate. This is common during initial server setup, development, or as a cost-saving measure, but is inappropriate for any production or customer-facing endpoint.

Technical Impact

A network-positioned attacker can perform a MITM attack by substituting their own certificate. Because users cannot distinguish a legitimate self-signed certificate from a forged one, they may accept the attacker's certificate — especially if they are already conditioned to click through browser warnings. This can result in interception of credentials, session tokens, and sensitive data in transit. The certificate also cannot be revoked if the private key is compromised.

Severity Justification

Exploitation requires a network-positioned attacker (e.g., same network segment, ARP spoofing, or DNS poisoning) and relies on users ignoring browser warnings. The vulnerability is real and well-understood, but is not remotely exploitable without additional preconditions. CVSS base score is moderate; contextual score rises if the endpoint handles sensitive data or is on a shared/public network.

Affected Components

  • Self-signed TLS certificate — all versions

Remediation Steps

  1. Obtain a free, trusted certificate from Let's Encrypt using Certbot. For Nginx: `sudo apt install certbot python3-certbot-nginx && sudo certbot --nginx -d yourdomain.com`. For Apache: `sudo apt install certbot python3-certbot-apache && sudo certbot --apache -d yourdomain.com`. Certbot will automatically configure the web server and set up renewal.
  2. Verify automatic renewal is active: `sudo certbot renew --dry-run`. Certbot installs a systemd timer or cron job that renews certificates before they expire.
  3. If the endpoint is internal-only (not publicly reachable), use a private internal CA and distribute its root certificate to all clients, rather than a public CA.
  4. After replacing the certificate, configure HSTS to prevent protocol downgrade: add `Strict-Transport-Security: max-age=31536000; includeSubDomains` to your server response headers.
  5. Remove or disable any legacy self-signed certificate files from the server to prevent accidental re-use.

Verification Steps

  1. Run `curl -vI https://yourdomain.com 2>&1 | grep -E 'issuer|subject|SSL'` and confirm the issuer is a trusted CA (e.g., Let's Encrypt, DigiCert), not the server itself.
  2. Visit https://www.ssllabs.com/ssltest/ and enter your domain — a valid CA-signed certificate should achieve at least a B rating with no trust errors.
  3. Check the browser padlock icon: clicking it should show a valid certificate chain with a recognised root CA, and no warnings.
  4. Confirm auto-renewal: `sudo systemctl status certbot.timer` (systemd) or `sudo crontab -l | grep certbot` (cron).

Code Examples (nginx)

Vulnerable
# Nginx config using a self-signed certificate
ssl_certificate     /etc/ssl/certs/selfsigned.crt;
ssl_certificate_key /etc/ssl/private/selfsigned.key;
Fixed
# Nginx config using a Let's Encrypt certificate (managed by Certbot)
ssl_certificate     /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

# HSTS header (add inside server block)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Best Practices

  • Use a publicly trusted CA (e.g., Let's Encrypt) for all public-facing endpoints; use a private internal CA for internal services.
  • Automate certificate renewal — Let's Encrypt certificates expire every 90 days and Certbot handles this automatically.
  • Enable HSTS after deploying a trusted certificate to prevent protocol downgrade attacks.
  • Never deploy development or test certificates (self-signed) to production environments.

Found this in your infrastructure?

VulWall scans for this and dozens of other issues automatically.

Scan Your Domain Free