Sécurisation de mon code - Demande de conseil

Moderator: Mod

Sécurisation de mon code - Demande de conseil

Postby GOLGOTA » Wed Aug 04, 2010 1:20 pm

Salut :)

Comme dit dans ma présentation, j'ai commencer le développement de mon site. Je commencerais par un blog car c'est rapide à coder 2 petites pages php. J'avais déjà bien bosser sur un site entier auparavant, mais vu la taille du truc et mon immense désire d'aller le plus vite possible, j'ai été vite dégouter car trop d'erreur, beaucoup de failles de sécurité, etc..
Donc là, j'irais étape par étapes, tranquillement, bref !!

Voici le code. Pour information, je dois encore inclure un script anti-bot pour protégé le formulaire de post de commentaire. Et je n'ai protégé la page admin qu'avec un fichier .htaccess, il n'y donc pas encore de script pour enregistrer un admin ou des membres.

Index.php

[code:1:98697cb745]
<?php
//Inclusion du fichier config, nécéssaire pour la connexion à la base de données
include "include/config.php";

//On récupère a, qui est la variable qui nous guidera dans les conditions
if(empty($_GET['a']))
{
$a = NULL;
}
else
{
$a = htmlspecialchars($_GET['a']);
}

if($a == 1)
{
//Si a = 1, c'est qu'on veut afficher un article et ses commentaires
//1. On charge l'article, en ayant pris soin de récupéré son id.
$id = htmlspecialchars($_GET['id']);
$requete = $bdd->prepare('SELECT * FROM article WHERE id = :id');
$requete->execute(array('id' => $id));
$donnees = $requete->fetch();

$titre = htmlspecialchars($donnees['titre']);
$contenu = nl2br(htmlspecialchars($donnees['contenu']));

echo "<fieldset>";
echo "<label>Titre : ". $titre ."</label><br />";
echo "<p>". $contenu ."</p>" ;
echo "</fieldset>";

$requete->closeCursor();

//2. On récupère les commentaires lié à l'id de l'article précédemment charger.
$requetes = $bdd->prepare('SELECT * FROM commentaire WHERE id_article = :id');
$requetes->execute(array('id' => $id));

while ($donnees = $requetes->fetch())
{
$auteur = htmlspecialchars($donnees['auteur']);
$contenu = nl2br(htmlspecialchars($donnees['contenu']));
echo "<fieldset>";
echo "<p><label>". $auteur ." à dit :</label></p>";
echo "<p>". $contenu ."</p>";
echo "</fieldset>";
}
$requetes->closeCursor();

}
if($a == 2)
{
//Si a = 2, c'est qu'on veut poster un nouveau commentaire, on affiche alors un formulaire.
//L'id est transféré au formulaire et on le retransferera directement au traitement des donnnées
//pour lié le commentaire à l'article dans la base de données avec le champ id_article.
$id = htmlspecialchars($_GET['id']);
echo "<form action=\"index.php?a=3&id=". $id ."\" method=\"POST\" />";
?>
<fieldset>
<label>Poster un commentaire :</label><br />
Auteur : <input type="text" name="auteur" /><br />
Contenu :<br />
<textarea name="contenu" id="contenu" row="20" cols="50"></textarea><br />
<input type="submit" value="Poster" />
</fieldset>
</form>
<?
}
if($a == 3)
{
//Si a = 3, on traîte les données reçues.
$id = htmlspecialchars($_GET['id']);
$auteur = htmlspecialchars($_POST['auteur']);
$contenu = htmlspecialchars($_POST['contenu']);

$requete = $bdd->prepare('INSERT INTO commentaire (auteur, contenu, id_article) VALUES (:auteur, :contenu, :id_article) ');
$requete->execute(array(
'auteur' => $auteur,
'contenu' => $contenu,
'id_article' => $id));

echo "Pour revenir sur le message : <a href=\"index.php?a=1&id=". $id ."\">Cliquez ici</a><br />";
echo "Pour revenir sur la page principale : <a href=\"index.php\">Cliquez ici</a><br />";
}
if($a == NULL)
{
//Si a n'a pas de valeur, alors on charge les articles.
$requete = $bdd->query('SELECT * FROM article ORDER BY id DESC Limit 0,50');

while ($donnees = $requete->fetch())
{
$id = htmlspecialchars($donnees['id']);
$titre = htmlspecialchars($donnees['titre']);
$contenu = nl2br(htmlspecialchars($donnees['contenu']));

echo "<fieldset>";
echo "<label>Titre : ". $titre ."</label><br />";
echo "<p>". $contenu ."</p>" ;
echo "<a href=\"index.php?a=1&id=". $id ."\">Voir les commentaires</a></br>";
echo "<a href=\"index.php?a=2&id=".$id ."\">Ajouter un commentaire</a><br />";
echo "</fieldset>";
}
$requete->closeCursor();
}
?>
[/code:1:98697cb745]

La page admin.php

[code:1:98697cb745]
<?php

include "../include/config.php";
if(empty($_GET['a']))
{
$a = NULL;
}
else
{
$a = htmlspecialchars($_GET['a']);
}
if(empty($_GET['i']))
{
$i = NULL;
}
else
{
$i = htmlspecialchars($_GET['i']);
}
switch ($a)
{
//Poster un article
case 1:
?>
<form action="admin.php?a=3&i=1" method="POST">
<fieldset>
<label>Poster un article</label><br />
Le Titre : <input type="text" name="titre" id="titre" /><br />
Le contenu :<br />
<textarea name="contenu" id="contenu" row="20" cols="50"></textarea><br />
<input type="submit" value="Poster" /><br />
</fieldset>
</form>
<?
break;

//Modifier un article
case 2:
$id = htmlspecialchars($_GET['id']);

$requete = $bdd->prepare('SELECT titre, contenu FROM article WHERE id = :id');
$requete->execute(array('id' => $id));
$donnees = $requete->fetch();

$titre = htmlspecialchars($donnees['titre']);
$contenu = nl2br(htmlspecialchars($donnees['contenu']));

echo "<form action=\"admin.php?a=3&i=2&id=". $id ."\" method=\"POST\">";
echo "<fieldset>";
echo "<label>Modifier un article</label><br />";
echo "Le Titre <input type=\"text\" name=\"titre\" value=\"". $titre ."\" /><br />";
echo "Le Contenu :<br />";
echo "<textarea name=\"contenu\" id=\"contenu\" row=\"20\" cols=\"50\">". $contenu ."</textarea><br />";
echo "<input type=\"submit\" value=\"Modifier\" /><br />";
echo "</fieldset>";
echo "</form>";

$requete->closeCursor();
break;

//Traitement des données des articles ajout/modification/suppression
case 3:
if($i == 1)
{
//On post un article
$titre = htmlspecialchars($_POST['titre']);
$contenu = htmlspecialchars($_POST['contenu']);

$requete = $bdd->prepare('INSERT INTO article (titre, contenu) VALUES(?, ?)');
$requete->execute(array($_POST['titre'], $_POST['contenu']));
echo "Article ajouté ! <a href=\"admin.php\">Cliquez ici</a> pour revenir à la page principale";
$requete->closeCursor();
}
if($i == 2)
{
//On modifie un article
$id = htmlspecialchars($_GET['id']);
$titre = htmlspecialchars($_POST['titre']);
$contenu = htmlspecialchars($_POST['contenu']);

$requete = $bdd->prepare('UPDATE article SET titre = :titre, contenu = :contenu WHERE id = :id ');
$requete->execute(array(
'titre' => $titre,
'contenu' => $contenu,
'id' => $id));
echo "Article modifié !<a href=\"admin.php\">Cliquez ici</a> pour revenir à la page principale.";
$requete->closeCursor();
}
if($i == 3)
{
//On supprime un article et ses commentaires.
//1. On supprime les commentaires lié à l'article.
$id = htmlspecialchars($_GET['id']);
$requete = $bdd->prepare('DELETE FROM commentaire WHERE id_article = :id');
$requete->execute(array('id' => $id));
//2. On supprime l'article.
$requete = $bdd->prepare('DELETE FROM article WHERE id = :id');
$requete->execute(array('id' => $id));
echo "L'article et ses commentaires ont bien été supprimés ! <a href=\"admin.php\">Cliquez ici</a> pour revenir à la page principale.";
$requete->closeCursor();
}
else
{
echo "Vous n'avez rien à faire ici.";
}
break;

//Lister les articles
case 4:
$requete = $bdd->query('SELECT id, titre FROM article ORDER BY id DESC');

echo "<table>";
while ($donnees = $requete->fetch())
{
$id = htmlspecialchars($donnees['id']);
$titre = htmlspecialchars($donnees['titre']);
echo "<tr><td>". $id ."</td>
<td>". $titre ."</td>
<td><a href=\"admin.php?a=3&i=3&id=". $id ."\">Supprimer</a></td>
<td><a href=\"admin.php?a=2&id=". $id ."\">Modifier</a></td>
<td><a href=\"admin.php?a=5&id=". $id ."\">Moderer</a></td></tr>";
}
echo "</table>";
$requete->closeCursor();
break;

//Voir un article et ses commentaires
case 5:
$id = htmlspecialchars($_GET['id']);
$requete = $bdd->prepare('SELECT titre, contenu FROM article WHERE id = :id ');
$requete->execute(array('id' => $id));
$donnees = $requete->fetch();

$titre = htmlspecialchars($donnees['titre']);
$contenu = nl2br(htmlspecialchars($donnees['contenu']));

echo "<fieldset>";
echo "<label>". $titre ."</label><br />";
echo "<p>". $contenu ."</p>" ;
echo "<fieldset />";

$requete = $bdd->prepare('SELECT id, auteur, contenu FROM commentaire WHERE id_article = :id');
$requete->execute(array('id' => $id));

while($donnees = $requete->fetch())
{
$idc = $donnees['id'];
$auteur = htmlspecialchars($donnees['auteur']);
$contenu = nl2br(htmlspecialchars($donnees['contenu']));
echo "<fieldset>";
echo "<label>". $auteur ." a dit :</label><br />";
echo "<p>". $contenu ."</p>";
echo "<a href=\"admin.php?a=6&id=". $idc ."\">Supprimer le commentaire ?</a>";
echo "</fieldset>";
}
$requete->closeCursor();
break;

//Supprimer un commentaire
case 6:
$id = htmlspecialchars($_GET['id']);
$requete = $bdd->prepare('DELETE FROM commentaire WHERE id = :id');
$requete->execute(array('id' => $id));

echo "Le commentaire à été supprimer.<br />";
echo "<a href=\"admin.php\">Cliquez ici</a> pour retourner au menu de départ";
$requete->closeCursor();
break;

//Aucun choix n'est fait, on affiche la page d'accueil d'admin
default:
echo "Que voulez-vous faire ?<br />";
echo "<a href=\"admin.php?a=1\">Poster un nouvel article ?</a><br />";
echo "<a href=\"admin.php?a=4\">Voir la liste des articles ?</a><br />";
echo "<a href=\"../index.php\">Retourner sur le blog ?</a><br />";
break;
}
?>
[/code:1:98697cb745]

Et la page config.php ne contenant qu'une seule ligne :

[code:1:98697cb745]
$bdd = new PDO('mysql:host=localhost;dbname=nom_bdd', 'pseudo', 'mot_de_passe_db');
[/code:1:98697cb745]

Voilà, ce que je cherche c'est des conseils, ou mieux une analyse du code qui me dirait là ou je fais des erreurs, autant pour la sécurité que pour faciliter l'utilisation du script.

J'espère ne pas en demander de trop :oops:

Merci d'avance pour vos conseils, votre aide,

Golgota
GOLGOTA
Projets
 
Posts: 23
Joined: Wed Aug 04, 2010 12:15 pm

Postby Manu404 » Wed Aug 04, 2010 8:14 pm

Je te conseil de lire des cours sur l'architecture en php. Le mieux est de premièrement developper une série de classe que tu utilisera pour faire tes request. Ces classes contiennent des classes de connection, configuration, création des user utilisé dans les connections, gestion des droits. ensuite ton fichier de config contient lui des var pour presque "tout". Ca va de l'ip du srv SQL au nom des tables. Tente d'utiliser des design patterns pour résoudre le plus de situation possible avec de modèles éprouvés.
User avatar
Manu404
 
Posts: 2219
Joined: Tue Feb 26, 2008 3:44 pm
Location: ::1:

Postby GOLGOTA » Thu Aug 05, 2010 10:58 am

J'ai fait des recherches et j'commence à comprendre ce que tu me dis :)

L'utilisation des class à l'air vraiment pas mal, ça évite de ré-écrire plein de chose déjà tapées.

Merci, j'vais approfondir tout ça :)
GOLGOTA
Projets
 
Posts: 23
Joined: Wed Aug 04, 2010 12:15 pm

Postby JREM » Thu Aug 05, 2010 11:33 am

Salut, je voulais rajouter qu'on utilise "mysql_real_escape_string" pour protéger ses requêtes de l'injection sql.
JREM
Projets
 
Posts: 60
Joined: Sun Aug 03, 2008 8:58 pm

Postby GOLGOTA » Thu Aug 05, 2010 12:38 pm

Ha ! Merci :)

Je vais corriger ça :D
GOLGOTA
Projets
 
Posts: 23
Joined: Wed Aug 04, 2010 12:15 pm


Return to Php

Who is online

Users browsing this forum: No registered users and 2 guests

cron