2009-02-16 8 views
5

Je sais comment utiliser l'attribut AntiForgeryToken de MVC et son assistant HTML associé pour aider XSRF à sécuriser les POST de formulaire de mon application.Comment sécuriser mes appels JSONResult GET?

Est-ce que quelque chose de similaire peut être fait pour JsonResults qui implémentent GET?

Par exemple, mon avis contient un onSubmit appel jQuery comme tel:

$.getJSON("/allowActivity/YesOrNo/" + someFormValue, "{}", function(data) { 
    if(data.Allow) { 
    //Do something. 
    } 
}); 

Je veux vous assurer que ce JsonResult n'est appelable de la page prévue.

EDIT:

Je trouve this post sur une question similaire, sans réponse concrète.

Quel est le moyen le plus simple de vérifier que mon URL GET (non destructive) est utilisée uniquement par un appel AJAX provenant de ma propre page?

Répondre

8

Vous pouvez utiliser le AntiForgeryToken combiné avec une logique personnalisée. La création du jeton AntiForgery sur le serveur est la même, mais par défaut la valeur n'est pas incluse dans votre XmlHttpRequest.

La valeur de ce jeton se trouve dans le cookie HTTP "__RequestVerificationToken" et doit également figurer dans les données de formulaire publiées sur le serveur. Donc inclure une paire clé/valeur dans votre XMLHttpRequest et utiliser le ValidateAntiForgeryToken - attribut sur votre contrôleur

EDIT:

Aujourd'hui, j'ai essayé d'utiliser le AntiForgeryToken pour Ajax me demandes et cela fonctionne très bien. Il suffit d'utiliser le javascript suivant:

$.post('my_url', $.getAntiForgeryTokenString(), function() { ... }); 

$.getAntiForgeryTokenString = function() { 
    return $(document.getElementsByName("__RequestVerificationToken")).fieldSerialize(); 
}; 

Du côté du serveur, vous ne devez pas changer votre code - il suffit d'utiliser l'attribut ValidateAntiForgeryToken- pour votre action.

Hope this helps

+0

Comment voulez-vous intégrer la valeur __RequestVerificationToken avec le .getJSON $ ou composez le .ajax $? Rappelez-vous, ceci est une demande GET. –

+0

Lire "Divulgation de jeton dans l'URL" à l'adresse http://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet "Si des actions côté serveur sensibles sont garanties pour répondre uniquement aux requêtes POST, alors il n'est pas nécessaire d'inclure le jeton dans les requêtes GET "La clé est de s'assurer que votre GET ne modifie pas les données. Sinon, vous n'avez pas besoin de protéger les requêtes GET. –

0

Vous pouvez faire quelque chose de similaire aux méthodes anti XSRF. Il suffit de générer un identifiant pour l'insérer dans le javascript et lorsque l'utilisateur appelle votre URL JSON, demandez à cette URL d'inclure l'identifiant généré et de vérifier s'il existe.

Une défense contre XSRF utilise également la sessionID comme clé, ceci n'empêche pas l'utilisateur de l'exécuter à partir d'un autre site Web pour son propre compte.

Un hachage basé sur la session et l'heure pourrait faire l'affaire. Bien sûr, si l'utilisateur copie la valeur du JS, il peut toujours l'exécuter à partir d'un autre emplacement, mais vous pouvez avoir cette valeur expire toutes les x minutes. Une autre option consiste à définir un cookie avec JS et à le lire sur le serveur.

Espérons que cela vous donne quelques idées pour vous aider à démarrer.

1

tout d'abord pourquoi ne pas utiliser .post $ (url, données, rappel, 'json') au lieu de getJSON? Et comme dit kleolb02, vous pouvez ajouter de la valeur à partir du cookie aux données post en utilisant cookie plugin - {__RequestVerificationToken: .cookie de $ ('__ RequestVerificationToken')}

+0

Cela sonne bien. J'espérais éviter POST pour un simple appel ajax, mais je le ferai certainement si c'est le seul moyen de le sécuriser. –

+0

Vous devez utiliser post pour mettre à jour certaines données sur le serveur. C'est un scénario commun. Et pour autant que je m'en souvienne, AntiForgeryToken ne fonctionnent qu'avec des demandes de publication (ils recherchent une valeur dans FormCollection uniquement). – zihotki

+0

Ceci n'est pas une mise à jour, c'est un simple "get". Je voudrais simplement limiter la consommation de l'URL aux appels AJAX de ma propre page. –

1

J'ai utilisé un code similaire dans un projet ASP.NET MVC à utiliser sur la fonction de flou d'un élément sans avoir de forme Ajax. Ce code permet de remplir un champ de texte avec des données de serveur lorsqu'un événement Blur d'élément HTML se produit.

Espérons que cela aide aussi. Voici mon code:

Javascript:

var mytext = { 'myText': 'example text' }; 
$.post('/MyController/JsonResultMethod', AddAntiForgeryToken(myText), function (resultData) { 
     $('#htmlElement').val(resultData); 
}); 
AddAntiForgeryToken = function (data) { 
    data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val(); 
    return data; 
}; 

Code C-Sharp:

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public JsonResult SeoString(string myText) 
    { 
     try 
     { 
      // do something here 
      return this.Json("result text"); 
     } 
     catch (Exception) 
     { return this.Json(string.Empty); } 
    } 
Questions connexes