# Programmation PHP/Sécurité

* Introduction
* Installer PHP
* Composer
* IDE
** PhpStorm
** NetBeans
** Eclipse
** Visual Studio Code
* Bases du langage
** Commentaires
** Premier programme
** Variables
** Variables superglobales
** Constantes
** Opérateurs
** Fonctions
** Tableaux
** Structures de contrôle
** Boucles
* Programmation avancée
** Dates
** Sessions
** Cookies
** Cache
*** Memcached
*** Redis
** Formulaire
** Fichiers
*** Objets COM
*** Images
** Mails
** Sécurité
** Programmation orientée objet
** Bases de données
*** Microsoft SQL Server
*** MySQL
*** PDO
*** SQLite
** Expressions rationnelles
** Code de haute qualité
*** Analyse statique de programmes
** Exceptions
** Xdebug
** Mots réservés
* Apprendre par l'exemple
** Utilisation de variables
** Un sommaire simple
** Interaction avec un formulaire
** Afficher le résultat d'une requête BDD
** Modifier une table
** Faire un livre d'or
** Faire un mini forum de discussion
** Parser avec DomXml
** Coder en MVC
** Faire un webservice
** Vérification RIO
** AJAX
** Sommaire en Ajax
** Mise à jour périodique d'un cadre
** Mini CMS
** Introduction
** Développement
*** Les couches choisies
*** Code de service
*** Modélisation
*** Implémentation
*** La vue
*** Ajaxification
*** Premier noyau
*** Fournir les données
*** IHM
** Rétrospective
** Conclusion
* Extensions PHP
** cURL
** DOMDocument
** JSON
** MING
** SPL
* Bibliothèques externes
** ADODB
** DOMPDF
** FPDF
** PHPExcel
** PHPMailer
** PHPWord
** RabbitMQ
* Cadriciels
** CakePHP
** PEAR
** Symfony
** Frameworks de tests
*** PHPUnit
*** SimpleTest
*** Behat
* Logiciels métier
* Problèmes connus
* Introduction
* Installer PHP
* Composer
* IDE
** PhpStorm
** NetBeans
** Eclipse
** Visual Studio Code
* Bases du langage
** Commentaires
** Premier programme
** Variables
** Variables superglobales
** Constantes
** Opérateurs
** Fonctions
** Tableaux
** Structures de contrôle
** Boucles
* Programmation avancée
** Dates
** Sessions
** Cookies
** Cache
*** Memcached
*** Redis
** Formulaire
** Fichiers
*** Objets COM
*** Images
** Mails
** Sécurité
** Programmation orientée objet
** Bases de données
*** Microsoft SQL Server
*** MySQL
*** PDO
*** SQLite
** Expressions rationnelles
** Code de haute qualité
*** Analyse statique de programmes
** Exceptions
** Xdebug
** Mots réservés
* Apprendre par l'exemple
** Utilisation de variables
** Un sommaire simple
** Interaction avec un formulaire
** Afficher le résultat d'une requête BDD
** Modifier une table
** Faire un livre d'or
** Faire un mini forum de discussion
** Parser avec DomXml
** Coder en MVC
** Faire un webservice
** Vérification RIO
** AJAX
** Sommaire en Ajax
** Mise à jour périodique d'un cadre
** Mini CMS
** Introduction
** Développement
*** Les couches choisies
*** Code de service
*** Modélisation
*** Implémentation
*** La vue
*** Ajaxification
*** Premier noyau
*** Fournir les données
*** IHM
** Rétrospective
** Conclusion
* Extensions PHP
** cURL
** DOMDocument
** JSON
** MING
** SPL
* Bibliothèques externes
** ADODB
** DOMPDF
** FPDF
** PHPExcel
** PHPMailer
** PHPWord
** RabbitMQ
* Cadriciels
** CakePHP
** PEAR
** Symfony
** Frameworks de tests
*** PHPUnit
*** SimpleTest
*** Behat
* Logiciels métier
* Problèmes connus
[ Modifier le sommaire ]

## Sécuriser les en-têtes HTTP

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

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 :

### Restreindre les connexions

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) :
Voir aussi Cross Origin Ressource Sharing (CORS) avec Access-Control-Allow-Origin.

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

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).
* 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, ou sur MediaWiki TitleBlacklist.
* Utiliser PHP >= 8 qui protège par défaut contre les attaques XML external entity attack (XXE).

## Protéger les données sensibles

Le fait de stocker les mots de passe en clair, dans un fichier ou une base de connées constitue une faille de sécurité.
Il est donc obligatoire de les hasher. Pour réaliser cela, il existe plusieurs fonctions PHP:
* hash($algo, $data) : avec un algorithme de la liste hash_algos. Ex : hash('sha256', $maChaine). Déconseillé car pas adapté pour les mots de passe.
* crypt est une fonction de hachage à sens unique d'une chaine, qui accepte en deuxième paramètre optionnel un salage. Déconseillé car vulnérable à certaines attaques.
* sha1 : déconseillé car facile à casser.
* md5 : déconseillé car facile à casser.
La méthode actuellement recommandée pour hasher un mot de passe est l'utilisation de la fonction password_hash conjointement avec password_verify pour vérifier si un mot de passe saisi par l'utilisateur est correct.

## Scanners

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

* ↑ https://github.com/WebGoat/WebGoat
* ↑ https://symfony.com/doc/current/the-fast-track/fr/16-spam.html
* ↑ https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#php
* ↑ https://www.php.net/manual/fr/function.hash.php
* ↑ https://www.php.net/manual/fr/function.hash-algos.php
* ↑ http://php.net/manual/fr/function.crypt.php
* ↑ https://www.php.net/manual/fr/function.sha1.php
* ↑ https://www.php.net/manual/fr/function.md5.php
* ↑ https://www.php.net/manual/fr/function.password-hash.php
* ↑ https://www.php.net/manual/fr/function.password-verify.php

## Voir aussi

* Sécurité des systèmes informatiques
* Introduction au test logiciel/Tests d'intrusion