← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
tenable:15901

SSL Certificate Expiry

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a dead ID badge on the front door, not a hidden tunnel through the vault

Plugin 15901 fires when a scanned SSL/TLS-enabled service presents an X.509 certificate whose notAfter date is already in the past. There is no vulnerable software version range here in the normal CVE sense; *any* product version can trigger it if the currently deployed certificate is expired, including web servers, VPN portals, load balancers, middleware, management interfaces, and internal apps.

Tenable labels it Medium because expired certificates break validation and can undermine integrity if users or clients are trained to click through warnings. For enterprise patch prioritization, that overstates the *exploitability*: an expired cert is mostly an availability, trust, and compliance failure unless an attacker also has a man-in-the-middle position or can trick users into bypassing validation.

"Expired certs are real hygiene debt, but they are not an exploit chain by themselves."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Enumerate the TLS service with openssl s_client or zgrab2

The attacker or scanner connects to the target service and reads the presented certificate chain during the TLS handshake. If the leaf certificate is past notAfter, the condition is observable immediately without credentials or exploitation.
Conditions required:
  • Network reachability to the TLS service
  • A service actually presenting an expired certificate
Where this breaks in practice:
  • This is only discovery; it does not grant code execution, auth bypass, or data access
  • Many findings are on internal-only or admin-only services with no external user path
Detection/coverage: Excellent scanner coverage. Nessus, browser tooling, openssl, load balancers, and synthetic monitoring all detect this reliably.
STEP 02

Client validation fails in the browser, agent, or API consumer

Modern clients are supposed to reject or warn on invalid certificates, including expired ones. That usually stops the connection or at least places a very visible warning in front of the user or application.
Conditions required:
  • A user, browser, script, or service attempts to connect
  • The client performs normal certificate validation
Where this breaks in practice:
  • Secure clients block the session rather than enabling attacker progress
  • Well-built API clients and service meshes fail closed instead of silently accepting the cert
Detection/coverage: Browser errors, application logs, synthetic transactions, and reverse proxies typically surface the break quickly.
STEP 03

Attacker abuses the exception path with mitmproxy or bettercap

To turn the condition into compromise, the attacker generally needs a second ingredient: a man-in-the-middle position, DNS tampering, hostile Wi-Fi, or a social-engineering path that convinces users to ignore certificate warnings. The expired cert matters because repeated warning fatigue can normalize unsafe click-through behavior.
Conditions required:
  • Attacker can intercept or redirect traffic
  • Users or clients are willing or configured to bypass certificate errors
Where this breaks in practice:
  • Requires prior network position or another foothold
  • HSTS, pinned certs, strict TLS libraries, corporate proxies, and managed browsers often block the bypass
Detection/coverage: NGFW, DNS monitoring, proxy logs, EDR network telemetry, and browser hardening policies should catch or prevent most real attack attempts here.
STEP 04

Impact is trust erosion or outage before it is compromise

In most enterprises the first-order impact is broken access, failed integrations, PCI findings, and emergency certificate replacement work. Security impact becomes material only when operators compensate unsafely by disabling validation or training users to accept broken TLS.
Conditions required:
  • Business process depends on the affected service
  • Operational teams use insecure workarounds
Where this breaks in practice:
  • No direct payload delivery path exists from the expired certificate alone
  • Blast radius is limited to the specific service or trust path presenting the bad certificate
Detection/coverage: Service monitors, PKI inventory, certificate-expiry alerting, and attack-surface tools catch this much earlier than exploit detection tooling.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo active exploitation evidence as a standalone issue. This is not a CVE-class software flaw and there is no known campaign category where 'expired cert only' is the intrusion mechanism.
Proof-of-concept availabilityTrivial to verify, not really exploitable. Any TLS client such as openssl s_client, a browser, or zgrab2 can confirm the condition, but that is validation failure testing, not weaponized exploit code.
EPSSNot applicable. There is no CVE, so no FIRST EPSS probability exists.
KEV statusNot applicable. Plugin 15901 is a Nessus finding, not a CISA KEV-listed CVE.
Vendor score and vectorTenable assigns Medium / 5.3 with CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N, manually justified because expired certificates cannot be validated.
Affected scopeAny product version can be affected if it currently presents an expired SSL/TLS certificate. This is certificate state, not a buggy release train.
Fixed stateNo patched software version. The condition clears when the presented leaf cert and chain are renewed/replaced and the service is reloaded or restarted as required.
Exposure and scanning realityPublic-internet search engines like Censys index certificate validity metadata and explicitly note that expired certificates on live hosts can cause service interruption. But this plugin also commonly hits internal-only services, so fleet exposure is highly environment-specific.
Compliance and business impactTenable documents plugin 15901 as part of PCI SSL/TLS validity and expiration checks; an expired cert can become an audit failure even when exploitability is low.
Disclosure / originNessus plugin 15901 was published on 2004-12-03 by Tenable. That date reflects scanner content publication, not disclosure of a software vulnerability.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (2.2/10)

The decisive friction is that an expired certificate is not an exploit primitive: it does not hand an attacker execution, access, or privilege by itself. To get from this finding to compromise, the attacker usually needs a second major assumption such as MITM position, client misconfiguration, or users conditioned to bypass TLS warnings.

HIGH Downgrade from vendor Medium to enterprise patch-priority LOW
HIGH Technical characterization as certificate-state/configuration debt rather than software vulnerability
MEDIUM Business urgency for specific internet-facing services may exceed the security severity

Why this verdict

  • Start at 5.3, then subtract hard because this is not a software vuln. Tenable's baseline treats failed certificate validation as integrity impact, but there is no memory corruption, auth bypass, sandbox escape, or direct attacker-controlled state transition here.
  • Second-stage attacker position required. To weaponize this into credential theft or interception, the adversary typically needs unauthenticated remote reach *plus* a MITM position, DNS influence, hostile Wi-Fi, or a user willing to click through warnings. Each of those assumptions sharply narrows real-world exploitability.
  • Reachable population is broader than external exposure but narrower than the score implies. Plugin 15901 hits internet-facing apps, internal apps, appliances, and management planes alike; many detections are operationally important but never exposed to arbitrary attackers, which compounds downward pressure on severity.

Why not higher?

There is no credible single-step path from 'expired cert detected' to host compromise. Modern browsers and TLS libraries are designed to stop at this exact boundary, so the finding more often causes outages and audit pain than attacker success.

Why not lower?

This is not pure noise. Expired certificates on production services break authentication guarantees, generate user warning fatigue, and can push teams into unsafe exceptions like disabling validation or bypassing browser warnings. On customer-facing or identity-adjacent systems, that operational pressure is worth tracking even if it is not emergency patch material.

05 · Compensating Control

What to do — in priority order.

  1. Turn on certificate-expiry monitoring — Deploy or tighten monitoring at the load balancer, reverse proxy, PKI platform, or synthetic probe layer so you alert on 30/14/7/3/1 day thresholds before Nessus finds it. For a LOW verdict there is no SLA — treat as backlog hygiene, but do this in the next routine cert-management cycle because prevention is far cheaper than cleanup.
  2. Block insecure client exceptions — Enforce managed browser and API-client policies that prohibit click-through on invalid certs and ban flags like --insecure, curl -k, or custom trust-all code paths. For a LOW verdict there is no SLA — treat as backlog hygiene, but close exception paths before they become the real vulnerability.
  3. Automate certificate renewal — Use ACME, centralized PKI automation, or cert lifecycle tooling so replacement and service reload happen without calendar-driven manual work. For a LOW verdict there is no SLA — treat as backlog hygiene, but this is the durable fix for large fleets.
  4. Prioritize internet-facing and identity services first — If the expired cert sits on SSO, VPN, mail, customer portals, or externally reachable apps, treat it as an *operations outage* and renew it immediately even though the security severity is LOW. The reassessment only says 'don't burn emergency vuln-patching capacity across the whole fleet.'
What doesn't work
  • Suppressing the Nessus finding without renewing the certificate; you only hide the symptom while users and clients still hit validation failures.
  • Disabling certificate validation in browsers, agents, or scripts; that removes the very control that prevents an expired cert from becoming a real interception risk.
  • Relying on EDR alone; endpoint tools do not fix broken PKI state or prevent unsafe manual click-through decisions at the browser and middleware layers.
06 · Verification

Crowdsourced verification payload.

Run this from an auditor workstation, CI job, or scanner utility host that can reach the target service over the network. Invoke it as python3 check_cert_expiry.py example.com 443 or python3 check_cert_expiry.py 10.10.10.25 8443 app.internal.example; it needs no privileges beyond outbound TCP connectivity.

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
# check_cert_expiry.py
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

import sys
import ssl
import socket
from datetime import datetime, timezone

TIMEOUT = 8


def parse_args(argv):
    if len(argv) < 3 or len(argv) > 4:
        print("UNKNOWN - usage: python3 check_cert_expiry.py <host> <port> [sni]", flush=True)
        sys.exit(2)
    host = argv[1]
    try:
        port = int(argv[2])
    except ValueError:
        print("UNKNOWN - port must be an integer", flush=True)
        sys.exit(2)
    sni = argv[3] if len(argv) == 4 else host
    return host, port, sni


def get_peer_cert(host, port, sni):
    ctx = ssl.create_default_context()
    # We want to inspect the certificate even if it is expired or otherwise invalid.
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE

    with socket.create_connection((host, port), timeout=TIMEOUT) as sock:
        with ctx.wrap_socket(sock, server_hostname=sni) as tls:
            cert = tls.getpeercert()
            cipher = tls.cipher()
            version = tls.version()
            return cert, cipher, version


def main():
    host, port, sni = parse_args(sys.argv)

    try:
        cert, cipher, version = get_peer_cert(host, port, sni)
    except ssl.SSLError as e:
        print(f"UNKNOWN - TLS handshake failed: {e}", flush=True)
        sys.exit(2)
    except OSError as e:
        print(f"UNKNOWN - connection failed: {e}", flush=True)
        sys.exit(2)
    except Exception as e:
        print(f"UNKNOWN - unexpected error: {e}", flush=True)
        sys.exit(2)

    if not cert:
        print("UNKNOWN - no certificate presented by remote service", flush=True)
        sys.exit(2)

    not_after_raw = cert.get("notAfter")
    subject = cert.get("subject", ())
    issuer = cert.get("issuer", ())

    if not not_after_raw:
        print("UNKNOWN - certificate missing notAfter field", flush=True)
        sys.exit(2)

    try:
        # Typical format: 'Jun 14 23:59:59 2025 GMT'
        not_after = datetime.strptime(not_after_raw, "%b %d %H:%M:%S %Y %Z").replace(tzinfo=timezone.utc)
    except ValueError:
        print(f"UNKNOWN - unable to parse notAfter: {not_after_raw}", flush=True)
        sys.exit(2)

    now = datetime.now(timezone.utc)
    cn = ""
    try:
        for rdn in subject:
            for key, value in rdn:
                if key == "commonName":
                    cn = value
                    raise StopIteration
    except StopIteration:
        pass

    issuer_cn = ""
    try:
        for rdn in issuer:
            for key, value in rdn:
                if key == "commonName":
                    issuer_cn = value
                    raise StopIteration
    except StopIteration:
        pass

    meta = f"host={host} port={port} sni={sni} tls={version} cipher={cipher[0] if cipher else 'unknown'} cn={cn or 'unknown'} issuer={issuer_cn or 'unknown'} notAfter={not_after.isoformat()}"

    if now > not_after:
        print(f"VULNERABLE - expired certificate presented; {meta}", flush=True)
        sys.exit(1)
    else:
        days_left = (not_after - now).days
        print(f"PATCHED - certificate currently valid ({days_left} day(s) remaining); {meta}", flush=True)
        sys.exit(0)


if __name__ == "__main__":
    main()
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning: do not treat plugin 15901 as emergency vulnerability patching across the fleet. For this LOW reassessment there is no noisgate mitigation SLA and no noisgate remediation SLA beyond backlog hygiene, so go fix it through cert-lifecycle operations rather than burn zero-day capacity; the exception is any *already-broken internet-facing, SSO, VPN, or customer-facing service*, which you should renew today as an operational outage while folding the rest into automated renewal and expiry monitoring so the finding disappears on the next scan cycle.

Sources

  1. Tenable Nessus Plugin 15901 - SSL Certificate Expiry
  2. Tenable whitepaper - PCI / SSL certificate validity and expiration checks
  3. RFC 5280 - X.509 certificate validity period (`notBefore`/`notAfter`)
  4. MDN - insecure certificate error caused by expired or invalid TLS certs
  5. Mozilla Support - browsers stop connecting when certificate validity cannot be verified
  6. Censys ASM Host Assets - expired certificates on live hosts may cause service interruptions
  7. Censys Certificates dataset - certificate trust and validity metadata
  8. DigiCert FAQ - TLS/SSL certificate validity lifetimes and expiration context
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.