The Long Ago
Kongregate has been around for a relatively long time. We were around when Flash was cool, and also when it became uncool. We were also around when SSL was considered an optional luxury that added significant overhead and latency to network requests. Thus, we built our site with the assumption that HTTP was a fine protocol to use most everywhere, and SSL should just be used "as needed" -- for authentication, purchasing, and other sensitive data.
That assumption held up for over a decade, but in recent years there has been a large movement toward using SSL everywhere, with search engines and browser vendors alike starting to punish sites for serving up un-encrypted content. Visiting Kongregate using HTTP on modern browsers was starting to become a scary and confusing experience for our players, so we decided it was time to bite the bullet and switch to using HTTPS wherever possible.
The Basic Challenge
Converting to SSL can be a daunting task for even simple sites without much user-generated content. Here is a short list of the things that need to be done at minimum:
- Obtain and manage certificates for development, staging, and production
- This task is luckily made significantly less costly thanks to Let's Encrypt
- Set up web servers or load balancers to listen on the proper port and serve the correct certificates
- Ensure the application redirects HTTP traffic to HTTPS properly (and doesn't end up in a redirect loop)
- Make all active content such as scripts/AJAX requests load over SSL
- This should be done for all passive content as well where possible
- Ensure any third-party content such as ads/iframes/SDKs/etc. are loaded over SSL
- Depending on the third party, this may not even be possible
- Test everything on the site to make sure all is well
Getting into the Weeds
We started work on converting Kongregate to use HTTPS by default earlier this year. We began by picking off a lot of the low-hanging fruit such as scripts, images, stylesheets, and hard-coded references to
http://. This was done while keeping all top-level pages being served over HTTP to minimize the impact. Since you can always load secure elements in an insecure page, this allowed for some backward compatibility in case we wanted to roll things out incrementally.
The next step was requiring SSL for all top-level pages aside from the game page (more on why the game pages are more complicated in a bit). This allowed us to start utilizing the security tab of Chrome's developer tools to find and correct additional insecure resources that were sneaking in across various areas of the site. This part of the process also went pretty quickly, although we did run into some issues with first- and third-party ads sometimes attempting to load insecure assets.
User-Generated Content: Absolute Hell
By far the most complicated part of this transition was deciding what to do with the most important aspect of Kongregate -- the user-uploaded games and the pages that contain them. Almost all games on Kongregate are hosted in an iframe, and if the top-level page is served over HTTPS, the iframe cannot be HTTP or the browser will prevent it from loading.
Many of our tens of thousands of games are old and no longer maintained, but are still very popular and widely played. Since we didn't just want to break tons of games without giving developers a chance to update them, we added heuristics and per-game controls to allow legacy game pages to continue to load over HTTP during a grace period. This did add some complexity, as we needed to ensure things like the sign-in and purchasing lightboxes were still able to communicate with the top-level frame even though they were being served up over a different protocol, but we feel the tradeoff was worth it.
Let's look at the various types of games that can be played on Kongregate, and talk about the challenges that came up with each of them:
For Flash/Unity WebPlayer games that are directly uploaded to and hosted by Kongregate we have complete control over embedding of the content. This turned out to be great news, as we could simply convert the iframe and everything inside of it to be served securely. This worked without a hitch for most of the existing Flash games on the site. The main problem we ran into that forced us to continue to load these games over HTTP were sitelocks that included the protocol (luckily very rare).
We were also fortunate that changing the protocol of a SWF does not affect Flash Shared Object storage, so all saved games/data would remain intact and players would not lose any progress.
Given the fact that most of these games "just worked," we decided to convert them all to HTTPS at once, and whitelist games to load over HTTP as needed.
Hosted HTML5/Unity WebGL/etc.
Kongregate has supported hosting HTML5 games for several years. Games of this type uploaded on or after July 1st, 2016 were already being served over SSL by default. Games uploaded before that face several potential problems once we start serving them securely:
- They may be loading scripts or other active content over HTTP (the most frequent culprit here is the Kongregate API or tools like jQuery).
- Most HTML5 solutions for storing data client-side are based on the absolute URL of the page (including protocol), meaning that the saved game state would be lost after the migration.
We ended up creating a script to crawl through all our older HTML5 games to try and determine which ones were likely to break if switched over so that we could contact developers to let them know that their games would need to be updated. We also encouraged developers to give players a mechanism to export their saved games so that progress would not be lost once the switch was made.
For developers who require complete control over the hosting of their game, Kongregate offers external iframe embedding support. Many games were already using HTTPS URLs for their iframes, but the majority were HTTP. Once again, we wrote a script to investigate these games to determine which ones were likely to break by checking for timeouts, HTTP errors, and insecure resources.
First, we tried just loading the HTTP URL over HTTPS instead to see if it would work. In a few cases, it did. Frequently an HTTPS version of the iframe was indeed available, but it then ran into the same problems as the HTML5 games mentioned above -- loading insecure active content would cause the page to break.
Luckily, developers could easily test and resolve these issues ahead of time by simply creating a preview version of their iframe game that was served over HTTPS instead of HTTP.
A huge aspect of this project was testing to make sure everything would still work properly after the switch. As an engineer, you always feel bad for the QA team on deploys of this magnitude where you pretty much just tell them, "Yeah, go ahead and just make sure everything still works properly."
Our QA team deserves a whole heap of credit for not only finding some critical issues before this all rolled out, but also for testing so many high-value games (along with the community and platform teams) to determine which developers we needed to contact to let them know about potential issues.
For developers of non-iframe games, we gave them a query parameter which could be used to force their games to be loaded via SSL. This allowed them to clear up any related issues and ensure their games would work properly after we switched over.
The big deploy went relatively smoothly. We did have one high-profile game somewhat mysteriously stop working. This turned out to be due to their iframe URL not having a trailing slash and a server rule that redirected to add one. This is a fairly common thing, but the redirect unfortunately always redirected to HTTP instead of keeping the protocol intact. While investigating that particular issue my laptop also crashed and wouldn't boot back up because of course it did. Otherwise, aside from a few minor bugs and a white pixel that started appearing on the top-left of the site (unrelated), things went very well.
We will continue to work with developers to make their games SSL-compatible over the coming months so that hopefully in the near future we will not be serving any user-facing pages over HTTP, at which point we can enable Strict Transport Security.
Also, while we are defaulting to HTTPS, we still have a fair number of passive mixed-content warnings on game and forum pages. Some of these cannot be avoided, but we would like to start tracking and potentially fixing some of them with a Content Security Policy.