{"id":1056,"date":"2018-10-31T15:53:08","date_gmt":"2018-10-31T15:53:08","guid":{"rendered":"http:\/\/smartfoxserver.com\/blog\/?p=1056"},"modified":"2018-10-31T15:54:12","modified_gmt":"2018-10-31T15:54:12","slug":"security-for-html5-games","status":"publish","type":"post","link":"https:\/\/smartfoxserver.com\/blog\/security-for-html5-games\/","title":{"rendered":"Security for HTML5 games"},"content":{"rendered":"<p>With <a href=\"https:\/\/www.smartfoxserver.com\/download\/sfs2x#p=updates\" target=\"_blank\" rel=\"noopener noreferrer\">SmartFoxServer 2X 2.13.4<\/a> we introduced <strong>websocket origin checks for HTML5 clients<\/strong>. What this mechanism does is essentially verify the\u00a0provenance of the client against a white-list of domains configured by the server admin. If the client origin does not match any of the allowed\u00a0domains\u00a0the client connection is denied.<\/p>\n<p>In this article we&#8217;ll\u00a0demonstrate how to use and configure websocket origins in SmartFoxServer 2X and\u00a0discuss the advantages and limitations of this security measure. We&#8217;ll also take a deeper look at the issue of cheating clients and propose several ideas to improve the security of your online game.<!--more--><\/p>\n<h2>\u00bb Who is knocking at the door?<\/h2>\n<p>Publishing\u00a0a multiplayer\u00a0HTML5 game online has many advantages, one of which is that the game client itself is always available for access to any player\u00a0armed with an Internet browser.<\/p>\n<p>This\u00a0direct availability however can also attract\u00a0folks who are not interested in the game itself but rather in messing with it, by dissecting the client\u00a0and trying\u00a0to understand how to take advantage of potential flaws or bugs.<\/p>\n<p>With\u00a0web-based games cheaters can have an easy time accessing the game client&#8217;s code and try to recreate a different client that attempts to abuse the system. Without a specific protection that is able to recognize\u00a0a genuine client from a fake one, it will be very hard to get rid of these attackers.<\/p>\n<h2>\u00bb Websocket origin to the rescue<\/h2>\n<p>Fortunately for us the websocket protocol includes an &#8220;Origin&#8221; parameter in the HTTP request (specifically in the &#8220;upgrade&#8221; request) that can be leveraged to apply some basic security checks.<\/p>\n<p>In fact the &#8220;Origin&#8221;\u00a0value will tell us the source of the web page requesting a socket connection and with that we can verify it against a list of safe domains.<\/p>\n<p>Below is a screenshot from the SFS2X AdminTool, under the <strong>Server Settings<\/strong> &gt; <strong>Web server tab<\/strong><img loading=\"lazy\" class=\"size-full wp-image-1059 aligncenter\" src=\"http:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2018\/10\/sfs2x-origins-1.png\" alt=\"\" width=\"650\" height=\"388\" srcset=\"https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2018\/10\/sfs2x-origins-1.png 650w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2018\/10\/sfs2x-origins-1-300x179.png 300w, https:\/\/smartfoxserver.com\/blog\/wp-content\/uploads\/2018\/10\/sfs2x-origins-1-624x372.png 624w\" sizes=\"(max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>Here in the &#8220;Allowed client origin&#8221; box we have configured two valid domains:<\/p>\n<ul>\n<li><strong>my-website.com:\u00a0<\/strong>this specifies that only clients from this domain can connect to SFS2X, without exceptions. For instance www.my-website.com will be rejected as it doesn&#8217;t strictly match our setting.<\/li>\n<li><strong>*.my-website2.net:\u00a0<\/strong>using a wildcard (asterisk) allows to loosen up the check a bit. In particular this allows any third level subdomain of my-website2.net, such as games.my-website2.net or www.my-website2.net, to be able to connect.<\/li>\n<\/ul>\n<p>By default SFS2X is configured with no allowed origin configured. In this case any client will be allowed to connect via websocket.<\/p>\n<p>When origins are specified the server will match the client&#8217;s provenance with the white-list and shut down\u00a0any connection attempt that fails the check. If someone steals your game code and then attempts to run a\u00a0modded version from\u00a0his computer or another online server, he will be out of luck as no connections will go through.<\/p>\n<p><strong>NOTE<\/strong>: keep in mind that only one wildcard is allowed per entry and it must be placed at the start of the domain entry. Examples such as these:<\/p>\n<ul>\n<li>*.*.my.domain-com<\/li>\n<li>subdomain.*.my-domain.com<\/li>\n<\/ul>\n<p>are incorrect and will be rejected.<\/p>\n<h2>\u00bb\u00a0Limitations and improvements<\/h2>\n<p>While the origin check is a good security measure to\u00a0keep activated it won&#8217;t protect you from\u00a0other cheating attempts. In particular, smarter hackers\u00a0could be able to\u00a0forge\u00a0an HTTP header\u00a0and\u00a0fake the origin\u00a0to what the server expects, even if the client is effectively coming from somewhere else.<\/p>\n<p>For instance, this could be done by building a client in Java or C# using a websocket library to send the fake origin,\u00a0thus bypassing the protection. From there the\u00a0cheating\u00a0client can communicate with the server and none\u00a0is the wiser.<\/p>\n<p>There are supplementary techniques that can be employed to increase the origin protection. For example, by generating a unique token in the game&#8217;s starting HTML page so that\u00a0it can be sent back to the server at login time for validation.<\/p>\n<p>The system essentially allows for a two-step validation, the first at connection time and the second at login time.<\/p>\n<p>Even this countermeasure isn&#8217;t 100% hack-proof\u00a0since setting a token on client side still provides opportunities for malicious clients to\u00a0scan the HTML\u00a0for such token and then using\u00a0it\u00a0in a custom built client.<\/p>\n<h2>\u00bb Higher and lower level security measures<\/h2>\n<p>Verifying\u00a0the client&#8217;s origin and introducing a dynamic token to be verified at login time are valid ways to keep a number of attacks away and\u00a0discourage casual hacking attempts.<\/p>\n<p>The better protections, however, usually comes from\u00a0proper validation of every incoming request. In particular it is crucial to run most of the game logic on the server side and remove any authority from the client. This way even if attackers can bypass the client origin checks, no real harm will be done\u00a0since the server\u00a0will deny any of their potential shenanigans.<\/p>\n<p>There is an old mantra in multiplayer development that says: &#8220;<strong>the client can&#8217;t be trusted<\/strong>&#8220;, which is probably one of the best principle upon which building any multiplayer game.<\/p>\n<h2>\u00bb\u00a0Learn more<\/h2>\n<p>If you&#8217;re interested in learning more about securing your multiplayer game we highly recommend\u00a0reading this in-depth\u00a0<a href=\"https:\/\/www.smartfoxserver.com\/downloads\/sfs2x\/documents\/SFS2X_WP_Security.pdf\" target=\"_blank\" rel=\"noopener noreferrer\">security white-paper<\/a>.<\/p>\n<p>The document analyzes many aspects of online game&#8217;s security, the relative tools that SmartFoxServer offers and the best practices to avoid common attacks and secure the game.<\/p>\n<p>For any feedback or questions you can always <a href=\"https:\/\/www.smartfoxserver.com\/forums\/index.php\" target=\"_blank\" rel=\"noopener noreferrer\">reach us via our support forums<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With SmartFoxServer 2X 2.13.4 we introduced websocket origin checks for HTML5 clients. What this mechanism does is essentially verify the\u00a0provenance of the client against a white-list of domains configured by the server admin. If the client origin does not match any of the allowed\u00a0domains\u00a0the client connection is denied. In this article we&#8217;ll\u00a0demonstrate how to use [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/1056"}],"collection":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/comments?post=1056"}],"version-history":[{"count":7,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/1056\/revisions"}],"predecessor-version":[{"id":1065,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/1056\/revisions\/1065"}],"wp:attachment":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/media?parent=1056"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/categories?post=1056"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/tags?post=1056"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}