Skip to content

CWE-298: Improper Certificate Validation (Expired)

Overview

This guidance helps you interpret and remediate findings from DAST (Dynamic Application Security Testing) tools. The scanner detected that the application accepted expired TLS/SSL certificates when establishing secure connections. Evidence includes successful HTTPS responses from endpoints using expired certificates, or the application proceeding with connections despite notAfter dates in the past. This is observed when the scanner intercepts or monitors the application's outbound HTTPS connections.

Analyzing the Dynamic Scan Result

What the DAST Scanner Found

When reviewing your security scan results, you'll see:

HTTP Request Details

  • URL and endpoint that triggered the finding
  • HTTP method (GET, POST, etc.)
  • Query parameters or form data with test payloads
  • Request headers and body content

HTTP Response Evidence

  • Response showing the vulnerability manifestation
  • Evidence that expired certificates were accepted
  • Runtime behavior indicators

Attack Vector

  • Which parameter or input is vulnerable
  • Type of exploitation possible
  • Context where the vulnerability appears

Mapping DAST Findings to Source Code

Find the Vulnerable Endpoint

Search for certificate validation code:

# Search for SSL/TLS client code
grep -r "ssl" src/
grep -r "verify" src/
grep -r "certificate" src/
grep -r "https.get" src/

Locate Certificate Validation

Common patterns to search for:

  • Python: Certificate validation in requests, urllib
  • Node.js: TLS options, certificate checks
  • Java: X509Certificate validation
  • C#/.NET: Certificate callback handlers
  • PHP: cURL certificate verification

Find Expiry Checks

Search for certificate handling:

# Find certificate validation
grep -r "check_expiry" src/
grep -r "notAfter" src/
grep -r "cert.verify" src/

Trace to Vulnerable Operation

Look for missing expiry validation:

  • Disabled expiry check: Custom validators ignoring expiry
  • Missing expiry enforcement or reliance on external renewal processes
  • Expiry treated as advisory rather than mandatory
  • No auto-renewal: Certificates not monitored/renewed
  • Grace period: Accepting certificates past expiry date

Remediation

Core Principle: Never establish a TLS connection unless the certificate is currently valid; certificates outside their defined validity period must always be rejected by the TLS stack.

Verification and Follow-Up Testing

After applying the fix:

Reproduce the Vulnerability

# Check certificate expiry
openssl s_client -connect localhost:443 </dev/null 2>&1 | openssl x509 -noout -dates

Trigger the application feature that performs an outbound HTTPS connection and verify that the request fails when the upstream presents an expired certificate (for example, using expired.badssl.com as the upstream).

Verify the Fix

  • Confirm certificate expiry dates valid
  • Verify certificates auto-renewed before expiry
  • Check expiry validation not bypassed in code
  • Ensure monitoring alerts before expiry
  • Test that expired certificates are rejected

Test Edge Cases

# Check certificate validity period
openssl x509 -in cert.pem -noout -startdate -enddate

# The following demonstrates expected upstream behavior;
# the actual test must invoke the application feature that
# performs the outbound HTTPS request.

# Test with expired certificate
curl https://expired.badssl.com/
# Should fail with certificate verify failed

# Check server certificate
echo | openssl s_client -connect localhost:443 2>&1 | grep "Verify return code"
# Should be: 0 (ok), NOT: 10 (certificate has expired)

# Or use browser DevTools Network tab to copy as cURL

Re-run DAST Scanner

Run your dynamic scanner again on the fixed endpoint to confirm remediation.

Additional Resources