Bonjour,

Il y a longtemps j'avais programmé un site avec un système de compte avec une connexion via un formulaire (+ mémorisation dans une session et cookie).
Je souhaiterai donc savoir si ces scripts sont sécurisés contre toutes attaques (XSS, injection SQL...).

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Connexion via formulaire -> AJAX
$lg = $mysqli->real_escape_string(stripslashes($_POST["lg"]));
$mp = $mysqli->real_escape_string(stripslashes($_POST["mp"]));
$rm = $mysqli->real_escape_string(intval($_POST["rm"]));
 
$r = $mysqli->query("SELECT id, mdp, cle, nom, prenom, valid, vcode FROM users WHERE email = '".$lg."' LIMIT 1");
$nb = mysqli_num_rows($r);
if(!empty($nb)) {
	$v = mysqli_fetch_assoc($r);
	$idu = intval($v['id']);
	$mdp = $v['mdp'];
	$cle = $v['cle']; // créée lors de la création du compte = hash de plusieurs valeurs
	$nom = $v['nom'];
	$prenom = $v['prenom'];
	$valid = $v['valid'];
	$vcode = $v['vcode'];
	if(password_verify($mp, $mdp)) {
		if($valid == '1') {
			if(!isset($_SESSION["connexclt"])) $_SESSION["connexclt"] = array();
			$_SESSION["connexclt"]['id'] = $idu;
			$_SESSION["connexclt"]['login'] = $lg;
			$_SESSION["connexclt"]['cle'] = $cle;
			$_SESSION["connexclt"]['nom'] = $nom;
			$_SESSION["connexclt"]['prenom'] = $prenom;
			$mysqli->query("UPDATE users SET lastvisite = '".date('Y-m-d h:i:s')."' WHERE id = '".$idu."' LIMIT 1");
			if($rm == 1) {
				$k = password_hash($cle.$mdp, PASSWORD_HASH_ALGORITHM, array('cost' => PASSWORD_HASH_COST));
				setcookie("nomcookie", $idu."[+]".$k, array('expires'=>time()+15778463,'path'=>'/','domain'=>$ssdomain.".".$domain,'secure'=>$domainsecure,'httponly'=>true,'samesite'=>"None"));	
			}
			return array('login'=>true,'error'=>false,'nom'=>$nom,'prenom'=>$prenom);
		} else {
			return array('login'=>false,'error'=>"NOVALID",'idu'=>$idu,'email'=>$lg,'nom'=>$nom,'prenom'=>$prenom,'vcode'=>$vcode);
 
		}
	} else {
		$badlog = true;
		$error = "Ces identifiants sont incorrects, veuillez vérifier votre email et votre mot de passe.";
	}
	//... traitement des erreurs de connexion ...
}
 
// Fonction de vérification de la connexion sur les pages privées
 
function cltconnected() {
	global $mysqli, $ssdomain, $domain, $domainsecure;
	if(isset($_SESSION["connexclt"]) && isset($_SESSION["connexclt"]['id']) && isset($_SESSION["connexclt"]['login']) && isset($_SESSION["connexclt"]['cle']) && isset($_SESSION["connexclt"]['nom']) && isset($_SESSION["connexclt"]['prenom']) && $_SESSION["connexclt"]['id'] && $_SESSION["connexclt"]['login'] && $_SESSION["connexclt"]['cle'] && $_SESSION["connexclt"]['nom'] && $_SESSION["connexclt"]['prenom']) {
		$id = intval($mysqli->real_escape_string($_SESSION["connexclt"]['id']));
		$cle = $mysqli->real_escape_string($_SESSION["connexclt"]['cle']);
		$r = $mysqli->query("SELECT email, valid FROM users WHERE id = '".$id."' AND cle = '".$cle."' LIMIT 1");
		$nb = mysqli_num_rows($r);
		if(!empty($nb)) {
			$v = mysqli_fetch_assoc($r);
			$email = $v['email'];
			$valid = $v['valid'];
			if($valid == '1') {
				$vcle = // même hash de plusieurs valeurs - idem lors de la création du compte;
				if($_SESSION["connexclt"]['cle'] == $vcle) {
					$mysqli->query("UPDATE users SET lastvisite = '".date('Y-m-d h:i:s')."' WHERE id = '".$id."' LIMIT 1");
					return true;
				} else {
					unset($_SESSION["connexclt"]);
					if(isset($_COOKIE["nomcookie"])) setcookie("nomcookie", '', 0,'/',$ssdomain.".".$domain, $domainsecure, true);
					return false;
				}
			} else {
				unset($_SESSION["connexclt"]);
				if(isset($_COOKIE["nomcookie"])) setcookie("nomcookie", '', 0,'/',$ssdomain.".".$domain, $domainsecure, true);
				return false;
			}
		} else {
			unset($_SESSION["connexclt"]);
			if(isset($_COOKIE["nomcookie"])) setcookie("nomcookie", '', 0,'/',$ssdomain.".".$domain, $domainsecure, true);
			return false;
		}
 
	} elseif(isset($_COOKIE["nomcookie"]) && $_COOKIE["nomcookie"]) {
		$ccode = $_COOKIE["nomcookie"];
		$tcode = explode("[+]",$ccode);
		$idu = intval($mysqli->real_escape_string($tcode[0]));
		$code = $tcode[1];
		$r = $mysqli->query("SELECT email, mdp, cle, nom, prenom, valid FROM users WHERE id = '".$idu."' LIMIT 1");
		$nb = mysqli_num_rows($r);
		if(!empty($nb)) {
			$v = mysqli_fetch_assoc($r);
			$lg = $v['email'];
			$mdp = $v['mdp'];
			$cle = $v['cle'];
			$nom = $v['nom'];
			$prenom = $v['prenom'];
			$valid = $v['valid'];
			if($valid == '1') {
				if(password_verify($cle.$mdp, $code)) {
					if(!isset($_SESSION["connexclt"])) $_SESSION["connexclt"] = array();
					$_SESSION["connexclt"]['id'] = $idu;
					$_SESSION["connexclt"]['login'] = $lg;
					$_SESSION["connexclt"]['cle'] = $cle;
					$_SESSION["connexclt"]['nom'] = $nom;
					$_SESSION["connexclt"]['prenom'] = $prenom;
					$k = password_hash($cle.$mdp, PASSWORD_HASH_ALGORITHM, array('cost' => PASSWORD_HASH_COST));
					setcookie("nomcookie", $idu."[+]".$k, array('expires'=>time()+15778463,'path'=>'/','domain'=>$ssdomain.".".$domain,'secure'=>$domainsecure,'httponly'=>true,'samesite'=>"Strict"));	
					$mysqli->query("UPDATE users SET lastvisite = '".date('Y-m-d h:i:s')."' WHERE id = '".$idu."' LIMIT 1");
					return true;
				} else {
					setcookie("nomcookie", '', 0,'/',$ssdomain.".".$domain, $domainsecure, true);
					return false;
				}
			} else {
				setcookie("nomcookie", '', 0,'/',$ssdomain.".".$domain, $domainsecure, true);
				return false;
			}
		} else {
			setcookie("nomcookie", '', 0,'/',$ssdomain.".".$domain, $domainsecure, true);
			return false;
		}
	} else {
		setcookie("nomcookie", '', 0,'/',$ssdomain.".".$domain, $domainsecure, true);
		return false;
	}
}
Et pour une simple requête (de recherche par exemple) j'utilise toujours soit intval quand c'est un entier soit $mysqli->real_escape_string.
Les valeurs dans la requête sont toujours entourées par des apostrophes.
Apparemment "real_escape_string" ne serait pas suffisant (ex. avec "1 OR 1 = 1") mais ça c'est si on ne met pas les valeurs entre apostrophes, non ?

Exemple de requête basique :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
$val = $mysqli->real_escape_string(stripslashes($_POST["val"]));
$r = $mysqli->query("SELECT param FROM table WHERE param = '".addslashes($val)."'");
J'ai vu que maintenant il est conseillé d'utiliser des requêtes préparées mais tout reprendre serait très long, donc je souhaiterai savoir si ces méthodes sont entièrement sécurisées ou non.

En vous remerciant par avance !