La sécurité dans le mkframework

Introduction

La sécurité est un point à ne pas négliger surtout lorsque l'on fait une application web "publique" qui pourra faire l'objet de nombreuses attaques.
Pour nous prévenir des failles les plus communes (Xss,Xsrf/Sql injection...) il existe des conventions/bonnes pratiques plus ou moins connu des développeurs.
Travaillant depuis plusieurs années avec une société de sécurité qui audite certaines de nos applications, j'ai implémenté au fur et à mesure ces recommandations sur le mkframework pour vous proposer un framework le plus sécurisé possible.

Concernant le Xss/Css/null byte

Le xss consistant à utiliser un paramètre (GET/POST...) pour modifier le site, le framework propose d'utiliser la méthode _root::getParam() à la place des variables globales $_GET/$_POST
Le contenu retourné par _root::getParam() filtre les entrées des attaques XSS mais également des attaques de type null byte


  
$id
=_root::getParam('id'); //a la place de $id=$_GET['id'];
//idem pour le POST
$titre=_root::getParam('titre'); //a la place de $titre=$_POST['titire'];
    



Plus d'informations sur le Xss/Css: http://fr.wikipedia.org/wiki/Cross-site_scripting


Concernant le Xsrf/Csrf

Le xsrf est un peu plus vicieux, il permet de soumettre une requête à la place d'un utilisateur, pour vous protéger de cette attaque, le framework propose un plugin: plugin_xsrf.
Celui-ci génère un jeton et propose une méthode pour vérifier sa validité.

note: vous pouvez renforcer cette sécurité en activant la variable xsrf.session.enabled=1 dans la section [security] dans le fichier de configuration conf/site.ini.php
Celle-ci nécessite d'avoir une session ouverte (le jeton étant stoqué en session pour garantir son utilisation unique)

note 2: pensez à modifier le sel present dans le constructeur du plugin plugin_xsrf
Modifiez cette propriété pour la rendre unique:

  
public function plugin_xsrf(){
   $this->sSalt='fdsfhoyu679hjfdsAfef';
   (...)
}
    



Tutorial ici http://mkdevs.com/tutoriaux.html#token

Plus d'informations sur le Xsrf/Csrf: http://fr.wikipedia.org/wiki/Cross-site_request_forgery


Concernant l'injection SQL

L'injection consistant à profiter d'une requête pour en modifier le but (récupérer les identifiants, faire des modifications en base...).
Le framework utilise les "prepared statement" de Pdo pour vous protéger de ce type d'attaque.


  
//pour une requete recuperant un auteur par son id
public function findById($id){
   return $this->findOne('SELECT FOM auteur WHERE id=?',$id);
}
    



Plus d'informations sur l'SQL injection http://fr.wikipedia.org/wiki/Injection_SQL

Les bonnes pratiques non implémentées dans le framework, à la charge du développeur

Désactivez l'auto complétion sur les champs d'identification

Il est recommandé d'utiliser l'attribut autocomplete="off" dans vos champs input d'authentification.
Les internautes peuvent se connecter via des sites "publiques" (cyber café, hotels...) et il serait peu sécurisé que le login soit enregistré sur l'ordinateur.


  
<input autocomplete="off" name="utilisateur" />
    



Passez votre site en mode production

Editez le fichier conf/mode.ini.php
Et mettez en valeur "production" plutot que "dev"

  
[site]
mode=production
   


Ceci permet de cacher les erreurs php, à la place, ils sont ajoutés dans le fichier de log
Vous pouvez d'ailleurs paramétrer dans le ficheir conf/site.ini.php où consigner les erreurs de "production"

  
file
.enabled=1
apache
.enabled=1
   



Gérer une politique de mauvaise authentification

Afin d'éviter les intrusions par "brute force", il faut pour limiter ce type d'attaque:
- bloquer totalement un compte au bout d'un nombre d'authentification infructueuse
- suspendre le compte pendant un temps défini (l'obligeant à attendre pour se connecter)
- ajouter un Captcha en cas d'erreur, qui limitera les robots de "brute force"
- selon un nombre de tentatives de connexions/minute: interdire l'IP utilisé par l'auteur

note: attention au blocage de compte, ils peuvent être utilisée pour des attaques DDOS* (en bloquant l'ensemble des comptes)
note 2: afin d'éviter les DDOS sur le hashage de mot de passe, vérifier que le mot de passe proposé ne dépasse pas au minimum 100 caractères: sinon on peut vous envoyer en boucle des mots de passe de N milliers de caractères que votre serveur mettra du temps à hasher pour faire tomber celui-ci
Note 3: le générateur web (builder) permet de générer un module d'authentification

Plus d'informations sur le DDOS http://fr.wikipedia.org/wiki/Attaque_par_d%C3%A9ni_de_service

Bien gérer l'isolation des données

Sur un site web de gestion d'email par exemple, il ne serait pas agréable qu'un utilisateur puisse voir ou répondre aux emails d'un autre.
Pour cela, il faut gérer l'isolation des données: vérifier à chaque fois que vous listez des données ou affichez le détail de l'une d'entre elles qu'elle appartient bien à l'utilisateur connecté.

Interdire la mise en frame/iframe de votre site web

Si un site hacké inclut une iframe vers un formulaire de votre site, et qu'un utilisateur connecté dans un autre onglet se rend sur le site, le hackeur peut, via javascript soumettre le formulaire à l'insu de l'internaute.
Pour cela, apache inclut une directive prise en compte par la majorité des navigateurs ( supérieur à ie7)

  
Header set X
-Frame-Options"sameorigin"
    


Qui peut prendre plusieurs valeurs: même domaine autorisé, non autorisé...

Conclusion

Comme vous avez pu le lire, je continue régulièrement à faire de la veille sur la sécurité et prendre en compte les recommandations de société de sécurité avec qui nous travaillons.