This site is a
portfolio piece too.
A security portfolio should practice what it preaches. Every choice below is enforced by the build or the hosting config, not by good intentions. Check it yourself in one command.
Controls in place
- Content-Security-PolicyStrict, no unsafe-inline, no unsafe-evalHTTP
- Strict-Transport-Security2 years, subdomains, preloadHTTP
- X-Frame-Options + frame-ancestorsDENY: the site cannot be framedHTTP
- X-Content-Type-OptionsnosniffHTTP
- Referrer-Policystrict-origin-when-cross-originHTTP
- Permissions-Policycamera, microphone, geolocation offHTTP
- Cross-Origin-Opener-Policysame-originHTTP
- Third-party requests0: fonts self-hosted, no CDN, no embedsPage
- Cookies and trackers0: no analytics, no consent banner neededPrivacy
- Server-side attack surfaceNone: static HTML, no backend, no database, no formsArchitecture
- security.txtPublished at /.well-known/security.txt (RFC 9116)Disclosure
- Known vulnerabilities0 reported by npm auditSupply chain
- Dependencies8 direct packages, all used at build time onlySupply chain
The actual policy
Read at build time from the same vercel.json that the hosting platform applies, so this page cannot drift from production.
default-src 'self';
script-src 'self';
style-src 'self';
img-src 'self' data:;
font-src 'self';
connect-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requestsDesign decisions
No inline code, anywhere
All JavaScript is bundled into one external file. Code samples are highlighted at build time with CSS classes instead of inline styles. Dynamic values (the card spotlight) go through the CSSOM, which CSP allows. Result: script-src and style-src can stay at self.
Static by design
There is nothing to hack on the server because there is no server logic: every page is pre-rendered HTML. Contact goes through mailto, so no form endpoint to spam or inject.
Nothing third-party
Fonts are bundled with the site, there are no analytics, no social widgets and no CDN scripts. Visitors are not tracked, and a compromised third party cannot inject code here.
Supply chain hygiene
A small dependency tree, a committed lockfile, and npm audit kept at 0. Astro was upgraded across two major versions to clear a critical advisory before it could matter.
Try to hack me
Paste an XSS payload, or pick one below, and inject it. This page really inserts it into the DOM, using a method that would execute scripts. The only thing standing in the way is the Content-Security-Policy, and the log shows the browser blocking each attempt in real time.
Verify it yourself
Headers are public. These commands and scanners show exactly what the browser receives.
$ curl -sI https://mouaadsek.dev | grep -iE "content-security|strict-transport|x-frame|referrer|permissions"Known limits
- The site runs on its own domain, mouaadsek.dev, but DNS and TLS still depend on the registrar and the host (Name.com and Vercel).
- My email address is published on purpose: being reachable is the point of a portfolio.
- Browsers already force HTTPS for every .dev domain (the whole TLD is preloaded), but mouaadsek.dev is not yet submitted on its own to the HSTS preload list.