Active

Cybersecurity Policy

Legal document with structured content including metadata, citations, and references. Use heading navigation to jump between sections or the table of contents for overview.

Abstract

Discover david-osipov.vision's Zero Trust cybersecurity framework: DNSSEC, CSP, and automated defenses. Learn how spec-driven SDLC ensures unbreakable security.

1. My Security Philosophy: A Zero Trust Fortress

This Cybersecurity Policy provides a transparent, technical specification of the security posture for david-osipov.vision. My security model is built on a Zero Trust philosophy and implemented through Constitution-Driven Development. Every component is designed with the assumption that other parts of the system could be compromised. Security is not an ad-hoc feature; it is the non-negotiable foundation of this project, governed by a formal internal document: The Official Security & Engineering Constitution.

My core tenets are:

  • Secure by Default: The application’s default state is its most secure state.
  • Defense in Depth: I layer multiple, independent, and verifiable security controls.
  • Performance as a Security Feature: A performant, non-blocking UI mitigates timing attacks and improves the user experience, which in turn encourages safer user behavior.
  • Verifiable Security: A security control is considered non-existent until it is validated by automated, adversarial testing within the CI/CD pipeline.

2. Architectural Security: An Inherently Secure Foundation

2.1. Static Site Architecture

david-osipov.vision is a fully static website. This architectural choice eliminates entire classes of vulnerabilities by design—including RCE and SQLi—as it has no server-side interpreters or database connections.

2.2. Infrastructure Hardening with Cloudflare

The website is hosted on Cloudflare Pages, which provides critical edge security:

  • Global DDoS Mitigation & WAF: Malicious traffic is filtered at the network edge by Cloudflare’s WAF.
  • Managed & Secure TLS: All content is served exclusively over HTTPS. TLS certificate management is handled by Cloudflare, prioritizing modern, secure ciphers like TLS 1.3.

2.3. Domain & DNS-Level Security

  • DNSSEC (Domain Name System Security Extensions): The david-osipov.vision domain is protected by DNSSEC. This cryptographically signs the DNS records, preventing DNS spoofing and cache poisoning attacks.
  • CAA (Certification Authority Authorization): I enforce a strict CAA policy via DNS records, explicitly specifying which Certificate Authorities are permitted to issue certificates for the domain, thereby preventing mis-issuance.

3. Application-Level Security: Browser-Enforced Protections

3.1. Automated Hash-Based Content Security Policy (CSP)

I enforce a strict, hash-based CSP as the primary defense against Cross-Site Scripting (XSS). This system is fully automated to eliminate 'unsafe-inline' and guarantee that the policy remains synchronized with the deployed code.

  • Mechanism: During the build process, a custom Astro integration (csp-hash-collector.mjs) scans all generated HTML files, computes cryptographic hashes (sha-384 for script/style blocks, sha-256 for inline style attributes) of every legitimate inline asset, and writes them to a canonical report file (dist/csp-hashes.json).
  • Enforcement: A separate script (apply-csp-hashes.mjs) then uses this report to update the Content-Security-Policy header in the deployment configuration (public/_headers).
  • Verification: The CI pipeline runs a verification script (verify-csp-hashes.mjs) that fails the build if the headers ever drift from the generated report, ensuring the policy is always accurate.

3.2. Mandatory Trusted Types

To make the CSP non-bypassable and to prevent DOM-based XSS, Trusted Types are enforced via the CSP directive require-trusted-types-for 'script'.

  • Mechanism: This prevents dangerous DOM sinks (e.g., .innerHTML) from accepting simple strings. Instead, they require a special TrustedHTML object.
  • Implementation: The app-policy is the sole mechanism permitted to create these objects. It uses a heavily configured isomorphic-dompurify instance with strict allowlists for tags and attributes, explicitly blocking dangerous elements and all on* event handlers.

3.3. Hardened HTTP Headers & Cross-Origin Isolation

  • Core Security Headers: Strict-Transport-Security (with preload), X-Content-Type-Options: nosniff, Referrer-Policy, and a restrictive Permissions-Policy.
  • Cross-Origin Isolation: To protect against speculative execution side-channel attacks like Spectre, a Cross-Origin Isolated environment is established by serving Cross-Origin-Opener-Policy (COOP): same-origin and Cross-Origin-Embedder-Policy (COEP): credentialless.

3.4. Third-Party Code & SVG Isolation

  • Analytics Pipeline: Third-party analytics code (e.g., Google Analytics) is never executed directly on the page. Instead, it operates within a sandboxed Web Worker, isolating its network requests and preventing it from accessing the main DOM, thus adhering to the Principle of Least Privilege.
  • SVG Security: The project employs a two-pronged SVG security strategy:
    1. Local Icons: All local icons undergo a build-time sanitization pipeline that uses DOMPurify to strip all scripts, event handlers, and unsafe tags, ensuring only safe, static vector data is rendered.
    2. Dynamic Badges: Dynamic SVGs (e.g., from shields.io) are routed through a hardened server-side proxy (/api/safe-svg) that validates, sanitizes, and caches the content before serving it, mitigating supply-chain risks.

3.5. Encrypted Contact Form System (Client-side E2E Encryption)

As a concrete example of the project’s security-first engineering, I operate an encrypted contact form system that performs end-to-end encryption of message content entirely in the user’s browser before submission. This system demonstrates several of the architecture’s defensive patterns (defense-in-depth, Trusted Types, and strict CSP) and integrates with vendor tooling in a privacy-preserving way.

Key properties:

  • Client-side encryption: The message body is encrypted in the browser using OpenPGP (OpenPGP.js) and the recipient’s public key. Only the ciphertext is transmitted and stored by the form submission endpoint.
  • Selective plaintext metadata: For compatibility with standard email delivery, sender metadata (name, email, subject) remain plaintext to enable routing; only message content is encrypted.
  • Public key discovery & verification: The recipient’s PGP public key is retrieved from a Web Key Directory (WKD) hosted at openpgpkey.david-osipov.vision. The client verifies the key’s cryptographic fingerprint against a hardcoded expected value and computes a SHA-512 hash of the armored key as an advisory integrity check.
  • hCaptcha integration: A client-side hCaptcha challenge prevents automated submissions; server-side verification is performed by the form backend (Web3Forms) for defense-in-depth.
  • Transport & delivery: Encrypted payloads are POSTed to Web3Forms (access key managed by site configuration). Web3Forms performs captcha verification and forwards the message (ciphertext) to the recipient’s email — only the recipient’s private key can decrypt.
  • Trusted UI & sanitization: All DOM updates, error messages, and the encryption notice use Trusted Types and textContent to eliminate XSS vectors; public-facing strings are validated by the content schema and i18n system.

Security verification values (for manual and automated audits):

PGP key fingerprint: D3FC4983E500AC3F7F136EB80E55C4A47454E82E
SHA-512 (armored key): E63AE1C82DA6C6022A6362CEAA6FE8AE6EE094A8F4A56F92069973DB290E885640D645CA6D796411830724B42BBE11D889EBB6BDBCB4A82999752EE69AF9A877

Operational notes:

  • The client enforces a fatal failure if fingerprint verification fails, preventing encryption with an unexpected key. SHA-512 mismatch is treated as an advisory warning (logged) to provide defense-in-depth without false-positive denials.
  • The public key is pre-fetched during page load and cached in-memory to reduce latency during submission. An AbortController governs all network activity so navigation or teardown always cancels outstanding operations.
  • The system adheres to the project’s Security Constitution: no use of Math.random(), Trusted Types for DOM sinks, CSP-compliant third-party script loading (nonce’d), and explicit cleanup via destroy() methods.

4. Secure Software Development Lifecycle (SDLC)

Security is integrated into every phase of the development process, governed by the internal constitution and enforced by the CI/CD pipeline (.github/workflows/bastion-gates.yml).

4.1. Build-Time Security & Hardening

Security is shifted left and integrated directly into the Astro build process:

  • Strongly-Typed Content Collections: Using Zod schemas in src/content/config.ts, I enforce a strict data structure for all content. This prevents data integrity issues and mitigates the risk of injection vulnerabilities at the source.
  • Build-Time Content Processing: Custom Remark plugins like remark-figure-captions and remark-toc-data.mjs process content during the build. This shifts complex data parsing from the client (runtime) to the trusted build-time environment, reducing the client-side attack surface and improving performance.
  • Static Output Sanitization: As a final defense-in-depth measure, the CI pipeline runs a verification script (scripts/verify-sanitize-dist.mjs) that scans the final HTML output for high-risk patterns like inline event handlers or javascript: URLs. Any such finding will block deployment.

4.2. Secure by Design Code Implementation

The codebase is a direct reflection of my security principles:

  • Cryptographic Integrity: The security-kit.ts module exclusively uses the Web Crypto API (crypto.getRandomValues) and explicitly throws a CryptoUnavailableError instead of falling back to the insecure Math.random(). To generate unbiased random integers and strings, I use rejection sampling (inspired by nanoid) to guarantee a uniform distribution.
  • Secure DOM Interaction: A centralized SecureDOMValidator class is used to validate all dynamic DOM selectors against a strict allowlist to prevent Selector Injection. Furthermore, it validates that the result of a query is an instanceof Element, a key defense against DOM Clobbering attacks.
  • Secure URL Handling: The project forbids direct use of native functions like encodeURIComponent. Instead, it mandates the use of custom helpers in security-kit.ts (e.g., createSecureURL) that leverage the browser’s hardened URL and URLSearchParams APIs to prevent common URL encoding vulnerabilities.
  • State Management & Resilience: True encapsulation is enforced with private class fields (#), and Object.freeze() is used for immutable configurations to prevent runtime tampering. All event listeners are managed with an AbortController for leak-free cleanup in SPA environments.

4.3. Performance as a Security Feature

A performant application is a more secure one. I mandate modern, efficient patterns:

  • Jank-Free Animations (WAAPI): The Web Animations API (element.animate) is used to run animations on the compositor thread.
  • Efficient Observation: IntersectionObserver is used for scroll detection and ResizeObserver for layout changes, eliminating the performance cost of legacy event listeners.
  • GPU Layer Promotion: I explicitly hint to the browser to promote animated elements to their own compositing layer using transform: translateZ(0) and will-change.

4.4. Automated Verification & CI/CD Security Gates

My CI/CD pipeline is the ultimate enforcer of these security policies. A pull request cannot be merged unless all checks in the bastion-gates.yml workflow pass.

  • Static Application Security Testing (SAST): The Analyze job in the CI pipeline integrates ESLint with security-focused plugins (eslint-plugin-security, eslint-plugin-no-unsanitized) and GitHub’s CodeQL for deep semantic analysis. This SAST setup automatically detects and blocks insecure patterns.
  • Automated Dependency Management: Renovate bot (renovate.json) is used to automatically create pull requests for dependency updates, ensuring security patches are applied promptly. My philosophy is that Trust is Not Transitive; every dependency is a potential vector.
  • Dependency Auditing: The CI pipeline executes npm audit --audit-level=high. A build will fail and deployment will be blocked if any high or critical severity vulnerabilities are found in the production dependency tree.

5. Vulnerability Disclosure and Reporting

I am committed to resolving security vulnerabilities quickly and responsibly and have adopted the standardized security.txt protocol (RFC 9116) for vulnerability disclosure.

The authoritative instructions for reporting a security vulnerability can be found at the following standard location:

https://david-osipov.vision/.well-known/security.txt

This file contains the appropriate contact information, my PGP public key for encrypted communication, and the scope of this policy. I ask that you follow the procedures outlined in this file and do not disclose any findings publicly until there has been a reasonable opportunity to investigate and address them.

Document version history with 1 versions. Click on any row to view detailed changes for that version.

Version History 1

VersionStatusDateActions