Website security checks you can run without hacking anything
Passive security checks for online stores: TLS certificate expiry, HSTS, CSP, nosniff, cookie flags, mixed content, outdated jQuery, security.txt and DMARC.
FixReports editorial team10 min read
You can check a lot of an online store's security setup from the outside by reading what the site already sends to every visitor: its TLS certificate, redirects, HTTP response headers, cookies, the scripts it loads and its public DNS records. These passive checks send no attack traffic and need no login, so they put no more load on a store than a normal visit. They catch configuration gaps such as an expiring certificate, missing HSTS, insecure cookies, mixed content or a jQuery version with known flaws. They are not a penetration test and cannot prove a store is secure.
Key points
- Publicly trusted TLS certificates issued since 15 March 2026 can be valid for at most 200 days, falling to 100 days in March 2027 and 47 days in March 2029 (CA/Browser Forum (opens in a new tab)).
- Browsers ignore the HSTS header when it is sent over plain HTTP (MDN (opens in a new tab)).
- The CSP
frame-ancestorsdirective does not work in a<meta>tag; it has to be a response header (MDN (opens in a new tab)). - jQuery versions before 3.5.0 are affected by two XSS vulnerabilities, and CISA added one of them, CVE-2020-11023, to its Known Exploited Vulnerabilities catalog on 23 January 2025 (NVD (opens in a new tab)).
- A
security.txtfile must containContactandExpiresfields and live at/.well-known/security.txt(RFC 9116 (opens in a new tab)).
What counts as a passive security check?
A passive check only reads what the site or its DNS returns to an ordinary request.
That means loading public pages, reading the certificate and response headers, listing the cookies and scripts a page sets, and querying public DNS records. A passive check does not guess passwords, send injection payloads, probe admin URLs or scan ports. Everything below can be done with a browser, curl, openssl and dig.
How do you check your TLS certificate and its expiry?
Read the certificate's dates and names directly, and make sure renewal is automated.
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
Check that notAfter is comfortably in the future, that the certificate covers both example.com and www.example.com if you use both (the browser's certificate viewer lists the names), and that the browser shows no warnings. Certificate lifetimes are shrinking under the CA/Browser Forum Baseline Requirements (section 6.3.2, version 2.3.1 as of October 2026), following Ballot SC-081v3 (opens in a new tab), adopted on 11 April 2025:
| Certificate issued | Maximum validity |
|---|---|
| Before 15 March 2026 | 398 days |
| 15 March 2026 to 14 March 2027 | 200 days |
| 15 March 2027 to 14 March 2029 | 100 days |
| From 15 March 2029 | 47 days |
Short lifetimes make manual renewal risky, so confirm that your host or certificate tool renews automatically. Also confirm that plain HTTP redirects to HTTPS:
curl -sI http://example.com/ | grep -i -E "^HTTP|^location"
You want a 301 (or 308) response with a location header starting with https://.
Which security headers should an online store send?
A small set of response headers blocks common browser-side attacks at almost no cost.
| Header | What it does | Typical value | Source |
|---|---|---|---|
Strict-Transport-Security | Tells browsers to use HTTPS only and stops users clicking through certificate errors | max-age=31536000; includeSubDomains | MDN (opens in a new tab) |
Content-Security-Policy: frame-ancestors | Controls which sites may embed your pages, which defends against clickjacking | frame-ancestors 'self' | MDN (opens in a new tab) |
X-Frame-Options | Older framing control; OWASP says frame-ancestors obsoletes it in supporting browsers | DENY or SAMEORIGIN | OWASP (opens in a new tab) |
X-Content-Type-Options | Stops MIME sniffing and blocks scripts and stylesheets served with the wrong type | nosniff | MDN (opens in a new tab) |
Referrer-Policy | Limits how much of your URLs is sent to other sites | strict-origin-when-cross-origin | OWASP |
X-XSS-Protection | Browser XSS filter header; OWASP says it can create XSS vulnerabilities in otherwise safe sites | Do not set, or 0 | OWASP |
Check what your store sends:
curl -sI https://example.com/
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: frame-ancestors 'self'
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Two cautions. includeSubDomains blocks any subdomain that only works over HTTP, so check subdomains first. HSTS preloading requires max-age of at least 31536000 and includeSubDomains, so only add preload when every subdomain is ready for HTTPS. A full CSP that restricts scripts is worth having, but OWASP notes it is complex to configure and maintain, and stores with many apps need to test it carefully.
Are your cookies set with Secure, HttpOnly and SameSite?
Session and cart cookies should carry all three attributes, and you can see them in the Set-Cookie response headers.
| Attribute | Effect (per MDN (opens in a new tab)) | Where it matters |
|---|---|---|
Secure | Sent only over HTTPS; sites on plain HTTP cannot set it | Every cookie on an HTTPS store |
HttpOnly | JavaScript cannot read it through document.cookie, which helps against XSS | Login sessions and carts |
SameSite=Lax or Strict | Limits when the cookie is sent on cross-site requests | Sessions; Strict suits authentication and cart cookies |
SameSite=None | Sent on cross-site requests; must be combined with Secure | Only embedded third-party features that need it |
If no SameSite attribute is set, browsers treat the cookie as Lax. Cookies that your own scripts need to read cannot be HttpOnly, so focus on the ones that identify a logged-in customer or an admin.
curl -sI https://example.com/ | grep -i "^set-cookie"
Browser developer tools show the same information, including cookies set by scripts after the page loads.
How do you find mixed content?
Mixed content is any resource loaded over HTTP on a page served over HTTPS, and the browser console lists it.
MDN (opens in a new tab) splits it into two groups. Images, audio and video are "upgradable": browsers automatically request them over HTTPS. Scripts, stylesheets, iframes, fonts and fetch() requests are "blockable": browsers block them, which breaks whatever depended on them. Upgraded requests to a bare IP address are blocked too.
To find it, open the console on your key templates (home, collection, product, cart) and search your theme code, page content and app settings for http://. Shopify's help center says any store page with an asset not delivered over HTTPS is considered insecure (opens in a new tab), and recommends hosting assets on Shopify or serving them over HTTPS. On WooCommerce, check old post content and theme options if the site ever ran on http://.
How do you spot outdated JavaScript libraries with known CVEs?
List the libraries each page loads, read their versions, and compare them with the National Vulnerability Database.
Start with jQuery. In the browser console, $.fn.jquery returns the loaded version (jQuery API (opens in a new tab)). Versions to flag:
| CVE | Affected versions | Issue | NVD score (v3.1) |
|---|---|---|---|
| CVE-2020-11022 (opens in a new tab) | 1.12.0 to before 3.5.0 | Passing untrusted HTML to methods like .html() or .append() may run code | 6.1 Medium |
| CVE-2020-11023 (opens in a new tab) | 1.0.3 to before 3.5.0 | Same, for HTML containing <option> elements; in CISA's KEV catalog since 23 January 2025 | 6.1 Medium |
| CVE-2019-11358 (opens in a new tab) | Before 3.4.0 | Prototype pollution through jQuery.extend(true, ...) | 6.1 Medium |
Both 2020 issues are fixed in jQuery 3.5.0. A vulnerable version means the flawed code is present; whether it can be exploited depends on how the site passes data to it. WordPress has bundled jQuery 3.5.1 since version 5.6 (opens in a new tab), so an old jQuery on a WooCommerce store points to an outdated WordPress or to a theme or plugin loading its own copy. On Shopify, check your theme files and the apps that inject scripts.
What is security.txt and does your store need one?
It is a plain text file that tells security researchers how to report a vulnerability to you.
RFC 9116 (opens in a new tab) (April 2022, an Informational RFC, so following it is voluntary) says the file must be served over HTTPS at /.well-known/security.txt as text/plain. Contact and Expires are required, and the RFC recommends an Expires date less than a year ahead.
Contact: mailto:security@example.com
Expires: 2027-09-30T23:00:00.000Z
Preferred-Languages: en
Policy: https://example.com/security-policy
On WooCommerce you can place the file on your server. On a hosted platform, check whether you can publish a file at that path; if not, a clearly labelled security contact on your contact page still helps.
How does DMARC protect your store from email spoofing?
DMARC lets you ask mailbox providers to quarantine or reject mail that uses your domain in the From address without passing aligned SPF or DKIM.
A record at p=none only collects reports; it does not stop spoofed mail. Customers expect order confirmations and password resets from your domain, so a phishing message that shows your exact domain is worth blocking. Check your policy with dig +short TXT _dmarc.example.com, and see RFC 9989 (opens in a new tab) for the specification. DMARC does not cover lookalike domains, only the domain that publishes the record.
What does Shopify manage, and what do you control on WooCommerce?
Shopify runs the servers behind its storefronts, while a self-hosted WooCommerce store leaves server settings to you and your host.
| Check | Shopify | WooCommerce (self-hosted) |
|---|---|---|
| TLS certificate | Free for all domains added to Shopify (opens in a new tab); may take up to 48 hours for third-party domains | Your host or your own setup |
| HTTP to HTTPS redirect | Platform | Web server, CDN or host settings |
| Security headers | Sent by Shopify's servers | Web server, CDN or a plugin |
| Cookie flags | Shopify's own cookies set by the platform; app and theme cookies are yours | WordPress core, plugins and server |
| Mixed content and JS libraries | Your theme, content and apps | Your theme, content and plugins |
| security.txt and DMARC | Your domain and DNS | Your domain and DNS |
When we checked several Shopify-hosted storefronts in October 2026, their responses included HSTS with a max-age of about 91 days, X-Content-Type-Options: nosniff and a CSP with upgrade-insecure-requests, while frame-ancestors differed between stores. Shopify says it is certified Level 1 PCI DSS compliant (opens in a new tab). Your theme and installed apps remain your responsibility.
On WooCommerce, WordPress's hardening guide (opens in a new tab) says to keep WordPress and plugins updated, delete plugins you don't use, and ask your host what security precautions they take.
Why is this not a penetration test?
A penetration test actively attempts attacks; passive checks only observe.
NIST SP 800-115 defines penetration testing as security testing in which evaluators mimic real-world attacks to find ways around a system's security features (NIST glossary (opens in a new tab)). Passive checks cannot see server-side flaws in plugins, weak or reused admin passwords, missing two-factor authentication, broken access control or vulnerable code that never appears in page source. Use them as a baseline you can repeat at any time. For deeper assurance, commission a penetration test with a written scope, on systems you own or are authorised to test.
A free scan runs a first pass over your store. The Website Security Report covers the passive checks in this article, from TLS and redirects to headers, cookies, mixed content, outdated libraries, security.txt and DMARC, with fixes for each finding. Like any passive review, it cannot guarantee that a store is secure.
Frequently asked questions
Do passive security checks put my store at risk?
No more than a normal visit. They request the same public pages and DNS records that any browser or mail server would, and they don't try to log in or send attack payloads.
Can I add security headers on Shopify?
Storefront response headers come from Shopify's servers, so contact Shopify Support if one you need is missing. A CSP <meta> tag in your theme can add some directives, but MDN notes that frame-ancestors is not supported in <meta>.
Does an old jQuery version mean my store has been hacked?
No. It means code with known vulnerabilities is loaded, which raises the risk if the site passes untrusted HTML to the affected methods. Update it, or remove the theme or plugin that loads it.
How long can a TLS certificate be valid now?
Publicly trusted certificates issued from 15 March 2026 can be valid for at most 200 days. The limit drops to 100 days from 15 March 2027 and 47 days from 15 March 2029.
Is a security.txt file required?
RFC 9116 is an Informational RFC, so publishing the file is voluntary under the standard. It is cheap to publish and gives researchers a clear way to reach you.
Does a clean passive scan mean my store is secure?
No. It shows that the public configuration looks right. Server-side vulnerabilities, account security and business logic flaws need other testing.
Sources
- Baseline Requirements for the Issuance and Management of Publicly-Trusted TLS Server Certificates, version 2.3.1 (opens in a new tab), CA/Browser Forum, 4 October 2026
- Ballot SC-081v3: Introduce Schedule of Reducing Validity and Data Reuse Periods (opens in a new tab), CA/Browser Forum, 11 April 2025
- Strict-Transport-Security (opens in a new tab), MDN Web Docs, last modified 11 September 2026
- CSP: frame-ancestors (opens in a new tab), MDN Web Docs, last modified 27 August 2026
- X-Content-Type-Options (opens in a new tab), MDN Web Docs, last modified 17 March 2026
- Using HTTP cookies (opens in a new tab), MDN Web Docs, last modified 17 September 2026
- Mixed content (opens in a new tab), MDN Web Docs, last modified 15 August 2026
- HTTP Security Response Headers Cheat Sheet (opens in a new tab), OWASP Cheat Sheet Series, accessed 22 October 2026
- CVE-2020-11022 (opens in a new tab), NIST National Vulnerability Database, published 29 April 2020
- CVE-2020-11023 (opens in a new tab), NIST National Vulnerability Database, published 29 April 2020
- CVE-2019-11358 (opens in a new tab), NIST National Vulnerability Database, published 20 April 2019
- .jquery (opens in a new tab), jQuery API Documentation, accessed 22 October 2026
- Updating core jQuery to version 3, part 2 (opens in a new tab), Make WordPress Core, 5 November 2020
- RFC 9116: A File Format to Aid in Security Vulnerability Disclosure (opens in a new tab), IETF, April 2022
- RFC 9989: Domain-Based Message Authentication, Reporting, and Conformance (DMARC) (opens in a new tab), IETF, May 2026
- Enabling secure connections to your Shopify store (opens in a new tab), Shopify Help Center, accessed 22 October 2026
- Security (opens in a new tab), Shopify, accessed 22 October 2026
- Hardening WordPress (opens in a new tab), WordPress Developer Resources, accessed 22 October 2026
- Penetration testing (glossary) (opens in a new tab), NIST Computer Security Resource Center, citing NIST SP 800-115 (September 2008), accessed 22 October 2026
All guides
- Accessibility overlays and the FTC's accessiBe order: what store owners should knowThe FTC's 2025 order made accessiBe pay $1 million over WCAG compliance claims. What the order says, what it doesn't, and what stores using overlays should do.
- Core Web Vitals for online stores: LCP, INP and CLS explainedWhat LCP, INP and CLS measure, the good and poor thresholds at the 75th percentile, lab vs field data, and the usual fixes on Shopify and WooCommerce stores.
- Got an ADA website demand letter? What to check firstWhat ADA website demand letters usually allege, how WCAG fits in, what to gather, why overlays don't fix code, and when to call a lawyer. Not legal advice.