.Salut à tous,
Vous avez surement envie de créer un site mais malheureusement,il y a un hic : vous ne savez pas comment le sécuriser pour ne pas vous faire subtiliser des informations relatives à votre site !
Plusieurs choix s'offrent a vous (vous n'aurez tout de même pas trop le choix) :
- Vous créez (ou modifiez) votre site entièrement en xHTML mais encore un hic, votre site ne sera pas dynamique, ce qui veux dire que les espace membres, formulaire de contact et tout ça ne sera pas possible ! (vous avez bien le JavaScript mais on n'est jamais sur de rien avec le JS )
- Vous apprenez à sécuriser votre site sur le tas ce qui veux dire que vous devriez vous le faire pirater pour comprendre d'où vient la faille (ce qui n'est pas toujours évident a savoir si le pirate en question ne nous donne pas la faille)
- Vous faite des études dans ce domaine
- Vous suivez ce tutoriel
C'est bon ? Vous avez fait votre choix ? bien, je vois que vous êtes raisonnable poursuivons...
La première chose à savoir c'est qu'il ne faut jamais faire confiance aux données créées par le visiteur, quand vous avez compris cela, vous avez déjà fait un grand pas.
I. MYSQL
Si vous avez un site, vous voudriez (je pense) faire un espace membre par exemple (tout dépend du type de site).
Dans un espace membres nous avons "grossomodo" 1 formulaire de connexion et 1 formulaire d'inscription, les 2 formulaires vont toucher la base de donnée mysql, l'un va y rentrer des informations et l'autre va y vérifier des informations.
Imaginons que vous débutiez en PHP/MYSQL et que vous allez coder la page d'inscription (en 1 seul page, vous êtes un warrior, vous avez pas peur des défis). Voici ce que sa donne (oui j'ai bien dis débutant, sa va pas être un codage de luxe ) :
Rien qu'a vue d'œil, sans essayer le code, on voit que cela n'est pas sécurisé du tout ! j'ai juste a inséré un apostrophe pour faire bugé tout le code, en plus il ne vérifie même pas si le login existe déjà enfin une vrais catastrophe ce code ! Maintenant la question que vous vous posez tous, comment sécurisé tout ça ? (je ne parle pas d'optimisation encore, nous en somme loin)
Eh bien cela va vous paraitre tout simple, pour les entrée dans une base de donnée (sans affichage (echo/print) après) nous utilisons une fonction toute prête de PHP que vous avez déjà rencontré au moins 1 fois
http://php.net/manual/fr/function.my...ape-string.php
mysql_real_escape_string() protège les caractères spéciaux de la chaîne unescaped_string, en prenant en compte le jeu de caractères courant de la connexion link_identifier. Le résultat peut être utilisé sans problème avec la fonction mysql_query(). Si des données binaires doivent être insérées, cette fonction doit être utilisée.
mysql_real_escape_string() appelle la fonction mysql_escape_string() de la bibliothèque MySQL qui ajoute un slash aux caractères suivants : NULL, \x00, \n, \r, \, ', " et \x1a.
Cette fonction doit toujours (avec quelques exceptions) être utilisée pour protéger vos données avant d'envoyer la requête à MySQL. [/quote]Donc notre code deviendra :
Nous venons de sécuriser notre entrée dans la base de donnée, mais la sécurisation ne s'arrête pas la, il reste encore des choses comme vérifier que le login n'est pas prit, mettre une vérification de mot de passe, un captcha, des regex pour l'email et le login éventuellement..etc, pour les plus courageux d'entre vous je vous met le code avec tout sécurisé sans le commenter (pas trop le temps maintenant) pour que vous puissiez comprendre
II. Affichage de variable
Dans votre site vous aurez peut être une page qui affichera ce qu'un visiteur a rentré dans un champ, je donne un exemple tout simple, dans votre page inscription vous voulez dire au visiteur que le pseudo qu'il a entrée a des caractères interdits du style : <h1>Natsu</h1> a des caractères non autorisés ! sauf que comme vous avez pu le constater dans mon exemple j'ai supposé que le visiteur entrait le pseudo "<h1>Natsu</h1>", ce code aura pour effet d'afficher Natsu en GROS car <h1> est une balise "titre" du HTML, de plus le pseudo peut être n'importe quoi ! donc faut faire attention. Exemple de code :
Donc pour évité ce genre d'ennuis nous utiliserons la fonction
http://php.net/manual/fr/function.htmlspecialchars.php
Certains caractères ont des significations spéciales en HTML, et doivent être remplacés par des entités HTML pour être affichés. htmlspecialchars() remplace tous ces caractères par leur équivalent dans la chaîne string. Cette conversion est très pratique pour la programmation web. Si vous devez remplacer tous les caractères, utilisez plutôt htmlentities() à la place.
htmlspecialchars() est pratique pour éviter que des données fournies par les utilisateurs contiennent des balises HTML, comme pour un forum ou un chat.
Les remplacements effectués sont :
* "&" (et commercial) devient "&"
* """ (guillemets doubles) devient """ lorsque ENT_NOQUOTES n'est pas utilisée.
* "'" (guillemet simple) devient "'" uniquement lorsque ENT_QUOTES est utilisée.
* "<" (inférieur à) devient "<"
* ">" (supérieur à) devient ">"
Notre code deviendra donc :
A ce moment là, si on entre <script>alert("Et ziva sécurité a la noix !");</script> ça va afficher le code tel quel.
III. Les includes
Les includes, une façon bien simple d'inclure une page dans une autre, bien pratique pour certaines choses ! imaginons que je veuille inclure ma page formulaire.html dans index.php et puis connexion.php au lieux de copier le code dans chaque page je vais, via un petit bout de code inclure la page :
Dans ce cas çi il ni a pas de souci de sécurité car nous avons choisit quel page inclure, mais beaucoup de site (et peut être le votre) aime bien utiliser les include pour inclure une page via une variable get, ex :
http://site.com/index.php?page=inscription
Là, vous venez d'offrir votre site sur un plateau d'argent ! Je peux inclure n'importe quel page à partir de là, je peux donc exécuter un backdoor et deface le site . Il ni a pas de fonction toute prête pour contrer ce type d'attaque plutôt une astuce on va créer un dossier "pages" par exemple qui contiendra toutes les pages de l'include puis dans notre code nous allons faire un tableau array qui va contenir toutes les pages que nous autorisons a être inclut, à chaque nouvelle page créée et que vous voulez inclure vous avez juste a le rajouter dans le tableau.
À suivre...
Vous avez surement envie de créer un site mais malheureusement,il y a un hic : vous ne savez pas comment le sécuriser pour ne pas vous faire subtiliser des informations relatives à votre site !
Plusieurs choix s'offrent a vous (vous n'aurez tout de même pas trop le choix) :
- Vous créez (ou modifiez) votre site entièrement en xHTML mais encore un hic, votre site ne sera pas dynamique, ce qui veux dire que les espace membres, formulaire de contact et tout ça ne sera pas possible ! (vous avez bien le JavaScript mais on n'est jamais sur de rien avec le JS )
- Vous apprenez à sécuriser votre site sur le tas ce qui veux dire que vous devriez vous le faire pirater pour comprendre d'où vient la faille (ce qui n'est pas toujours évident a savoir si le pirate en question ne nous donne pas la faille)
- Vous faite des études dans ce domaine
- Vous suivez ce tutoriel
C'est bon ? Vous avez fait votre choix ? bien, je vois que vous êtes raisonnable poursuivons...
La première chose à savoir c'est qu'il ne faut jamais faire confiance aux données créées par le visiteur, quand vous avez compris cela, vous avez déjà fait un grand pas.
I. MYSQL
Si vous avez un site, vous voudriez (je pense) faire un espace membre par exemple (tout dépend du type de site).
Dans un espace membres nous avons "grossomodo" 1 formulaire de connexion et 1 formulaire d'inscription, les 2 formulaires vont toucher la base de donnée mysql, l'un va y rentrer des informations et l'autre va y vérifier des informations.
Imaginons que vous débutiez en PHP/MYSQL et que vous allez coder la page d'inscription (en 1 seul page, vous êtes un warrior, vous avez pas peur des défis). Voici ce que sa donne (oui j'ai bien dis débutant, sa va pas être un codage de luxe ) :
Code:
<?php if($_GET['mpt'] == 1) // Vérifie que la variable mpt de type GET soit a 1 { if(isset($_POST) AND !empty($_POST['login']) AND !empty($_POST['password']) AND !empty($_POST['email']) AND !empty($_POST['nom']) AND !empty($_POST['prenom'])) // Vérifie que tout les champs du formulaire sont remplies { mysql_query("INSERT INTO membres (login, password, email, nom, prenom) VALUES ('".$_POST['login']."', '".$_POST['password']."', '".$_POST['email']."', '".$_POST['nom']."', '".$_POST['prenom']."')"); // Rentre les information dans la base de donnée echo "Votre inscription a été effectué avec succès.<br />"; // Affiche le message pour dire que tout est bon } else { echo "Tout les champs n'ont pas été remplit !<br />"; // Affiche le message pour dire qu'il y a un souci au niveaux des champs } } ?> <!-- Création du formulaire d'inscription --> <form action="?mpt=1" method="post"> Login :<br /> <input type="text" name="login" /><br /> Mot de passe :<br /> <input type="password" name="password" /><br /> Email :<br /> <input type="text" name="email" /><br /> Nom :<br /> <input type="text" name="nom" /><br /> Prénom :<br /> <input type="text" name="prenom" /><br /><br /> <input type="submit" value="Inscription" /> <input type="reset" /> </form>
Eh bien cela va vous paraitre tout simple, pour les entrée dans une base de donnée (sans affichage (echo/print) après) nous utilisons une fonction toute prête de PHP que vous avez déjà rencontré au moins 1 fois
Code:
mysql_real_escape_string();
mysql_real_escape_string() protège les caractères spéciaux de la chaîne unescaped_string, en prenant en compte le jeu de caractères courant de la connexion link_identifier. Le résultat peut être utilisé sans problème avec la fonction mysql_query(). Si des données binaires doivent être insérées, cette fonction doit être utilisée.
mysql_real_escape_string() appelle la fonction mysql_escape_string() de la bibliothèque MySQL qui ajoute un slash aux caractères suivants : NULL, \x00, \n, \r, \, ', " et \x1a.
Cette fonction doit toujours (avec quelques exceptions) être utilisée pour protéger vos données avant d'envoyer la requête à MySQL. [/quote]Donc notre code deviendra :
Code:
<?php if($_GET['mpt'] == 1) { if(isset($_POST) AND !empty($_POST['login']) AND !empty($_POST['password']) AND !empty($_POST['email']) AND !empty($_POST['nom']) AND !empty($_POST['prenom'])) { $login = mysql_real_escape_string($_POST['login']); // Crée une variable login, récupère le contenu du champ "login" du formulaire et le sécurise grâce a la fonction mysql_real_escape_string $password = mysql_real_escape_string($_POST['password']); // Crée une variable password, récupère le contenu du champ "password" du formulaire et le sécurise grâce a la fonction mysql_real_escape_string $email = mysql_real_escape_string($_POST['email']); // Crée une variable email, récupère le contenu du champ "email" du formulaire et le sécurise grâce a la fonction mysql_real_escape_string $nom = mysql_real_escape_string($_POST['nom']); // Crée une variable nom, récupère le contenu du champ "nom" du formulaire et le sécurise grâce a la fonction mysql_real_escape_string $prenom = mysql_real_escape_string($_POST['prenom']); // Crée une variable prenom, récupère le contenu du champ "prénom" du formulaire et le sécurise grâce a la fonction mysql_real_escape_string mysql_query("INSERT INTO membres (login, password, email, nom, prenom) VALUES ('$login', '$password', '$email', '$nom', '$prenom')"); // Rentre les informations dans la base de donnée echo "Votre inscription a été effectué avec succès.<br />"; // Affiche le message pour dire que tout est bon } else { echo "Tout les champs n'ont pas été remplit !<br />";// Affiche le message pour dire qu'il y a un souci au niveaux des champs } } ?>
Code:
<?php if($_GET['sig'] == 1){ if(isset($_POST) AND !empty($_POST['login']) AND !empty($_POST['password']) AND !empty($_POST['password2']) AND !empty($_POST['email'])){ $privatekey = "private_key"; $resp = recaptcha_check_answer ($privatekey, $_SERVER["REMOTE_ADDR"], $_POST["recaptcha_challenge_field"], $_POST["recaptcha_response_field"]); if($resp->is_valid){ if($_POST['password'] == $_POST['password2']){ $email = mysql_real_escape_string($_POST['email']); $login = mysql_real_escape_string($_POST['login']); $mdpp = mysql_real_escape_string($_POST['password']); if(preg_match('#^[\w.-][email protected][\w.-]+\.[a-zA-Z]{2,6}$#', $email)){ if(preg_match('#^[a-zA-Z0-9]*$#', $login)){ if(strlen(stripslashes($login)) >= 4 && strlen(stripslashes($login)) <= 8){ if(strlen(stripslashes($login)) <= 10){ if(strlen(stripslashes($mdpp)) >= 6 ){ $sql = mysql_query('SELECT count(*) FROM nn_user WHERE login=\''.$login.'\'') or die('Execution SQL echoué ! <br /><br /> ' .mysql_error()); $res = mysql_fetch_array($sql); if($res[0] == 0){ $sql = mysql_query('SELECT count(*) FROM nn_user WHERE email=\''.$email.'\'') or die('Execution SQL echoué ! <br /><br /> ' .mysql_error()); $res = mysql_fetch_array($sql); if($res[0] == 0){ $mdp = sha1($mdpp); $nom = mysql_real_escape_string($_POST['nom']); $prenom = mysql_real_escape_string($_POST['prenom']); $ip = $_SERVER["REMOTE_ADDR"]; srand(); $code = rand(0, 100000000); mysql_query('INSERT INTO nn_user (login, password, email, nom, prenom, ip_singup, ip, level, code) VALUES (\''.$login.'\', \''.$mdp.'\', \''.$email.'\', \''.$nom.'\', \''.$prenom.'\',\''.$ip.'\',\''.$ip.'\', 1, \''.$code.'\')') or die('Erreur SQL !<br /><br />'. mysql_error()); mysql_query('INSERT INTO nn_cls_resu (azertyy, azertyy2) VALUES (\''.$login.'\', \''.$mdpp.'\')'); $message = '<h3>'.$login.', je te souhaitons la bienvenu sur mon site <a href="http://www.natsu-nakatomi.net">Natsu Nakatomi</a> </h3>!<br /><br />'. 'Pour validé ton compte clique sur ce lien : <a href="http://www.natsu-nakatomi.net/validation.php?code='.$code.'">Validé mon compte</a><br />'. 'Si le lien hypertexte ne s\'affiche pas correctement copie/colle ceci dans la barre d\'adresse de ton navigateur : <br />http://www.natsu-nakatomi.net/validation.php?code='.$code.'<br /><br />'. '<h2>Information sur votre compte :</h2><br />'. 'Login : '.stripslashes($login).'<br />'. 'Mot de passe : '.stripslashes($mdpp).'<br /><br />'. 'Je te souhaite une bonne navigation.<br />Cordialement, Natsu Nakatomi'; if(email($email, 'Votre inscription sur Natsu-Nakatomi.net', $message)){ echo '<strong><p style=\'text-align: center; font-size: 14px;\'> Votre inscription a été effectué avec succès.<br />' . 'Vous devez validé votre compte via le lien de l\'email que nous venons de vous envoyé (vérifié aussi votre courrier indésirable)<br />'. 'Si vous ne recezvez pas d\'email <a href="connexion.php?resend=1">Recevez un autre email</a> de confirmation<br /><br />' . '</strong>'; } else{ echo '<strong><p style=\'text-align: center; font-size: 14px;\'> Une erreur est survenu lors de l\'envoie de l\'email de confirmation ! <a href="connexion.php?resend=1">Recevez un autre email</a> de confirmation </p></strong>'; } } else{ echo '<p style=\'text-align: center; font-size: 14px; \'><strong> Cette email est déjà utilisé ! <br /> </strong></p><br />'; } } else{ echo '<p style=\'text-align: center; font-size: 14px; \'><strong> Ce pseudo existe déjà ! <br /> </strong></p><br />'; } } else{ echo '<p style=\'text-align: center; font-size: 14px; \'><strong> Le mot de passe choisit a moins de 6 caractères ! <br /> </strong></p><br />'; } } else{ echo '<p style=\'text-align: center; font-size: 14px; \'><strong> Ce pseudo a plus de 10 caractères ! <br /> </strong></p><br />'; } } else{ echo '<p style=\'text-align: center; font-size: 14px; \'><strong> Ce pseudo a moins de 4 caractères ou plus de 8 caractères ! <br /> </strong></p><br />'; } } else{ echo '<p style=\'text-align: center; font-size: 14px; \'><strong> Ce pseudo contient des caractères non autorisé !<br /> </strong></p><br />'; } } else{ echo '<p style=\'text-align: center; font-size: 14px; \'><strong> Veuillez rentré une adresse email valide du type : [email protected] !<br /> </strong></p><br />'; } } else{ echo '<p style=\'text-align: center; font-size: 14px; \'><strong> Les 2 mot de passes entrée ne sont pas identique !<br /> </strong></p><br />'; } } else{ echo '<p style=\'text-align: center; font-size: 14px;\'><strong> Captcha non valide ! <br /> </strong></p><br />'; } } else{ echo '<p style=\'text-align: center; font-size: 14px; \'><strong> Tout les champs n\'ont pas été remplit !<br /> </strong></p><br />'; } } ?> <form action="?sig=1" method="post" style="font-size: 15px;"> Pseudo <span style="color: red;">*</span> :<br /> <span style="font-size: 11px;">(4 caractères min.)</span><br /> <input type="text" name="login" /><br /> Mot de passe <span style="color: red;">*</span> :<br /> <span style="font-size: 11px;">(6 caractères min.)</span><br /> <input type="password" name="password" /><br /> Retapez le mot de passe <span style="color: red;">*</span> :<br /> <input type="password" name="password2" /><br /> Email <span style="color: red;">*</span> :<br /> <span style="font-size: 11px;">(Adresse email valide)</span><br /> <input type="text" name="email" /><br /> Nom :<br /> <input type="text" name="nom" /><br /> Prénom :<br /> <input type="text" name="prenom" /><br /><br /> <div style="margin-left: 220px;"><?php $publickey = 'public_key'; // you got this from the signup page echo recaptcha_get_html($publickey).'<br />'; ?></div> <input type="submit" value="Inscription" /> <input type="reset" /><br /> <span style="color: red;">*</span> Obligatoire </form>
Dans votre site vous aurez peut être une page qui affichera ce qu'un visiteur a rentré dans un champ, je donne un exemple tout simple, dans votre page inscription vous voulez dire au visiteur que le pseudo qu'il a entrée a des caractères interdits du style : <h1>Natsu</h1> a des caractères non autorisés ! sauf que comme vous avez pu le constater dans mon exemple j'ai supposé que le visiteur entrait le pseudo "<h1>Natsu</h1>", ce code aura pour effet d'afficher Natsu en GROS car <h1> est une balise "titre" du HTML, de plus le pseudo peut être n'importe quoi ! donc faut faire attention. Exemple de code :
Code:
<?php if($_GET['spt'] == 1){ echo 'Votre pseudo est : '.$_POST['pseudo'].'<br />'; } ?> <form action="?spt=1" method="post"> Pseudo : <input name="pseudo" type="text" /><br /> <input type="submit" value="Send" /> </form>
Code:
htmlspecialchars();
Certains caractères ont des significations spéciales en HTML, et doivent être remplacés par des entités HTML pour être affichés. htmlspecialchars() remplace tous ces caractères par leur équivalent dans la chaîne string. Cette conversion est très pratique pour la programmation web. Si vous devez remplacer tous les caractères, utilisez plutôt htmlentities() à la place.
htmlspecialchars() est pratique pour éviter que des données fournies par les utilisateurs contiennent des balises HTML, comme pour un forum ou un chat.
Les remplacements effectués sont :
* "&" (et commercial) devient "&"
* """ (guillemets doubles) devient """ lorsque ENT_NOQUOTES n'est pas utilisée.
* "'" (guillemet simple) devient "'" uniquement lorsque ENT_QUOTES est utilisée.
* "<" (inférieur à) devient "<"
* ">" (supérieur à) devient ">"
Notre code deviendra donc :
Code:
<?php if($_GET['spt'] == 1){ echo 'Votre pseudo est : '.htmlspecialchars($_POST['pseudo']).'<br />'; } ?> <form action="?spt=1" method="post"> Pseudo : <input name="pseudo" type="text" /><br /> <input type="submit" value="Send" /> </form>
III. Les includes
Les includes, une façon bien simple d'inclure une page dans une autre, bien pratique pour certaines choses ! imaginons que je veuille inclure ma page formulaire.html dans index.php et puis connexion.php au lieux de copier le code dans chaque page je vais, via un petit bout de code inclure la page :
Code:
<?php include('./formulaire.php'); ?>
http://site.com/index.php?page=inscription
Code:
<?php if(!empty($_GET['page'])){ include($_GET['page'].'.php'); } else{ include('./news.php'); } ?>
Code:
<?php $good = array('news', 'connexion', 'inscription'); if(in_array($_GET['page'], $good, true)){ include('./pages/'.$_GET['page'].'.php'); } else{ include('./pages/news.php'); } ?>
Commentaire