shop.example.com
Sample report · a made-up online shop; all data is illustrative, not a real site
Date: 2026-10-28
🛡 Checked against databases on 28 Oct 2026: NVD, OSV, WPVulnerability + actively exploited list (28 Oct 2026)
32/100 Security score (100 = fewer observed risks)
Possible risks by public signs. Prioritize the findings below with your developer or hosting provider. Checks can be incomplete; this report offers no security guarantees.
Risk summary
Click a row to jump to those findings.
Critical Critical · 5
Critical ⚡ Actively exploited1. PHP 8.4.26 is vulnerable to PHP2Shell — server takeover without a password
Why it is dangerous right now: Since late October 2026 bots have been mass-exploiting PHP2Shell: they run their own code on the server without a password and steal the customer database. CISA lists it as actively exploited.
What we found
- Software
- PHP
- Component
- php
- Version
- 8.4.26
- Fixed in version
- 8.4.27
- Vulnerabilities
- CVE-2026-109618, CVE-2026-109619
- Signal
- X-Powered-By: PHP/8.4.26
- Page
- https://shop.example.com/
- Note
- Version taken from the X-Powered-By header; distribution builds may carry backported fixes
- Affected pages
- 1
- Confidence
- likely (please confirm)
Steps to fix
- Update PHP to the fixed release of your branch: 8.4.27, 8.3.36, 8.2.35 or 8.5.12 (for you: 8.4.27 or newer). On shared hosting this is the “PHP version” setting; on your own server, update the php package.
- PHP 8.1 or older gets no fix: move to 8.3/8.4 and enable a WAF (e.g. Cloudflare) with PHP2Shell rules until then.
- Hide the PHP version: set expose_php = Off in php.ini.
- Look for signs of compromise: unknown .php files in upload folders, new admin users, php processes spawning sh, curl or wget.
- How to check: curl -sI https://shop.example.com/ | grep -i x-powered-by must show no PHP version, and php -v on the server must show the fixed release.
Estimated effort: 30–90 minutes; confirm with your provider
Sources: www.cisa.gov/news-events/alerts/2026/10/21/critical-vulnerabilities-php-require-immediate-patching · www.bleepingcomputer.com/news/security/php2shell-security-flaws-now-sucessfully-exploited-in-the-wild/
Technical details
{
"product": "PHP",
"name": "php",
"version": "8.4.26",
"fixedIn": "8.4.27",
"cves": [
"CVE-2026-109618",
"CVE-2026-109619"
],
"signal": "X-Powered-By: PHP/8.4.26",
"url": "https://shop.example.com/",
"note": "Version taken from the X-Powered-By header; distribution builds may carry backported fixes",
"urls": [
"https://shop.example.com/"
],
"count": 1,
"confidence": "probable"
} Critical ⚡ Actively exploited2. The .env file with database, mail and payment passwords is public
Why it is dangerous right now: Bots probe for exposed .env and .git files around the clock: the EmeraldWhale campaign alone harvested over 15,000 cloud credentials this way, and the scanning continues.
What we found
- Path
- /.env
- Server response
- HTTP 200
- Confidence
- confirmed
Steps to fix
- Block hidden files right away. nginx: location ~ /\.(?!well-known) { deny all; }
- Apache (.htaccess): <FilesMatch "^\."> Require all denied </FilesMatch>
- Move .env outside the web root so the web server cannot serve it at all.
- Rotate EVERY password and key in the file: database, mail, payment gateway, API keys. Assume they are already stolen.
- Search the access logs for GET /.env to see when it was downloaded.
- How to check: curl -s https://shop.example.com/.env | head -c 200 must not show lines like APP_KEY= or DB_PASSWORD=. The status code alone proves nothing: many sites return 200 for any URL.
Estimated effort: 30–90 minutes; confirm with your provider
Sources: www.sysdig.com/blog/emeraldwhale · honeylabs.net/blog/credential-scraping-env-and-git
Technical details
{
"path": "/.env",
"status": 200,
"confidence": "exact"
} Critical ⚡ Actively exploited3. The .git folder with the site source code is public
Why it is dangerous right now: Attackers download the whole code base, secrets included, from an exposed .git in minutes — this is how the EmeraldWhale campaign stole over 15,000 cloud credentials.
What we found
- Path
- /.git/config
- Server response
- HTTP 200
- Confidence
- confirmed
Steps to fix
- Block .git. nginx: location ~ /\.git { deny all; }
- Apache (.htaccess): RedirectMatch 404 /\.git
- Deploy without the .git folder (git archive, a CI build or rsync --exclude .git).
- Rotate any password or key that was ever committed — the commit history leaked too.
- How to check: curl -s https://shop.example.com/.git/config | head -c 200 must not show a [core] line. The status code alone proves nothing: many sites return 200 for any URL.
Estimated effort: 30–90 minutes; confirm with your provider
Sources: www.sysdig.com/blog/emeraldwhale · honeylabs.net/blog/credential-scraping-env-and-git
Technical details
{
"path": "/.git/config",
"status": 200,
"confidence": "exact"
} Critical ⚡ Actively exploited4. Database or payment secret key (Supabase service_role) is visible in site code
Why it is dangerous right now: This key bypasses every access rule: any visitor can read and change the whole database — orders, customers, passwords. A similar mistake (CVE-2025-48757) exposed data in 170+ apps built with Lovable.
What we found
- Service
- Supabase service_role
- Key fragment (redacted)
- eyJhbGciOi…[219 chars, redacted]
- Found in
- https://shop.example.com/app/assets/index-8c1d2f.js
- Confidence
- likely (please confirm)
Steps to fix
- Rotate the key now: Supabase — Project Settings → API Keys (service_role / secret); Stripe — Developers → API keys. Treat the old key as stolen.
- Use only the public key (anon / publishable) in the browser; admin operations belong on the server (Edge Functions, an API route).
- Enable row level security on every table: alter table <table> enable row level security; and write policies for who sees which rows.
- Review database and payment logs for requests and exports you did not make.
- How to check: the site JS files must not contain service_role, sb_secret_ or sk_live_.
Estimated effort: 30–90 minutes; confirm with your provider
Sources: mattpalmer.io/posts/2025/05/statement-on-CVE-2025-48757/ · supabase.com/docs/guides/database/postgres/row-level-security · escape.tech/blog/methodology-how-we-discovered-vulnerabilities-apps-built-with-vibe-coding/
Technical details
{
"provider": "Supabase service_role",
"keyPreview": "eyJhbGciOi…[219 chars, redacted]",
"source": "https://shop.example.com/app/assets/index-8c1d2f.js",
"confidence": "probable"
} Critical ⚡ Actively exploited5. AI service secret key (OpenAI) is visible in site code
Why it is dangerous right now: Sites and chatbots built with AI tools often ship the key inside JavaScript; bots harvest such keys automatically and drain the balance within hours. Escape found 400+ exposed secrets across 5,600 such apps.
What we found
- Service
- OpenAI
- Key fragment (redacted)
- sk-proj-Xa…[164 chars, redacted]
- Found in
- https://shop.example.com/wp-content/plugins/shop-ai-assistant/assets/chat.js
- Confidence
- likely (please confirm)
Steps to fix
- Revoke the key now in the provider console and issue a new one — treat the old one as stolen.
- Set a spending limit in the provider console.
- Move AI calls to the server (a server function or API route): keep the new key only in server environment variables, never in the browser.
- Check the provider usage log for requests and charges you did not make.
- How to check: after rebuilding, search the site JS files for the key prefix (e.g. sk-) — there must be no match.
Estimated effort: 30–90 minutes; confirm with your provider
Sources: escape.tech/blog/methodology-how-we-discovered-vulnerabilities-apps-built-with-vibe-coding/
Technical details
{
"provider": "OpenAI",
"keyPreview": "sk-proj-Xa…[164 chars, redacted]",
"source": "https://shop.example.com/wp-content/plugins/shop-ai-assistant/assets/chat.js",
"confidence": "probable"
}High High · 3
High ⚡ Actively exploited6. Ninja Forms plugin 3.15.2: the flaw is already used to hack sites (CVE-2026-94504)
Why it is dangerous right now: In October 2026 this Ninja Forms flaw is being mass-exploited: an attacker submits a form entry carrying malicious code, and when an admin opens that submission in the WordPress dashboard the code runs with admin rights — enough to create hidden admin accounts and plant a backdoor. Fixed in 3.15.4.
What we found
- Software
- WordPress plugin ninja-forms
- Component
- ninja-forms
- Version
- 3.15.2
- Found in
- WPVulnerability
- Total vulnerabilities
- 1
- Vulnerabilities
- CVE-2026-94504
- Fixed in version
- 3.15.4
- Signal
- readme.txt Stable tag 3.15.2
- Confidence
- confirmed
- Main vulnerability
- CVE-2026-94504
Steps to fix
- Until you update, do not open new entries in Ninja Forms → Submissions.
- Update the plugin to 3.15.4 or newer: Dashboard → Plugins → “Update now”. If no update exists, deactivate it.
- Open Users → Administrators: delete unknown accounts and reset every admin password.
- Check the plugin list and wp-content/uploads for unknown files; restore from a clean backup if you see signs of compromise.
- Turn on auto-updates for this plugin and two-factor login for admins.
- How to check: the Plugins page shows the fixed version or newer, and a new SiteCheck scan no longer lists this finding.
Estimated effort: 30–90 minutes; confirm with your provider
Sources: www.bleepingcomputer.com/news/security/ninja-forms-plugin-flaw-exploited-to-hack-wordpress-sites/
Technical details
{
"product": "WordPress plugin ninja-forms",
"name": "ninja-forms",
"version": "3.15.2",
"source": "WPVulnerability",
"total": 1,
"cves": [
"CVE-2026-94504"
],
"fixedIn": "3.15.4",
"signal": "readme.txt Stable tag 3.15.2",
"confidence": "exact",
"cveId": "CVE-2026-94504",
"cvss": null,
"reference": "https://nvd.nist.gov/vuln/detail/CVE-2026-94504"
} High7. Site calls an AI service directly from the browser
What we found
- API addresses
- OpenAI
- Found in
- https://shop.example.com/wp-content/plugins/shop-ai-assistant/assets/chat.js
- Confidence
- likely (please confirm)
Steps to fix
- Route AI requests through your own server: keep the key there, limit what data is sent and filter personal data before it leaves your site.
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"endpoints": [
"OpenAI"
],
"source": "https://shop.example.com/wp-content/plugins/shop-ai-assistant/assets/chat.js",
"confidence": "probable"
} High8. HTTP does not redirect to HTTPS
What we found
- Address after redirect
- http://shop.example.com/
- Server response
- HTTP 200
- Affected pages
- 1
- Confidence
- confirmed
Steps to fix
- Why: Visitors who type the address without https stay on an insecure connection.
- Add a permanent 301 redirect from every HTTP URL to HTTPS (example below).
- nginx (server { listen 80; }): return 301 https://$host$request_uri;
- Apache: RewriteEngine On / RewriteCond %{HTTPS} off / RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
- How to check: curl -sI http://shop.example.com/ | grep -i location
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"finalUrl": "http://shop.example.com/",
"status": 200,
"urls": [
"http://shop.example.com/"
],
"count": 1,
"confidence": "exact"
}Medium Medium · 8
Medium9. Missing Content-Security-Policy header
What we found
- Page
- https://shop.example.com/
- Header
- content-security-policy
- Pages
- https://shop.example.com/, https://shop.example.com/catalog/, https://shop.example.com/cart/
- Affected pages
- 3
- Confidence
- confirmed
Steps to fix
- Why: CSP lets the browser run scripts only from your own and trusted domains — the main barrier against injected code (XSS, a hijacked analytics or chat script).
- List the domains the site loads scripts, styles and frames from (analytics, chat, CDN): DevTools → Network.
- Enable the policy as Content-Security-Policy-Report-Only (example below), watch violations in the browser console for 1–2 weeks and extend the domain list.
- When there are no violations, rename the header to Content-Security-Policy.
- nginx (server {}): add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' https://<script-domains>; object-src 'none'; base-uri 'self'; frame-ancestors 'self'" always;
- Apache (.htaccess): Header always set Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' https://<script-domains>; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"
- How to check: curl -sI https://shop.example.com/ | grep -i content-security-policy
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"url": "https://shop.example.com/",
"header": "content-security-policy",
"urls": [
"https://shop.example.com/",
"https://shop.example.com/catalog/",
"https://shop.example.com/cart/"
],
"count": 3,
"confidence": "exact"
} Medium10. Missing Strict-Transport-Security header
What we found
- Page
- https://shop.example.com/
- Header
- strict-transport-security
- Pages
- https://shop.example.com/, https://shop.example.com/catalog/, https://shop.example.com/cart/
- Affected pages
- 3
- Confidence
- confirmed
Steps to fix
- Why: HSTS makes browsers always use HTTPS and prevents interception of the first HTTP request on public Wi‑Fi.
- Make sure the site and all subdomains work over HTTPS.
- Start with max-age=86400 and raise it to 31536000 after a week without issues (example below).
- nginx (server {}): add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
- Apache (.htaccess): Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
- How to check: curl -sI https://shop.example.com/ | grep -i strict-transport-security
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"url": "https://shop.example.com/",
"header": "strict-transport-security",
"urls": [
"https://shop.example.com/",
"https://shop.example.com/catalog/",
"https://shop.example.com/cart/"
],
"count": 3,
"confidence": "exact"
} Medium11. Missing X-Content-Type-Options header
What we found
- Page
- https://shop.example.com/
- Header
- x-content-type-options
- Pages
- https://shop.example.com/, https://shop.example.com/catalog/, https://shop.example.com/cart/
- Affected pages
- 3
- Confidence
- confirmed
Steps to fix
- Why: Without nosniff the browser may guess a file type and run an uploaded file as a script.
- Send X-Content-Type-Options: nosniff on every response.
- nginx (server {}): add_header X-Content-Type-Options "nosniff" always;
- Apache (.htaccess): Header always set X-Content-Type-Options "nosniff"
- How to check: curl -sI https://shop.example.com/ | grep -i x-content-type-options
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"url": "https://shop.example.com/",
"header": "x-content-type-options",
"urls": [
"https://shop.example.com/",
"https://shop.example.com/catalog/",
"https://shop.example.com/cart/"
],
"count": 3,
"confidence": "exact"
} Medium12. No protection against framing (X-Frame-Options / frame-ancestors)
What we found
- Page
- https://shop.example.com/
- Header
- x-frame-options or CSP frame-ancestors
- Affected pages
- 1
- Confidence
- confirmed
Steps to fix
- Why: Without it the site can be framed by another page and visitors tricked into clicking your buttons (clickjacking).
- Send X-Frame-Options: SAMEORIGIN or add frame-ancestors 'self' to Content-Security-Policy.
- nginx (server {}): add_header X-Frame-Options "SAMEORIGIN" always;
- Apache (.htaccess): Header always set X-Frame-Options "SAMEORIGIN"
- How to check: curl -sI https://shop.example.com/ | grep -i x-frame-options
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"url": "https://shop.example.com/",
"header": "x-frame-options or CSP frame-ancestors",
"urls": [
"https://shop.example.com/"
],
"count": 1,
"confidence": "exact"
} Medium13. Cookies without httponly, samesite flags: woocommerce_session
What we found
- Page
- https://shop.example.com/
- Missing
- httponly, samesite
- Cookie
- woocommerce_session
- Cookies
- woocommerce_session
- Affected pages
- 1
- Confidence
- confirmed
Steps to fix
- Why: Without these flags a session cookie can travel over an insecure connection or be read by an injected script.
- Add the missing flags (httponly, samesite) to cookies woocommerce_session.
- If a third-party service sets the cookie (analytics, chat, CDN), configure the flags there — check the cookie domain in DevTools → Application → Cookies.
- PHP: session_set_cookie_params(['secure' => true, 'httponly' => true, 'samesite' => 'Lax']);
- nginx ≥ 1.19.3 (proxy): proxy_cookie_flags ~ secure httponly samesite=lax;
- How to check: curl -sI https://shop.example.com/ | grep -i set-cookie
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"url": "https://shop.example.com/",
"missing": [
"httponly",
"samesite"
],
"cookie": "woocommerce_session",
"urls": [
"https://shop.example.com/"
],
"cookies": [
"woocommerce_session"
],
"count": 1,
"confidence": "exact"
} Medium14. No DMARC record for shop.example.com
What we found
- Domain
- _dmarc.shop.example.com
- Confidence
- confirmed
Steps to fix
- Why: DMARC tells mail services what to do with spoofed mail from your domain and sends you reports.
- Publish a record with p=none and a report address (example below).
- After 2–4 weeks, if reports show only your servers, move to p=quarantine.
- _dmarc.shop.example.com. TXT "v=DMARC1; p=none; rua=mailto:[email protected]"
- How to check: dig +short TXT _dmarc.shop.example.com
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"hostname": "_dmarc.shop.example.com",
"confidence": "exact"
} Medium15. No SPF record for shop.example.com
What we found
- Domain
- shop.example.com
- Confidence
- confirmed
Steps to fix
- Why: Without SPF, mail from your domain is easy to spoof and real mail lands in spam more often.
- Get your mail provider’s include (Google: _spf.google.com, Microsoft: spf.protection.outlook.com).
- Publish a single TXT record (example below).
- shop.example.com. TXT "v=spf1 include:_spf.yandex.net ~all"
- How to check: dig +short TXT shop.example.com
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"hostname": "shop.example.com",
"confidence": "exact"
} Medium16. Known vulnerabilities in jquery 1.12.4: CVE-2020-11022
What we found
- Software
- jquery
- Version
- 1.12.4
- Confidence
- confirmed
- Main vulnerability
- CVE-2020-11022
- Severity score (CVSS)
- 6.1
Steps to fix
- Why: Vulnerabilities are published for this version — automated scanners target such sites first.
- Compare the installed jquery 1.12.4 version with the affected range (CVE-2020-11022).
- Back up and update jquery 1.12.4 to a fixed version.
- How to check: https://nvd.nist.gov/vuln/detail/CVE-2020-11022
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"product": "jquery",
"version": "1.12.4",
"confidence": "exact",
"cveId": "CVE-2020-11022",
"cvss": 6.1,
"reference": "https://nvd.nist.gov/vuln/detail/CVE-2020-11022"
}Low Low and informational · 5
Low17. Server header reveals software and version: “Apache/2.4.58 (Ubuntu)”
What we found
- Header
- server
- Value
- Apache/2.4.58 (Ubuntu)
- Confidence
- confirmed
Steps to fix
- Why: An exact server version helps automated scanners pick known vulnerabilities.
- Hide the version in web server responses (example below) and update the server if it is outdated.
- nginx (http {}): server_tokens off;
- Apache: ServerTokens Prod и ServerSignature Off
- How to check: curl -sI https://shop.example.com/ | grep -i '^server'
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"header": "server",
"value": "Apache/2.4.58 (Ubuntu)",
"confidence": "exact"
} Low18. X-Powered-By header reveals the platform: “PHP/8.4.26”
What we found
- Header
- x-powered-by
- Value
- PHP/8.4.26
- Confidence
- confirmed
Steps to fix
- Why: Platform name and version make it easier to pick known vulnerabilities.
- Turn the header off in the platform or hide it in the web server (examples below).
- PHP (php.ini): expose_php = Off
- nginx: fastcgi_hide_header X-Powered-By; proxy_hide_header X-Powered-By;
- Express: app.disable('x-powered-by')
- How to check: curl -sI https://shop.example.com/ | grep -i x-powered-by
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"header": "x-powered-by",
"value": "PHP/8.4.26",
"confidence": "exact"
} Low19. No /.well-known/security.txt file
What we found
- Server response
- HTTP 404
- Confidence
- confirmed
Steps to fix
- Why: It tells researchers where to report a vulnerability, so you hear about problems before attackers exploit them.
- Create /.well-known/security.txt with a contact and expiry date (example below).
- Contact: mailto:[email protected]
- Expires: 2027-12-31T23:59:59.000Z
- How to check: curl -s https://shop.example.com/.well-known/security.txt
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"status": 404,
"confidence": "exact"
} Low20. No CAA record for shop.example.com
What we found
- Domain
- shop.example.com
- Confidence
- confirmed
Steps to fix
- Why: CAA allows only chosen certificate authorities to issue certificates for the domain.
- Add a CAA record for the CA that issues your certificate (Let’s Encrypt example below).
- shop.example.com. CAA 0 issue "letsencrypt.org"
- How to check: dig +short CAA shop.example.com
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"hostname": "shop.example.com",
"confidence": "exact"
} Info21. CMS public signal
What we found
- Page
- https://shop.example.com/
- Software
- WordPress
- Affected pages
- 1
- Confidence
- confirmed
Steps to fix
- Confirm the CMS and keep its core, themes and plugins updated using the official updater.
Estimated effort: 30–90 minutes; confirm with your provider
Technical details
{
"url": "https://shop.example.com/",
"product": "WordPress",
"urls": [
"https://shop.example.com/"
],
"count": 1,
"confidence": "exact"
}NVD
This product uses the NVD API but is not endorsed or certified by the NVD.