I’ve recently finished overhauling this site. If you’ve noticed anything different around here, this is why. (If you haven’t, sweet! That was my goal.)
What?
I migrated player03.com from shared hosting to a virtual private server (VPS).
Along the way, I improved the site’s security (both front- and backend), wrote a bare-bones privacy policy, and tidied up some old posts and images. I considered big changes like switching to a more recent theme, but most of them broke something or would require extra work, and might confuse visitors. So instead, I aimed to keep it as close to the old version as possible.
Why?
Because CryptCheck gave me an F.

Two ranks below the bare minimum, ouch!
(Note: I have no evidence that anyone ever exploited these vulnerabilities in the wild.)
Who?
I don’t actually know who runs cryptcheck.fr, other than that they’re French and highly opinionated. The site was recommended by a security geek on social media, and as we all know, geeks on social media are infallible.
Whether or not I felt like trusting CryptCheck, Mozilla corroborated them. Their HTTP Observatory gave me a 40/100 (D-). Thankfully, unlike CryptCheck, Mozilla provided detailed descriptions of what was wrong, why it was wrong, and how to fix it.
What and why?
- I was allowing unsafe inline scripts. This meant that if someone found a way to insert text into the page, they could run a script in another visitor’s browser, potentially stealing data or directing them to a virus. (WordPress sanitizes comments, but you never know when someone will find a way to bypass that.)
- I was allowing other sites to embed mine in an iframe. In theory this can be used to steal user data, though in practice, what is there to steal?
- I wasn’t implementing HTTP Strict Transport Security (HSTS), meaning http://player03.com didn’t redirect to https://player03.com early enough in the connection process. It did redirect eventually, but the initial connection was done over http, which would technically be enough for someone to intercept the data and redirect users to a fake site.
How?
The easiest one to fix was iframe embedding. I opened up the root .htaccess file and added two lines. The first line sets X-Frame-Options "SAMEORIGIN", telling browsers not to let other sites embed mine. The second line sets frame-ancestors 'self', telling browsers not to let other sites embed mine. I think the difference is that the former is for old browsers and the latter is for new ones.
Next, I had to disable inline scripts. This isn’t hard to do: just delete 'unsafe-inline' from .htaccess. The trick was, I wanted my site to continue working afterwards, and some of my fancier blog posts made heavy use of inline scripts. I’d have buttons that you click, each with its own onclick="do.unique.thing()" inline script.
To fix this, I went through all my blog posts and figured out a way to replace these scripts. Turns out, while onclick="xyz" is unsafe, you can just move xyz into a .js file, and then it’s safe. The site uses HTTPS, which means all the .js files are cryptographically signed, so there’s no tampering with them during transit. I also submitted a pull request to Lime to remove inline scripts from Lime apps.
WordPress uses its own inline scripts, and I couldn’t transfer those. Instead, I manually approved them using SHA-256 hashes. These scripts will run as long as they’re completely 100% identical to the versions I approved, but even adding or removing a space would make browsers reject them. This ALSO means that I can expect parts of the site to break when WordPress updates, and I’ll need to manually re-approve it. WordPress is working on clearing out inline scripts, but not quickly.
Finally, HSTS and redirection. HSTS is easy: add a single line in .htaccess, promising to keep using HTTPS for a year. As for redirection, it’s just a couple more lines of code… that didn’t work. Each time I tried, it broke the whole site. Digging deeper, I realized these lines could not go in .htaccess, and what’s more, I didn’t have access to the correct file.
Where?
I needed access to the Apache server configuration files. However, I was on shared hosting, and being able to mess with those files would mean I could mess with other people’s websites (and they could mess with mine). Understandably it wasn’t allowed.
To do this one last little thing, I needed to move my entire website over to a whole new server, one under my control. On the plus side, it turns out that virtual private servers are cheaper than shared hosting, at least when you get the self-managed option. Pros of self-managed: I’m in full control, and no longer need to ask permission to change settings. Cons of self-managed: I’m in full control, and with great power comes great responsibility.
Since I had already spent time configuring Apache settings, I picked a LAMP stack (the A stands for Apache) over LEMP (the E stands for Nginx). My hosting provider offered a one-click install, but that didn’t work so I installed it myself. I set up firewall rules, an https redirect, restricted accounts for each service, SSH access, SELinux, and various other security measures. After briefly confusing FTPS and SFTP, I bulk-uploaded the site’s contents.
Aside: either guides have gotten better since 2014, or I’ve gotten better at following them, because everything ended up working as described. I did run into snags, but I was either able to work through them quickly enough, or I’d discover that there was a good reason it wasn’t allowed. I ended up with an aggressively basic setup, and I’m happy with that: basic means easy to verify.
When?
This Tuesday, I updated my DNS records to point to the new site.
Several things immediately broke, most notably the CSS, due to URLs still pointing to the test version of the site. My Content Security Policy (CSP) specified that scripts and styles must be loaded from 'self', not some strange alternate-dimension version of 'self' at a different web address. (It was the same thing, but browsers couldn’t verify that, so didn’t trust it.) I updated the site link in the WordPress dashboard and Apache config files, and things went back to normal.
Then I encountered another issue: my hosting provider unexpectedly restored the site’s old DNS record, in addition to the new ones. This left visitors with a 4/5 chance of getting the correct site, but a 1/5 chance of being sent to the old one, which was now broken due to the same sort of URL issues described above.
The reason this broke? Their nameservers were for shared hosting, and I wasn’t supposed to use them anymore.
So I set up my own nameserver on the VPS. Now, when you connect to my site, your browser contacts my server for instructions on how to contact my server. Seems weird, but there are several guides for exactly this, so I suppose that’s just the world we live in.
Is that all?
First off, rude, this took over a week of research and work.
Second, no, it’s not all. I have a short list of things still to do, and I’m sure there will be user-reported issues. I’ve already received one such report: apparently Run3.swf no longer works in the standalone Flash Projector. (Not sure how to debug this, sadly. If anyone has solid information on how the Flash Projector loads files, let me know!)