Skip to content

Security: eSolia/esolia-2025

SECURITY.md

Security Policy

Reporting a Vulnerability

If you discover a security vulnerability in this project, please report it responsibly.

Contact: Submit a report through our contact form with "Security Vulnerability" in the subject line.

Response: We aim to acknowledge reports within 24 hours and provide status updates as the investigation progresses.

Please include:

  • Description of the vulnerability
  • Steps to reproduce
  • Potential impact assessment
  • Suggested fix (if applicable)

We will not pursue legal action against researchers who report vulnerabilities in good faith.

Security Architecture

graph TB
    subgraph "Edge Protection (Cloudflare Pro)"
        WAF["WAF Rules"]
        DDOS["DDoS Mitigation"]
        BOT["Bot Management"]
        TUR["Turnstile (CAPTCHA)"]
    end

    subgraph "Transport"
        HSTS["HSTS<br/>(max-age=31536000, includeSubDomains, preload)"]
        TLS["TLS 1.3"]
    end

    subgraph "Application (SvelteKit + Workers)"
        CSP["Content Security Policy"]
        XFO["X-Frame-Options: DENY"]
        XCTO["X-Content-Type-Options: nosniff"]
        RP["Referrer-Policy: strict-origin-when-cross-origin"]
        PP["Permissions-Policy<br/>(camera, microphone, geolocation disabled)"]
    end

    subgraph "Code-Level Defenses"
        SAN["HTML Sanitization<br/>(all @html wrapped)"]
        ZOD["Zod Validation<br/>(frontmatter, API input)"]
        PARAM["Parameterized Queries<br/>(D1 .bind())"]
        LINT["Custom ESLint Rules<br/>(4 backpressure rules)"]
    end

    WAF --> HSTS --> CSP --> SAN
Loading

Security Headers

All responses include the following headers, set in hooks.server.ts:

Header Value
Strict-Transport-Security max-age=31536000; includeSubDomains; preload
X-Content-Type-Options nosniff
X-Frame-Options DENY
Referrer-Policy strict-origin-when-cross-origin
Permissions-Policy autoplay=(self), camera=(), microphone=(), payment=(), geolocation=()
Content-Security-Policy Restricts script, style, font, img, media, connect, and frame sources

Code-Level Protections

XSS Prevention

All {@html} usage is enforced by the custom esolia/no-raw-html ESLint rule to pass through one of three sanitization functions:

  • sanitizeHtml() — general HTML sanitization
  • sanitizeMarkdownHtml() — markdown-rendered HTML with allowlisted tags
  • jsonLdScript() — structured data injection (escapes </script> sequences)

Injection Prevention

  • SQL: All D1 queries use parameterized .bind() — never string interpolation
  • Input: Zod safeParse() validates all content frontmatter and API inputs
  • Platform leaks: esolia/no-binding-leak rule prevents returning platform.env from load functions

Bot Protection

Contact form submissions are protected by Cloudflare Turnstile with server-side token verification.

Dependency Management

  • pnpm audit runs as part of the verification pipeline
  • Security-critical dependency overrides applied in package.json (e.g., cookie >= 0.7.0)
  • Lockfile integrity verified via --frozen-lockfile in CI

Infrastructure

Component Protection
Cloudflare Workers Isolated V8 runtime, no shared state between requests
Cloudflare D1 SQLite-based, parameterized queries only
Static Assets Served via Workers Assets with immutable cache headers
Secrets Managed via wrangler secret — never in source
CI/CD GitHub Actions with pinned Node version and frozen lockfile

Supported Versions

Only the latest deployment on main is actively maintained and receives security updates. This is a continuously deployed project — there are no versioned releases.

There aren’t any published security advisories