Since I'm maintaining a security blog, I have to implement the best security practices on this website. I also worked on some things that aren't exactly related to security, but in my opinion things are that we all work on implementing, only then we will make the internet a better and safer place for everyone.

One of my first goals here was to remove all requests to third parties, which resulted in me removing jquery from this blog's theme. So if you're visiting my website, no additional servers will be contacted automatically, eliminating all the dependencies on third party servers, which is almost never the case on modern websites. Yes, I could also host my own jquery, but I don't want that, I prefer simplicity, and one of my next goals is to make the website free of JavaScript. The smaller the attack surface, the better.

The picture below shows all the requests your browser generates while requesting the main page.

Requests in Chrome developer toolbar

My second goal was to make it small. All those files are stored on this server. There are obviously still things that I can improve, like supporting HTTP/2, compressing images, removing JavaScript, but it's already far lighter than most of the web nowadays. As a cool side effect of this, the website works perfectly fine in any text-based browser, like eww in emacs:

Isn't emacs amazing?

My third goal was to make it obvious when people connect over IPv4. This is why I have assigned only a IPv6 address to the main domain. At first many have complained that they cannot reach my website, so I have created an ugly subdomain that resolves to a IPv4 only.

$ dig A +short danielonsecurity.com @8.8.8.8

$ dig AAAA +short danielonsecurity.com @8.8.8.8
2a02:c207:2029:9161::dead:f88d

$ dig AAAA +short myinternetprovidersuckssoihavetouseipv4.danielonsecurity.com @8.8.8.8

$ dig A +short myinternetprovidersuckssoihavetouseipv4.danielonsecurity.com @8.8.8.8
144.91.67.232

It's interesting to watch what search engines and other bots do when the domain is configured with such a hack. Lots of them display IPv4 only and cannot crawl IPv6-only links.

My fourth goal was to provide an easy way to subscribe to updates, which was fortunately very easy with RSS. Most blogging platforms support RSS out of the box, but often they are hidden since few people use them. If I find a blog that I like and it doesn't have any visible RSS on the front page, I tend to try to append '/feed' or '/rss' to the blog URL, and often it's available and fully functional. When appending those extensions doesn't find working feeds, I look at the HTML source code, and search for 'feed', 'rss' or 'atom' in the code. This worked many times for me with RSS-unfriendly websites. If none of those work, I give up and look for better sources.

Therefore, to encourage people to use RSS, I have made it clear at the top of the page, together with IPv4, IPv6, and TOR, which I'll talk about later.

Header of this website

Also, to show what RSS is capable of, I have built LINKS that periodically queries my RSS collection and show the recent articles sorted by categories. This was my fifth goal. I use it to keep track of the newest advisories, exploits, data breaches, etc...

My sixth goal was privacy. I don't want any data from you, I don't care who you are as a visitor of this website, so you will find no tracking stuff here. The only things that are stored are the server side logs from the Ghost platform and openbsd httpd/relayd servers. And those get deleted on log rotation, so no information about you will ever be saved here. I have written more about this in the privacy policy.

Speaking of privacy, I thought it would be cool to have a hidden service, so I added the onion link to the header like mentioned previously, which was my seventh goal. So I encourage you to use the hidden service if you are already a TOR user. If you are not, give it a try, TOR is a really cool project.

My eight goal was to get an A+ score on Qualys SSL test:

Qualys SSL Report for danielonsecurity.com

You can check it yourself if you want to see more details. I accomplished this by tweaking relayd.conf:

In the protocol section, I added the following line to use only the strong ciphers. In the Qualys report you can see that old browsers aren't able to access my website, and I am okay with that.

tls { ciphers "ALL:!RSA:!CAMELLIA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4:!SHA1:!SHA256:!SHA384:!DHE-RSA-AES128-GCM-SHA256" }

Strict-Transport-Security header enables HSTS, which will force the browser to request the website over HTTPS:

match response header set "Strict-Transport-Security" value "max-age=31536000; includeSubDomains"

The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in another frame or object. I don't need this, so I set it to DENY, but turns out Ghost blog needs it, so I have set it to SAMEORIGIN instead:

match response header set "X-Frame-Options" value "SAMEORIGIN"

The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised in the Content-Type headers should not be changed and be followed:

match response header set "X-Content-Type-Options" value "nosniff"

The Referrer-Policy HTTP header controls how much referrer information should be included with requests. I don't care about referrers, so I set this up to omitt the header entirely:

match response header set "Referrer-Policy" value "no-referrer"

Delete X-Powered-By headers, since no one needs to know that:

match response header remove "X-Powered-By"

My ninth goal was to have a working Content-Security-Policy. I ended up using something like this:

I don't need default sources:

default-src 'none';

HTML base tag should be allowed to use only self:

base-uri 'self';

Prevent loading assets using HTTP when the page is loaded using HTTPS:

block-all-mixed-content;

Allow XMLHttpRequest, WebSockets or similar connections only to itself:

connect-src 'self';

Valid sources of images are only on names belonging to this server:

img-src danielonsecurity.com myinternetprovidersuckssoihavetouseipv4.danielonsecurity.com dfzjhffodwtmnemymv4f7ztrr6ee2fvz2jli5cvahnjukky5krvds3qd.onion;

Same with frames:

frame-src danielonsecurity.com myinternetprovidersuckssoihavetouseipv4.danielonsecurity.com dfzjhffodwtmnemymv4f7ztrr6ee2fvz2jli5cvahnjukky5krvds3qd.onion;

Allow stylesheets from inline, and server addreses:

style-src 'self' 'unsafe-inline' danielonsecurity.com myinternetprovidersuckssoihavetouseipv4.danielonsecurity.com dfzjhffodwtmnemymv4f7ztrr6ee2fvz2jli5cvahnjukky5krvds3qd.onion;

Allow scripts with a random nonce and originating from server addreses:

script-src 'nonce-abcde123' danielonsecurity.com myinternetprovidersuckssoihavetouseipv4.danielonsecurity.com dfzjhffodwtmnemymv4f7ztrr6ee2fvz2jli5cvahnjukky5krvds3qd.onion

This is my first time setting up Content-Security-Policy, so if I did something wrong, please let me know.

With that being said, I totally understand that not everyone is able to give up using third parties, or stop tracking users, nor am I saying that anyone should have a hidden service. It's obviously all up to you, and I'm only trying to build a website where I wish that more websites could be like it. I don't want ads when browsing the web, I don't want to be tracked, and I want to be able to browse anonymously without having to complete reCaptchas for every refresh. I also don't want to close all those GDPR cookie popups before reading any article. I don't want to agree with them collecting all that information, neither do I want to be tracked in the first place.

If you have suggestions or find any issues on this website, please contact me at www@danielonsecurity.com (PGP key).