Programmation PHP/Sécurité

Sécuriser les en-têtes HTTP

modifier

Pour commencer, il est préférable d'utiliser HTTPS à HTTP pour complexifier l'attaque de l'homme du milieu, en garantissant l'intégrité et la confidentialité du flux réseau.

Ceci peut être forcé par le mécanisme HSTS, qui utilise l'en-tête HTTP Strict-Transport-Security.

Masquer les versions

modifier

Pour se prémunir des exploitations des failles de sécurité liées à sa version de PHP ou de serveur Web, on peut chercher régulièrement si certaines ont été détectées et ont une mise à jour sur https://www.exploit-db.com/.

Mais pour éviter d'être la cible de celles qui fonctionneraient, il est préférable de masquer ces versions dans les en-têtes HTTP.

Ceci se fait généralement au niveau des fichiers de configuration du serveur, mais peut aussi être réalisé en PHP ainsi :

ini_set('expose_php', 'Off');
header('X-Powered-By: UnknownWebServer');

Restreindre les connexions

modifier

De plus, il existe d'autres sécurisations des en-têtes HTTP pour se prémunir des attaques de type Cross-site request forgery (CSRF).

Exemple de couche de protection utilisant le Content Security Policy (CSP) :

ini_set('register_globals', 'Off');

header('Content-Security-Policy "default-src \'self\'; style-src \'self\' \'unsafe-inline\'; script-src \'self\' \'unsafe-inline\'; img-src \'self\' data:"');
header('X-Frame-Options "SAMEORIGIN" always');
header('X-Content-Type-Options nosniff');
header('Referrer-Policy: origin');
header('Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()"');

Voir aussi Cross Origin Ressource Sharing (CORS) avec Access-Control-Allow-Origin.

Protéger l'accès à l'application

modifier

Pour éviter que des robots spammeurs polluent l'application via ses formulaires et ses API, ou la saturent par une attaque par déni de service (DoS attack), il y a plusieurs solutions complémentaires :

  • Filtrer l'accès par un whitelistage d'IP (ex : via iptables).
  • Configurer un throttle dans le serveur Web, qui va empêcher un trop grand nombre de connexions de la même provenance (via iptables aussi).
  • Chiffrer la connexion par un VPN (impossible les utilisateurs prévus sont inconnus et proviennent des moteurs de recherche).
  • Échapper les caractères interprétés lors des attaques de type injection SQL (généralement les apostrophes), et cross-site scripting (alias XSS, qui injecte du JavaScript entre balises HTML "script"), ou clickjacking (balises "iframe"). En échappant les chevrons cela suffit)[1].
  • Imposer aux utilisateurs des mots de passe complexes (c'est-à-dire impossible à deviner par robots avant plusieurs années de tentatives infructueuses).
  • Installer un captcha sur les formulaires accessibles aux utilisateurs non connectés. Par exemple reCAPTCHA, ou sur MediaWiki ConfirmEdit.
  • Filtrer les messages postés sur l'application en les comparant aux listes partagées de spams connus, comme l'API Akismet[2], ou sur MediaWiki TitleBlacklist.
  • Utiliser PHP >= 8 qui protège par défaut contre les attaques XML external entity attack (XXE)[3].

Chiffrer les données sensibles

modifier

Le fait de stocker les mots de passe en clair (non chiffrés), dans un fichier ou une base de connées constitue une faille de sécurité.

Il est donc obligatoire de les chiffrer. Pour réaliser cela, il existe plusieurs fonctions PHP.

Chiffrement symétrique

modifier

Dans le cadre d'échange de données censées être déchiffrées par tout le monde, on peut utiliser base64, ce qui prend 33 % de place en plus que les données encodées[4] :

  • base64_encode()
  • base64_decode()

Mais si on souhaite restreindre le décodage à certains, une cryptographie symétrique peut être assurée avec OpenSSL[5] :

  • openssl_encrypt()
  • openssl_decrypt()

Chiffrement asymétrique

modifier

Le cryptographie asymétrique est plutôt utilisé pour garantir une identité, via une clé privée et une publique. En PHP, selon se traduit par :

  • openssl_public_encrypt()[6]
  • openssl_private_decrypt()

Hachage

modifier
  • hash($algo, $data)[7] : avec un algorithme de la liste hash_algos()[8]. Ex : hash('sha256', $maChaine).
  • crypt()[9] est une fonction de hachage à sens unique d'une chaine, qui accepte en deuxième paramètre optionnel un salage.
  • sha1() : déconseillé car facile à cracker[10].
  • md5() : déconseillé car facile à cracker[11].

Scanners

modifier

Certaines sociétés proposent des pentests payant (en boite noire ou blanche).

Mais un bon outil gratuit permet déjà de se faire une idée : https://observatory.mozilla.org.

Références

modifier


Voir aussi

modifier