Sécurisé un appel Ajax

Avatar du membre
Mammouth du PHP | 1564 Messages

18 juil. 2012, 14:14

je comprend un peu mais je sais pas comment créer mon token à vrai dire.

Voici ma solution (fiable d'après vous ?):

sur ma page index.php, j'appel en ajax, les messages qui sont sur la page /inc_chat/messages.php

dans la page messages.php, j'ai mis ce code:
if(!isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] != "http://localhost/tchat_ajax/") { exit(); }
cela fonctionne mais est il fiable ?

PS: ma solution consiste à que personne n’accède directement à ma page messages.php

Eléphant du PHP | 127 Messages

18 juil. 2012, 14:42

Cette solution n'est pas fiable. Il est très facile pour un utilisateur averti de modifier le HTTP_REFERER à la main.
Voici un extrait de la doc :
'HTTP_REFERER'
L'adresse de la page (si elle existe) qui a conduit le client à la page courante. Cette valeur est affectée par le client, et tous les clients ne le font pas. Certains navigateurs permettent même de modifier la valeur de HTTP_REFERER, sous forme de fonctionnalité. En bref, ce n'est pas une valeur de confiance.
Pour générer ton jeton, rien de plus simple : tu peux utiliser les fonctions crypt() ou hash() appliquées à une concaténation de valeurs aléatoires (via uniqid et rand par exemple). Ce jeton est stocké en base, en session peu importe et à une durée de vie limitée

Avatar du membre
Mammouth du PHP | 1564 Messages

18 juil. 2012, 15:50

ça à l'air tellement facile pour toi

PS: je sort un peu du sujet avec ce post-scriptum mais comment faire pour trouver le referer exact et à tout les coup ? avec javascript ? (document.referer)

Une question que je me pose: il faudrait que ce jeton soit générer à chaque message ajouté pour bien faire ? parce que l'utilisateur peut très bien regarder dans le code source et a le temps de la durée de vie du token pour accéder à la page messages.php

ViPHP
xTG
ViPHP | 7331 Messages

18 juil. 2012, 16:16

Tu ne peux pas.
Le referer est une donnée envoyée par le navigateur, certains navigateurs ne l'envoient jamais.
Ou bien proposent à l'utilisateur d'en renseigner un bidon qui sera toujours envoyé.

Eléphant du PHP | 127 Messages

18 juil. 2012, 22:38

Voici une fonction qui permet de générer un token :
function getToken() {
	return hash('sha256', uniqid() . rand());
}

echo getToken();
C'est basique mais il n'y pas besoin de plus. Une fois généré, il faut le stocker. Si tu ne souhaites pas garder l'historique des tokens, tu peux avoir une table users comme celle-ci :
CREATE TABLE users (
  id INT(11) PRIMARY KEY,
  login VARCHAR(20),
  password VARCHAR(255),
  token VARCHAR(255),
  token_expire_at DATETIME
);
Ainsi, quand un utilisateur s'authentifie avec son login/mot de passe, tu génères un token ainsi qu'une date de fin d'expiration (par exemple heure courante + 24 heures).
Pour que le système soit sécurisé, ce token doit être envoyé crypté (par exemple via HTTPS). Le client stocke le token sur son poste (par exemple via cookie crypté).
Dès que l'utilisateur envoie une requête (AJAX ou pas), il envoie également une valeur de hash calculée grâce à ce token et la requête.

Dans ton cas, on peut imaginer quelques fonctions JS qui calculent ce hash (pseudo code jquery) :
[javascript]
function sendSecuredAjax(url, datas) {

token = getCookie('token'); // Cookie à crypter
user = getCookie('user'); // Nom d'utilisateur, cookie à crypter

$.ajax(url + getHash(token, url, user), {
type : 'POST', // Données passées en POST mais token en GET
data : datas
});
}

function getHash(token, url, user) {
// Exemple d'implémentation en JS de SHA1
// http://www.webtoolkit.info/javascript-sha1.html
return '?hash=' + SHA1(token + url) + '&user=' + user;
}

// Fonction Site du zéro
function getCookie(sName) {
var oRegex = new RegExp("(?:; )?" + sName + "=([^;]*);?");

if (oRegex.test(document.cookie)) {
return decodeURIComponent(RegExp["$1"]);
} else {
return null;
}
}
[/javascript]

Et coté serveur, lors de la réception de la requête, il suffit de comparer le hash de la requête avec le hash calculé grâce à l'utilisateur, le token stocké dans la table et l'URI de la requête.
Bon courage.

Avatar du membre
Mammouth du PHP | 1564 Messages

19 juil. 2012, 10:38

Merci pour ces bouts de codes qui me seront très utile.

et également merci pour le "bon courage" :mrgreen: