Réseau (dont HTTP)

CSP: Content Security Policy

La Content Secutiry Policy permet de dire au navigateur "voilà les ressources (CSS, JS, images, etc) que mon site a le droit de charger, si mon site contient autre chose [ie: à cause d'une faille XSS], alors ne le charge pas". Cela mitige donc les attaques XSS.

Header always set Content-Security-Policy "default-src *.twitter.com 'self';\ style-src 'self' 'unsafe-inline';\ script-src *.twitter.com 'self' 'unsafe-inline'" # These got deprecated by CSP but are still recommended as of 2016 Header always set X-Content-Type-Options "nosniff" Header always set X-Frame-Options "SAMEORIGIN" Header always set X-XSS-Protection "1; mode=block"
Exemple de CSP autorisant les images/frames/etc de twitter et du site, les styles embarqués via style="..." et le JS dans les attributs type onclick onkeyup...

HTTPS

Générez un certificat HTTPS (via Let's Encrypt par exemple) et ne permettez la connexion à votre jeu que via HTTPS: les connexions HTTP sont à proscrire, même pour des images/assets! Imaginez qu'un pirate intercepte le traffic, et chaque les icônes: il peut pourrir votre réputation, ou amener de la confusion (de sorte que les utilisateurs se trompent), en inversant par exemple l'apparence du bouton "sauver" et du bouton "supprimer" (ou "annuler").

Utilisez également le Strict-Transport-Security (HSTS) pour que le navigateur sache qu'il doit toujours aller sur votre jeu en HTTPS, même si l'utilisateur a cliqué sur un lien HTTP.

# Redirect HTTP to HTTPS (always use Secure flag on Cookie so they won't leak!) RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L] # HSTS forces the use of HTTPS by the browser even if a link was HTTP (1 year, arbitrary) Header always set Strict-Transport-Security "max-age=31536000"

Cookies

Pour les cookies (Set-Cookie) , utilisez toujours les options Secure + HttpOnly + Path=... + SameSite=Strict + Max-Age/Expires=.... Vous aurez ainsi des cookies HTTPS uniquement, innaccessibles via JS, limités à une partie du jeu web, jamais envoyés en cas de CSRF, et qui ne dureront pas inutilement.

# Cookies config: No "Secure" on non-HTTPS domains, but always HttpOnly + SameSite Header edit Set-Cookie ^(.*)$ $1;Secure env=!SKIP_HTTPS Header edit Set-Cookie ^(.*)$ $1;HttpOnly; SameSite=Strict; Path=/game/; Max-Age=600
Exemple de configuration pour Apache

Status code

Utilisez-les autant que possible pour décrire l'état de la réponse d'un appel web (voir la liste dans les liens ci-dessous). Par exemple, bannissez les réponses JSON contenant { success: false, errorMessage: 'Usine introuvable' } au profit d'un response code HTTP 404 et un éventuel response body {message: 'Usine introuvable'}.

Le bon code HTTP vous permettra d'identifier facilement le type de réponse, et de dresser des statistiques pertinentes sans effort.

Compression

La compression peut se faire soit à la volée via AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript... soit statique en créant un .gz de vos JS et CSS puis en les servant avec le header Content-Encoding: gzip ou en laissant Apache faire grâce à l'envvar RewriteRule ^ - [E=no-gzip:1].

Ne gzippez pas les pages critiques servies en HTTPS, à cause de certaines failles éventuelles de sécurité (mais pour un jeu web, cela ne posera probablement aucun soucis).

N'hésitez pas à compresser statiquement les ressources de votre jeu, en crant une version .gz de vos js/css/xml, pour éviter de toujours devoir les compresser à la volée.

Cache

Dites au navigateur de garder les ressources du jeu en cache le plus longtemps possible via Cache-Control : public, max-age=... pour une ressource identiques à tous les joueurs, et private, max-age=... pour une ressource spécifique à un joueur.

Sur Isometry, la bonne utilisation du cache divise par 5 le temps de chargement des pages!

Pour forcer la mise à jour du cache, modifiez son URL, en rajoutant par exemple un paramètre ?t=... correspondant au timestamp de la dernière mise à jour du contenu de la ressource (ou la version de la ressource, ou son ETag ou son md5 etc).

Accept-Language

Ce header est envoyé par le navigateur et lu par Apache via %{HTTP:Accept-Language} ou par PHP via $_SERVER['HTTP_ACCEPT_LANGUAGE'] ou Locale::acceptFromHttp. Il décrit les langues que l'utilisateur (navigateur) souhaite recevoir. Cela vous permettra donc de servir à vos joueurs la bonne traduction de votre jeu web.

Dans le wiki de Dracca , ce header est complété par un paramètre GET (lang=fr/en) qui permet d'accéder directement à la traduction de la page en français ou en anglais, pour pouvoir la partager spécifiquement.
On remarquera également que la valeur du paramètre est conservé d'une page à l'autre, si et seulement si la langue spécifiée via GET n'est pas celle spécifiée via les HTTP headers. Cela donne une navigation fluide et intuitive.

Liens utiles

IP Encoding

Une adresse IP (v4) peut être encodée au format décimal, mais aussi octal, ou hexadécimal. Dans ce cas, les point . ne sont même plus nécessaires.
N'oubliez donc jamais de canoniser l'IP sous une unique forme (ie: IPv6 complète) avant de la manipuler (ie: pour vérifier qu'elle n'est pas dans une blacklist/whitelist).

Ces encodages sont souvent oubliés, et peuvent mener à ce genre de faille de sécurité !