← All projects
Web securityP-07
This site, a portfolio with no JavaScript and a strict CSP
How this site is built and hardened. It is static, ships zero JavaScript, sends a strict Content Security Policy, and collects no tracking data.
At a glance
- Role
- Designer and developer
- Stack
- Astro (static), Cloudflare Pages
- JavaScript
- None
- Headers
- Strict CSP, HSTS, Permissions-Policy
Context
A security portfolio should practice what it preaches. This site is a small example of secure-by-default web design: very little attack surface, nothing collected about visitors, and headers that leave browsers little room for abuse.
Design choices
- Static output. The site is pre-built HTML and CSS. There is no server-side code, database, login, or admin panel to attack.
- Zero JavaScript. Even the light/dark theme switch and the mobile menu are pure CSS, so the policy can block scripts entirely.
- Strict Content Security Policy.
default-src 'none',script-src 'none', and styles and fonts only from this site. Nounsafe-inlineanywhere, so the build is set up to emit no inline styles. - Transport security. HSTS with a long max-age, on a
.devdomain, which browsers already require to use HTTPS. - Other headers.
frame-ancestors 'none',nosniff, a strict referrer policy, and a Permissions-Policy that turns off camera, microphone, location, and similar browser features. - No tracking. No analytics, cookies, or third-party requests. Fonts are self-hosted.
- Disclosure. A
security.txtfile (RFC 9116) tells researchers how to report issues.
Domain and email (launch checklist)
These are being rolled out as part of the launch, in stages:
- DNSSEC, so the site’s DNS answers can be verified.
- CAA records to limit which certificate authorities may issue certificates for the domain.
- SPF, DKIM, and DMARC to stop others from sending email that pretends to come from the domain. DMARC starts in monitor-only mode and is enforced once the reports are clean.
Key decisions
- Privacy is part of the design. The site is about the work, not the person, so it holds very little personal information that could be scraped.
- Avoid features that need exceptions. Each convenience that would require loosening the policy, such as analytics or embedded widgets, was left out instead.