Sécurisé un appel Ajax

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Sécurisé un appel Ajax

Re: Sécurisé un appel Ajax

par two3d » 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:

Re: Sécurisé un appel Ajax

par nhachet » 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.

Re: Sécurisé un appel Ajax

par xTG » 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é.

Re: Sécurisé un appel Ajax

par two3d » 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

Re: Sécurisé un appel Ajax

par nhachet » 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

Re: Sécurisé un appel Ajax

par two3d » 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

Re: Sécurisé un appel Ajax

par nhachet » 18 juil. 2012, 11:52

Merci mais le token est il fixe ou généré un nouveau à chaque rechargement de la page ?

car si il est fixe on à juste à faire un appel de la page comme tu la préciser (ex: GET /ma/ressource?hash=<mon hash>&user=<mon user>)
Dans mon scénario, il est fixe. Ce que le client transmet dans la requête ci dessus ce n'est pas directement le token mais le hash calculé en fonction du token (dans mon exemple, le hash est calculé en concaténant le token + la requête URI, sans les paramètres GET).

Les jetons générés à chaque utilisation/validation de formulaire utilise un principe similaire, sauf que le jeton à une durée de vie courte (quelques minutes) et que le jeton est transmis tel quel (pas de hash). Il sont généralement utilisés pour contrer le CSRF.

Re: Sécurisé un appel Ajax

par two3d » 18 juil. 2012, 10:58

D'accord mais comment le généré à chaque fois et vérifier que c'est le bon ?

Re: Sécurisé un appel Ajax

par xTG » 18 juil. 2012, 09:15

Ah bah non il est régénéré à chaque chargement de page. Sinon aucun intérêt de le stocker en session puisqu'on pourrait le mettre en dur. ;)

Re: Sécurisé un appel Ajax

par two3d » 17 juil. 2012, 21:16

Merci mais le token est il fixe ou généré un nouveau à chaque rechargement de la page ?

car si il est fixe on à juste à faire un appel de la page comme tu la préciser (ex: GET /ma/ressource?hash=<mon hash>&user=<mon user>)

Re: Sécurisé un appel Ajax

par nhachet » 17 juil. 2012, 21:09

Bonsoir,

pour sécuriser un appel AJAX (ou tout autre appel d'ailleurs), rien de tel qu'un jeton d'authentification.
Voici un scénario :

1. authentification du client
2. un token unique et temporaire est généré coté serveur, transmis au client et stocké sur le serveur (<token>)
3. le client utilise ce token pour signer ses requêtes => création d'un hash concaténant ce token + la requête (ex: <token> + "GET /ma/ressource" = <mon hash> ; le MD5 est à bannir, privilégier SHA1 ou +)
4. envoi de la requête du client avec le hash (ex: GET /ma/ressource?hash=<mon hash>&user=<mon user>)
5. le serveur reçoit la requête et l'authentifie grâce au hash recalculé avec le user et le token temporaire.
6. le serveur sert la réponse ou rejette la requête (et archive les erreurs, prévient des admins, etc.)

A+

Re: Sécurisé un appel Ajax

par two3d » 17 juil. 2012, 20:47

c'est un tchat en ajax, les données sont appeler comme ceci:

ya index.php qui reçois les données de la page messages.php dans une div (<div id="tchat"></div>)

j'ai essayer de mettre le code de la page messages.php directement dans la balise div mais du coup ça me recharge un tchat à l'intérieur du tchat et pas moyen d'écrire un message

Re: Sécurisé un appel Ajax

par momox » 17 juil. 2012, 20:01

Impossible, si on peut appeller via Ajax, on peut l'accèder autrement.

Concrétement, quelle est ta problèmatique ? Ce sont des données "sensibles" ?

Re: Sécurisé un appel Ajax

par two3d » 15 juil. 2012, 21:20

Bonjour,

je souhaiterai que l'on ne puisse pas venir directement sur une page que j'appel avec AJAX mais je ne trouve pas, votre méthode avec session ne fonctionne pas.

Re: Sécurisé un appel Ajax

par Nours312 » 12 avr. 2010, 01:25

L'idée de session est bonne. Moi en plus je "cache" l'accès de la page AJAX dans le flow des includes de ma page globale. Cela veut dire : je fais pointer ma page AJAX vers index.php et dans index.php je teste via POST ou GET (selon le mode que tu as choisi en fait) qu'elle page appelle l'AJAX et je fais un include_once de la page qui fera le traitement.
t'as pas des risque qu'un petit malin te bombarde de requêtes cUrl et/ou analyse le comportement de tes requêtes, ou autres dans le but de trouver les variables (nom de la page à inclure) pour par la suite aller la chercher directement ?

perso, je considère les pages Ajax comme tout autre page, gérée avec un urlRewriting vérification des sécurité et autres sessions la seul différence entre une page ajax et une page dite "normale" c'est le template en charge de mettre les données en place et appeler les modules externes autonomes ... ainsi, si le gars viens directement, il a les données dans le design du site, et si il n'a pas les droits, il a la page d'accueil ou une 404 !
ça permet entre autre de stoquer +/- dans le template (ou autre) la liste des urls que le log JS va devoir charger en plaçant par exemple une classe sur les liens ou formulaires qui remplaceront le rechargement par une requete ajax pour les mettre (si className : popUp) dans une popUp ^^ ... c'est assez souple comme système ... et on reste dans un environnement de sessions donc c'est pas trop galère à sécuriser.

@+