Web application
Web application baseline scan
Daily passive scan against the running site for OWASP Top 10 exposure.
Healthy
0 high · 0 medium · 2 low · 4 excluded
Checked 7/30/2026, 3:18:46 AM · Source: Continuous integration
Daily OWASP ZAP baseline scan against the production site. Passive checks only (spider + inspect responses); no active payloads or fuzzing. 4 finding(s) deliberately excluded with documented rationale (see .zapignore.json or the findings list, severity=info).
What this check means
An automated scan runs daily, performing the kind of inspection a security analyst would: spider the site, capture every response, and check for the patterns associated with the OWASP Top 10 vulnerability categories. Strictly passive — no payload injection, no fuzzing, safe to run against production.
Documented exclusions (19)
19 finding types are deliberately not actioned here. Grouped by reason below — we publish them so the trade-offs and false-positive suppressions are visible and reviewable, not hidden.
Trade-offs · 3
Recommended setting would break legitimate functionality. We accept the finding instead.
CSP: script-src unsafe-inline + wasm-unsafe-eval
Two sub-rules under ZAP plugin 10055. (1) `unsafe-inline`: same trade-off as the Venom CSP exclusion — Next.js's React hydration requires inline `<script>` tags, and eliminating `unsafe-inline` requires a per-request nonce-based CSP threaded through every render path (a substantial refactor that also has to coexist with our 6 third-party scripts: Cloudflare Insights, Sentry, Auth0, Google Ads, Microsoft Clarity, Google Analytics). (2) `wasm-unsafe-eval`: required in production for client-side PDF export (@react-pdf/renderer compiles a WASM font/layout module via WebAssembly.instantiate). This is the *narrow modern directive* that permits WASM compile/instantiate ONLY — it does NOT permit JS eval(), new Function(), setTimeout(string), etc. Removing it breaks PDF export with `CompileError: WebAssembly.instantiate(): ... 'unsafe-eval' is not an allowed source`. The full `unsafe-eval` directive remains absent from the production CSP.
CSP: style-src unsafe-inline
Tailwind CSS v4 + shadcn/ui inject runtime styles via inline `<style>` tags during hydration. Same nonce-based-CSP refactor would be needed to eliminate this. Tracked separately.
Cross-Origin-Embedder-Policy Header Missing or Invalid
Same as Venom COEP exclusion. Setting `require-corp` breaks the Auth0 universal-login iframe, Google Ads creative iframes, and Cloudflare Turnstile. The hardening (cross-origin isolation for SharedArrayBuffer / high-resolution timers) is irrelevant — we don't use either.
Handled at the edge · 2
Path is blocked at the Cloudflare WAF before reaching our application.
Honeypot: dotenv probe
Blocked at the Cloudflare WAF before reaching the worker. ZAP's view of this URL is the WAF's branded block page (which has its own CSP applied via the /errors/* Transform Rule). Findings against the WAF block page are not actionable in our app.
Honeypot: dotgit probe
Blocked at the Cloudflare WAF. See /.env entry — same rationale.
False positives · 7
Scanner pattern-matched content that isn't actually a vulnerability — code samples, article text, framework markers.
Missing Anti-clickjacking Header on Cloudflare /cdn-cgi/* endpoints
/cdn-cgi/* is the Cloudflare-managed reserved path used for challenges, bot-detection scripts, and edge-internal endpoints. These responses are served by the Cloudflare edge BEFORE our worker runs — our middleware.ts (which sets X-Frame-Options: DENY and frame-ancestors 'none' on every response) cannot attach headers to them. Cloudflare's challenge surface intentionally needs to be embeddable for the JS challenge to render in some flows. Headers on /cdn-cgi/content?id=... are Cloudflare's responsibility, not ours. All real application paths return both X-Frame-Options: DENY and CSP frame-ancestors 'none' (verified in middleware.ts). Closes #1067. Reviewed 2026-05-07.
Source Code Disclosure - SQL
False positive on a documentation site. Pages like /comparisons/mysql-vs-postgresql, /code/database-connection-pooling, /architectures, etc. legitimately render SQL examples inside <pre>/<code> blocks as part of the article content. ZAP pattern-matches the SQL keywords and flags them as 'disclosure'. Real source code is in the repo, not exposed in the rendered HTML.
Information Disclosure - Suspicious Comments
Next.js's React Server Components emit boundary markers as HTML comments (e.g. <!--$--> <!--/$-->) on every page. ZAP matches these against a list of suspicious comment keywords. They contain no real disclosure — they're framework-internal hydration markers.
Timestamp Disclosure - Unix
False positive on article pages. /frameworks/<slug>, /hiring, /questions and similar render publication dates and 'updated at' timestamps in their content as integer seconds-since-epoch. These are public publication metadata, not internal timing leaks.
Dangerous JS Functions
False positive on documentation pages. /code/rate-limiting-redis and /code render JavaScript code samples that *demonstrate* eval() / Function() usage as part of teaching the topic. The page itself doesn't execute these — they're string content inside <pre><code> blocks.
Information Disclosure - Debug Error Messages
False positive on /code/* and /metrics/* documentation pages. ZAP's pattern matcher flags pages that contain words like 'error', 'exception', 'stack trace' in their text content. These are content articles ABOUT error handling and observability — they discuss the words, they don't leak runtime stacks.
Application Error Disclosure
Same as 10023 — false positive on /metrics and /metrics/error-rate, content pages that describe error-rate dashboards and SRE patterns. The rendered HTML contains the word 'error' in normal prose; no stacks or internal paths are exposed.
Informational · 7
Scanner notes that the scanner itself classifies as informational, not actionable.
Modern Web Application
Informational only. ZAP notes the site is a SPA / uses modern JS — not a vulnerability.
Non-Storable Content
Informational only. ZAP notes that authenticated/dynamic responses don't ship Cache-Control: public — which is the correct behaviour for those paths (admin, api). Not a finding.
Retrieved from Cache
Informational only — ZAP notes responses came from cache.
Re-examine Cache-control Directives
Informational. ZAP suggests we verify our cache directives. We have intentional Cache-Control values per route class (public pages cacheable, /admin/* no-store, /robots.txt + /sitemap.xml short-TTL). Reviewed.
Storable and Cacheable Content
Informational only — confirms cacheable content is correctly marked cacheable.
Storable but Non-Cacheable Content
Informational only.
CSP: Notices
Informational notice from CSP audit, not a finding.
Recent runs
| When | Result | Source | |
|---|---|---|---|
| 7/30/2026, 3:18:46 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/29/2026, 3:16:05 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/28/2026, 3:17:46 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/27/2026, 3:19:12 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/26/2026, 3:18:21 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/25/2026, 3:17:25 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/24/2026, 3:17:50 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/23/2026, 3:17:22 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/22/2026, 3:19:12 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/21/2026, 3:18:50 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/20/2026, 3:19:41 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/19/2026, 3:18:43 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/18/2026, 3:16:45 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/17/2026, 3:17:32 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/17/2026, 12:13:46 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/16/2026, 3:17:34 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/15/2026, 3:17:43 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/14/2026, 3:16:18 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/13/2026, 3:19:46 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/12/2026, 3:17:58 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/11/2026, 3:17:28 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/10/2026, 3:19:33 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/9/2026, 3:21:04 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/8/2026, 3:18:04 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/7/2026, 3:21:22 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/6/2026, 3:22:27 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/5/2026, 3:20:13 AM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/4/2026, 12:25:12 PM | 0 high · 0 medium · 2 low · 4 excluded | Continuous integration | |
| 7/4/2026, 3:09:10 AM | scan output missing | Continuous integration | |
| 7/3/2026, 6:13:37 AM | scan output missing | Continuous integration |
Need additional detail (sanitised report, supporting evidence)? security@theartofcto.com