JeuWeb - Crée ton jeu par navigateur
Sécurité qui casse tout - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Sécurité qui casse tout (/showthread.php?tid=2252)

Pages : 1 2


Sécurité qui casse tout - Malako - 06-01-2008




RE: Sécurité qui casse tout - Sephi-Chan - 06-01-2008

Code PHP :
<?php 
if($faction != 'Robots' && $faction != 'Humains'){
echo
'<p>Erreur : '.$faction." n'est pas une faction valide.</p>";
exit;
}
else {
echo
'<p>Correct : '.$faction.' est une faction valide.</p>';
/* Suite du script. */
}
Ça, ça marche (j'ai testé). Ça refoule ceux qui ont n'ont pas l'un des deux noms. C'était un problème d'évaluation. Avec un OR, l'une des proposition était toujours vrai.

Si tu veux tout de même utiliser un OR, voici la solution :
Code PHP :
<?php 
if($faction == 'Robots' || $faction == 'Humains'){
echo
'<p>Correct : '.$faction.' est une faction valide.</p>';
/* Suite du script. */
}
else {
echo
'<p>Erreur : '.$faction." n'est pas une faction valide.</p>";
exit;
}

Par contre, concernant la sécurité, il y a des trucs que tu n'as pas saisi. Explique-nous pourquoi tu mets des htmlentities(), s'il te plaît. Ça nous permettra de t'aider à y voir plus clair.


Sephi-Chan


RE: Sécurité qui casse tout - Malako - 06-01-2008

Ba j'ai lu que ca eviter d'executer du php du genre OR 1='1' ^^


RE: Sécurité qui casse tout - Sephi-Chan - 06-01-2008

Documentation PHP - htmlentities()


RE: Sécurité qui casse tout - Malako - 06-01-2008

J'ai du confondre avec htmlspecialchars() non ? Smile

ps : j'avais déjà lu ça, mais merci comme même Wink


RE: Sécurité qui casse tout - Sephi-Chan - 06-01-2008

Non, ils n'ont pas la même utilité (bien que très proche). Ce que je veux dire, c'est que tu en mets partout alors que ça ne sert à rien. J'éditerai ce post au fur et à mesure en reprenant point par point ton script.

Code PHP :
<?php 
$_SESSION
['pseudo'] = htmlentities($_SESSION['pseudo']);
if (isset(
$_SESSION['connect']))//On vérifie que le variable existe
{
$connect=$_SESSION['connect'];//On récupère la valeur de la variable de session
}
else
{
$connect=0;//Si $_SESSION['connect'] n'existe pas, on donne la valeur "0"
}
if (
$connect == "1") // Si le visiteur s'est identifié
{ ?><div id="corps"><?php
echo 'Vous êtes déjà inscris '.$_SESSION['pseudo'].''; exit;
}
?>
Déjà, dès le début, une ligne de trop. Ensuite, voici un moyen simple d'écourter énormément ton script. Quand ton joueur se connecte, tu vérifies s'il existe bien une entre dans la base de donnée ayant le nom et le mot de passe qu'il a donné dans le formulaire. Si oui, tu lui attribue une variable de session contenant son identifiant et une pour son pseudo.

Voici un exemple de fonction de connexion :
Code PHP :
<?php 
function connect($name, $password){
// On vérifie qu'il existe une entrée qui a le nom et le mot de passe indiqué.
$query = sprintf("SELECT id, name FROM player WHERE `name` = '%s' AND `password` = '%s';",
mysql_real_escape_string($name), // On sécurise la chaîne de caractère avec la fonction faîte pour ça.
sha1($password) // Comme le mot de passe est crypté en SHA1 dans la base, on compare le SHA1 du mot de passe donné, pas le mot de passe directement.
);

if(
$sql = mysql_query($query)){ // On effectue la requête dans un if, pour pouvoir effectuer des actions dans le else en cas d'échec.
if(mysql_num_rows($sql) > 0){ // On demande le nombre de résultats pour la requête.
$result = mysql_fetch_assoc($sql); // Puisqu'on a un seul résultat, on ne l'extrait directement, sans utiliser de boucle while.
$_SESSION['playerId'] = $result['id']; // On crée une variable de session contenant l'identifiant du joueur (c'est plus performant que d'utiliser son nom).
$_SESSION['playerName'] = $result['name']; // On crée une autre variable de session pour son nom, pour l'afficher à l'écran.
return true;
}
else {
// Si la requête n'a rien retourné.
echo "<p>Aucun compte ne correspond à ces identifiants.</p>";
return
false;
}
}
else {
// Si la requête a généré une erreur.
echo "<p>La connexion a échouée.</p>";
return
false;
}
}


Sephi-Chan


RE: Sécurité qui casse tout - Malako - 06-01-2008

Merci beaucoup .

Juste une question , ta une idée de pourquoi je me plante tout le temps ? :rip:


RE: Sécurité qui casse tout - Sephi-Chan - 06-01-2008

Malako a écrit :Merci beaucoup .

Juste une question , ta une idée de pourquoi je me plante tout le temps ? :rip:
C'est parce que tu ne sais pas vraiment ce que tu fais. Tout le monde, ou presque, a déjà connu ça. Surtout en matière de sécurité, on est un peu parano et on fait des choses qui sont, au final, plus inutiles qu'autre chose.


Sephi-Chan


RE: Sécurité qui casse tout - Malako - 06-01-2008

Il faut donc toujours utiliser une id pour les champs ? Smile


RE: Sécurité qui casse tout - Sephi-Chan - 06-01-2008

Code PHP :
<?php session_start();
include
'includes/mysql_connect.php'; // On se connecte à MySQL, ça évite de le faire après.

// On génère un mot de passe.
$chaine = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$password = substr(str_shuffle($chaine), 0, mt_rand(10, 15));

// On vérifie si la faction est bien autorisée.
if($faction != 'Robots' && $faction != 'Humains'){
// Quand on affiche ce que l'utilisateur a rentré, on utilise htmlentities, pour empêcher qu'il execute du code Javascript, par exemple.
echo '<p>Erreur : '.htmlentities($faction)." n'est pas une faction valide.</p>";
exit();
// On termine le script si l'utilisateur à tenté de tricher.
}

// On vérifie si le nom ou l'email n'est pas pris.
$query = sprintf(
"SELECT id FROM users WHERE name = '%s' OR email = '%s'",
mysql_real_escape_string($_POST['name']),
mysql_real_escape_string($_POST['email'])
);
// On fait une requête qui cherche les gens qui ont le nom ou l'email indiqué.
if($sql = mysql_query($query)){ // On execute la requête.
if(mysql_num_rows($sql) > 0){ // S'il y a un résultat, c'est que le nom est déjà pris.
echo '<p>Erreur : Un compte portant ce nom ou cette adresse email existe déjà.</p>';
exit();
}
}
else {
echo
'<p>Erreur : La requête SQL a échouée.</p>';
exit();
}

// On envoie l'email.
$objet = 'Inscription réussie';
/* On écrit le message. En utilisant les guillemets doubles,
on assure que les sauts de lignes apparaîtront dans l'email */
$message = "Rappel de vos identifiants :
Pseudo : "
.$_POST['nom']."
Mot de passe : "
.$password;
$from = 'From: admin@zxi.fr';

// Si l'envoi de l'email échoue, on envoie une erreur.
if(!mail($_POST['email'], $objet, $message, $from)){
echo
"<p>Erreur : L'envoi de l'email a échoué.</p>";
exit();
}


// On procède à l'insertion dans la base de donnée.
$query = sprintf(
"INSERT INTO users (faction, pseudo, password,email)
VALUES('%s', '%s', '%s', '%s');"
,
$faction,
mysql_real_escape_string($_POST['nom']),
sha1($_POST['nom']), // Mieux vaut utiliser sha1 que md5 pour hasher, c'est ce que la documentation recommande.
mysql_real_escape_string($_POST['email'])
);
if(
mysql_query($query)){ // Si la création de l'entrée dans la table users a fonctionné, on continue.
$query = sprinf(
"INSERT INTO ressources (id, ressources) VALUES(%d, %d);"
mysql_insert_id(), // On renseigne un identifiant du joueur, et pas son nom. Dans notre cas on utilise l'id qu'a généré l'auto_increment de l'insertion qu'on vient de faire.
500
);
if(!
mysql_query($query)){
echo
"<p>Erreur : L'attribution des ressources de départ a échoué.</p>";
exit();
}
}
else {
echo
"<p>Erreur : La création du compte a échoué.</p>";
exit();
}

mysql_close();

include
'template/haut.php';

// On écrit le bilan de l'opération.

echo "<p>La création du compte <q>".htmlentities($_POST['nom'])."</q> et l'attribution des ressources de départ a réussi.
<br />Un email a été envoyé à l'adresse indiquée.
<br /><a href=\"index.html\" title=\"Retourner sur la page d'accueil\">Retourner sur la page d'accueil</a></p>"
;

?>