Security Headers & SSL Checker - Bulk SSL Expiry & HSTS avatar

Security Headers & SSL Checker - Bulk SSL Expiry & HSTS

Pricing

from $3.00 / 1,000 site auditeds

Go to Apify Store
Security Headers & SSL Checker - Bulk SSL Expiry & HSTS

Security Headers & SSL Checker - Bulk SSL Expiry & HSTS

Bulk security headers checker and SSL checker: HSTS, CSP, X-Frame-Options, Referrer-Policy, Permissions-Policy, SSL certificate expiry and issuer, TLS version, HTTPS redirect and cookie flags for thousands of websites. A-F grade and copy-paste fixes per site.

Pricing

from $3.00 / 1,000 site auditeds

Rating

0.0

(0)

Developer

Adam Abdou-Gustavson

Adam Abdou-Gustavson

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

10 days ago

Last modified

Features

Limited permissions

Share

Security Headers & SSL Checker — Bulk SSL Expiry, HSTS and CSP Audit

Check HTTP security headers and SSL/TLS certificates for hundreds or thousands of websites in one run, and get an A+ to F grade, a 0–100 score and a copy-paste fix for every issue.

What it does

For each website this security headers checker and SSL checker makes one HTTPS request and one TLS handshake (plus an optional http:// request to test the redirect) and reports:

Security headers

  • Strict-Transport-Security (HSTS): max-age in days, includeSubDomains, preload
  • Content-Security-Policy: present or missing, report-only mode, and weak script-src sources ('unsafe-inline', 'unsafe-eval', wildcards)
  • Clickjacking protection: X-Frame-Options or CSP frame-ancestors
  • X-Content-Type-Options, Referrer-Policy, Permissions-Policy, Cross-Origin-Opener-Policy
  • Version disclosure in Server / X-Powered-By
  • Cookie flags: Secure, HttpOnly, SameSite for every cookie set on the page

SSL / TLS certificate

  • SSL certificate validity: expired, self-signed, hostname mismatch or untrusted chain, with the error message
  • SSL expiry checker: issuer, subject, SANs, valid-from and valid-to dates, and days left (certDaysLeft), plus certExpiringSoon and certExpired true/false flags. certExpiringSoon is true at or below certExpiryWarningDays (default 21), and a high-severity issue is added. The dates are also read from certificates that fail verification (expired, self-signed, wrong host), so an expired certificate shows how long ago it expired
  • Negotiated TLS version and cipher (TLS 1.0 / 1.1 are flagged)
  • HTTP → HTTPS redirect

It is passive: no vulnerability scanning, no payloads, no login. It sees only what any browser sees.

Quick start

  1. Click Try for free (or Start) on this page.
  2. Paste your websites into URLs, one per line. Bare domains like example.com are fine (the form is pre-filled with github.com and example.com).
  3. Click Start. Open the Output tab, or export to CSV, Excel or JSON. Sort by certDaysLeft to see which certificates expire first, or open the SSL expiry monitor view and filter on certExpiringSoon.

Input examples

1. Bulk security headers check:

{
"urls": ["github.com", "example.com", "https://shop.example.org/"]
}

2. SSL expiry monitoring for client sites (warn 30 days ahead, skip the HTTP check):

{
"urls": ["client1.com", "client2.com", "client3.com"],
"certExpiryWarningDays": 30,
"checkHttpRedirect": false
}

3. Large list of sites, more parallel requests:

{
"urls": ["site1.com", "site2.com", "site3.com"],
"certExpiryWarningDays": 21,
"maxConcurrency": 30
}
FieldDefaultWhat it does
urls–Websites or domains. https:// is added when missing; duplicates are removed; invalid entries are listed in the SUMMARY.
certExpiryWarningDays21Certificates expiring within this many days (or already expired) get certExpiringSoon: true and a high-severity issue.
checkHttpRedirecttrueAlso request http:// to check it redirects to HTTPS.
maxConcurrency10Sites audited in parallel (1–50).

Sample output

Real results from an earlier run on 2026-10-20. github.com (the long CSP value is shortened here with "..."):

{
"inputUrl": "https://github.com/",
"checkedAt": "2026-10-20T04:10:00+00:00",
"finalUrl": "https://github.com/",
"statusCode": 200,
"hsts": "max-age=31536000; includeSubdomains; preload",
"hstsMaxAgeDays": 365,
"hstsIncludeSubDomains": true,
"hstsPreload": true,
"csp": "default-src 'none'; base-uri 'self'; child-src github.githubassets.com ...",
"cspReportOnly": true,
"xFrameOptions": "deny",
"xContentTypeOptions": "nosniff",
"referrerPolicy": "origin-when-cross-origin, strict-origin-when-cross-origin",
"permissionsPolicy": null,
"coop": null,
"serverHeader": "github.com",
"poweredBy": null,
"cookies": [
{ "name": "_gh_sess", "secure": true, "httpOnly": true, "sameSite": "lax" },
{ "name": "_octo", "secure": true, "httpOnly": false, "sameSite": "lax" },
{ "name": "logged_in", "secure": true, "httpOnly": true, "sameSite": "lax" }
],
"tlsVersion": "TLSv1.3",
"cipher": "TLS_AES_128_GCM_SHA256",
"certValid": true,
"certSubject": "github.com",
"certIssuer": "Sectigo Limited",
"certValidFrom": "2026-09-01",
"certValidTo": "2026-11-29",
"certDaysLeft": 40,
"certExpired": false,
"certExpiringSoon": false,
"certSans": ["github.com", "www.github.com"],
"httpsRedirect": true,
"missingHeaders": ["Permissions-Policy"],
"score": 85,
"grade": "A",
"topIssue": "Missing Permissions-Policy",
"issues": [
{
"severity": "low",
"issue": "Missing Permissions-Policy",
"recommendation": "Add e.g. \"Permissions-Policy: camera=(), microphone=(), geolocation=()\"."
},
{
"severity": "low",
"issue": "Cookies without Secure/HttpOnly: ['_octo']",
"recommendation": "Set Secure; HttpOnly; SameSite=Lax on session cookies."
}
]
}

An expired certificate from a local run on 2026-11-02 (expired.badssl.com, a public test site), shortened to the key fields:

{
"inputUrl": "https://expired.badssl.com/",
"certValid": false,
"certError": "certificate has expired",
"certIssuer": "COMODO CA Limited",
"certValidTo": "2015-04-12",
"certDaysLeft": -4222,
"certExpired": true,
"certExpiringSoon": true,
"score": 0,
"grade": "F",
"topIssue": "Invalid TLS certificate: certificate has expired",
"issues": [
{
"severity": "critical",
"issue": "Invalid TLS certificate: certificate has expired",
"recommendation": "Install a valid certificate (e.g. Let's Encrypt)."
},
{
"severity": "critical",
"issue": "Site not reachable over HTTPS",
"recommendation": "Enable HTTPS."
}
]
}

Scoring

Points for HSTS (up to 20), CSP (up to 25), clickjacking protection (15), X-Content-Type-Options (10), Referrer-Policy (10), Permissions-Policy (10) and smaller items such as COOP and no version disclosure. Penalties apply for no HTTP→HTTPS redirect and outdated TLS, and an invalid certificate caps the score at 30. Grades: A+ ≥ 95, A ≥ 85, B ≥ 70, C ≥ 55, D ≥ 40, F < 40.

Use cases

  • SSL certificate expiry monitoring: schedule a weekly run over all your domains and alert on certDaysLeft before anything expires.
  • Web agencies and MSPs: grade every client site, send the fixes, and track improvements over time.
  • Vendor and third-party risk reviews: check the public security posture of suppliers in bulk.
  • Security consultants and pentest scoping: a quick, passive first look at a list of hosts.
  • Sales prospecting: find sites with missing headers or expiring certificates as a reason to start a conversation.

Pricing

This Actor uses pay-per-event pricing. These are the current prices:

EventPriceWhen it is charged
Site audited (site-audited)$0.003 per site ($3 per 1,000 sites)Once for each unique site in the output
Actor start (apify-actor-start)$0.00005Once per run, per GB of memory (the default memory needs one)

Headers, certificate, TLS and redirect checks are all included in the per-site price.

SitesCost
50$0.15
1,000$3.00
10,000$30.00
100,000$300.00

Duplicates are removed before auditing and invalid entries are not charged. Sites that are unreachable still get an output row (with the error) and are charged. There is no rental fee and no separate compute charge. Set a maximum cost per run in the run options (or maxTotalChargeUsd in the API) and the Actor stops cleanly when it reaches it.

Use it via API, code or AI agents

Everything in the Console also works over the API, so you can run it from code, a scheduler or an AI agent. Replace <YOUR_APIFY_TOKEN> with your token from Apify Console → Settings → API & Integrations.

REST: run and get the results in one call (waits up to 5 minutes; maxTotalChargeUsd caps what the run can cost):

curl -X POST "https://api.apify.com/v2/acts/batreek~security-headers-ssl-audit/run-sync-get-dataset-items?maxTotalChargeUsd=1" \
-H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"urls": ["example.com", "github.com"], "certExpiryWarningDays": 21}'

Python (pip install apify-client):

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("batreek/security-headers-ssl-audit").call(run_input={
"urls": [
"example.com",
"github.com"
],
"certExpiryWarningDays": 21
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

JavaScript / Node.js (npm install apify-client):

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('batreek/security-headers-ssl-audit').call({"urls": ["example.com", "github.com"], "certExpiryWarningDays": 21});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

AI agents (MCP): add this Actor as a tool in Claude, ChatGPT, Cursor or any MCP client through Apify's hosted MCP server at https://mcp.apify.com?tools=batreek/security-headers-ssl-audit. The agent can then audit security headers and SSL expiry for a list of websites and read the structured results. Runs are billed to your Apify account like any other run.

No-code: use Apify's integrations (Zapier, Make, n8n, Google Sheets, Slack, webhooks) or put it on an Apify Schedule.

FAQ

Is this a vulnerability scanner? No. It reads the response headers and the TLS certificate that any browser receives. It sends no attack payloads and does not log in, so it is safe to run on sites you do not own.

How do I monitor SSL certificate expiry? Save your list as a task with certExpiryWarningDays set to your lead time (for example 30) and schedule it weekly. Then filter the output on certExpiringSoon: true, or open the SSL expiry monitor dataset view. The run's SUMMARY record also counts certExpiringSoon, certExpired and certInvalid, so a webhook or script can alert when they are above zero.

Does it check subdomains automatically? No. It audits exactly the URLs you give it. Add each subdomain (for example shop.example.com) as its own entry.

Why is a site graded F even though it works fine? Most sites are missing several security headers. The grade reflects those headers, not whether the site is up. The issues list tells you exactly what to add.

Which page does it check? The URL you give (the home page for a bare domain), after following redirects. Headers can differ on other pages of the same site.

Does it check HSTS preload list status? It reads the preload directive in your HSTS header (hstsPreload). It does not query the browser preload list itself.

How is this different from securityheaders.com or SSL Labs? Those tools check one site at a time in a browser. This Actor checks hundreds or thousands of sites in one run, puts headers, certificate expiry, HTTPS redirect and cookie flags in one row per site, and gives you JSON, CSV, Excel or an API you can schedule. It does not run SSL Labs' full cipher-suite and protocol scan; it reports the TLS version and cipher your connection negotiated.

Can I use the results in Google Sheets or Slack? Yes. Export the dataset, or connect the task to Google Sheets, Slack, Zapier, Make or n8n with Apify integrations.

Limitations

  • One page per site: only the URL you give (after redirects) is checked, not every page.
  • Headers and certificate only: no port scanning, no vulnerability or malware checks, no DNS (SPF/DMARC) checks, and no TLS cipher-suite enumeration beyond the cipher that was negotiated.
  • Port 443 only: the TLS handshake is made on the default HTTPS port.
  • Bot protection: some sites (for example behind Cloudflare challenges) may return a block page with different headers than a real browser sees.
  • Timeouts: each request times out after 20 seconds (10 seconds to connect) and follows up to 10 redirects; slower sites are reported with an error.
  • The score is a heuristic: it is a practical guide to what to fix first, not a compliance certification.