How this site is built
A site about security should be able to show its own. This one is deliberately small: static files, one web server, and nothing that runs on the server when you visit.
Static, and nothing else
Every page is a plain HTML file, generated by a small build script from content files kept in Git. There is no database, no content management system, no server-side code, and no cookies. Every page except the puzzles can be read without JavaScript; elsewhere, the scripts only add the interactive parts, such as tracing a network's way out in the diagram, and definitions for technical terms.
The button in the top bar shows the same pages as an old ANSI bulletin board: sixteen colours, one monospace font, and a key for each menu item. If you choose it, your browser remembers that in its own storage, so the next page opens the same way. Nothing about it is sent to the server, and without JavaScript the site simply keeps its normal design.
Nothing from other domains
No web fonts, no scripts from a CDN, no analytics, no trackers, no embedded videos. Text uses the fonts your system already has. When you load a page, your browser talks to this server and nowhere else, and the server keeps only standard access logs. They are copied to my own log system at home, used only to watch for attacks, and deleted after 180 days.
Headers
The web server sends these with every response:
| Header | What it does here |
|---|---|
Content-Security-Policy | The browser may load scripts, styles, images and fonts only from this site, and nothing inline. No connections to other servers, no forms, and no framing by other sites. |
Strict-Transport-Security | Browsers use HTTPS only, for two years, on every subdomain. |
X-Content-Type-Options | Files are treated as the type they are served as, never guessed. |
Referrer-Policy | Following a link from here tells the next site nothing about where you came from. |
Permissions-Policy | Camera, microphone, location, payment and USB are switched off for every page. |
Cross-Origin-Opener-Policy, -Resource-Policy | Other sites cannot hold a reference to these pages or embed their files. |
add_header Content-Security-Policy "default-src 'none'; script-src 'self'; style-src 'self'; img-src 'self'; font-src 'self'; connect-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; upgrade-insecure-requests" always;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), interest-cohort=()" always;
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Resource-Policy "same-origin" always;- The policy can be this strict because the site was built for it from the start: no inline styles or scripts anywhere, not even in the diagram.
The server
The site runs on a small cloud server that has no way into the home network: no VPN, no tunnel, no shared accounts or keys. Its logs are fetched from home every fifteen minutes, by a key that can read them and do nothing else. If the server were ever compromised, it would lead nowhere.
- nginx serves only the files the site consists of, and answers only
GETandHEAD. Hidden files and unknown paths return 404. - TLS 1.2 and 1.3 only, with certificates from Let's Encrypt, renewed automatically. DNS allows no other authority to issue for the domain.
- Requests that do not name this site, such as a scan of the bare address, get no answer and no certificate.
- SSH accepts keys only, from one address, and never for root. A host firewall lets in SSH, HTTP and HTTPS, and nothing else.
- Security updates install themselves, with a reboot at night when one needs it.
- Publishing uses a key that can write files into the web root and do nothing else.
Every step of setting it up, with the files it runs on, is in the web server guide.
Reporting a problem
If you find a security problem with this site or its server, please email security@azit.se. The contact is also in security.txt.
- In scope: this website and the server it runs on. The home network is not reachable from here.
- Welcome: reports made in good faith. Please do not degrade the service, and give me time to fix a problem before you publish it.
- No bug bounty: there is no payment, but every real report gets an answer, and a thank-you here if you want one.
- Something sensitive: say so in your first email, and we will agree on a secure channel.