J'ai mis en œuvre dans mon application l'atténuation des attaques CSRF suite aux informations que j'ai lues sur certains articles de blog sur Internet. En particulier, ces postes ont été le moteur de ma mise en œuvre
- Meilleures pratiques pour ASP.NET MVC de l'équipe de contenu pour les développeurs ASP.NET et Web Tools
- Anatomie d'une attaque de contrefaçon de demande intersite de intersite sur le blog de Phil Haack
- AntiForgeryToken dans le cadre ASP.NET MVC - Html.AntiForgeryToken et ValidateAntiForgeryToken Attribute from David Hayden blog
Fondamentalement, ces articles et recommandations indiquent que pour empêcher l'attaque CSRF, quiconque devrait implémenter le code suivant:
1) Ajoutez le [ValidateAntiForgeryToken]
sur chaque action qui accepte le verbe Http POST
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SomeAction( SomeModel model ) {
}
2) Ajoutez l' <%= Html.AntiForgeryToken() %>
assistant à l'intérieur des formulaires qui soumet des données au serveur
<div style="text-align:right; padding: 8px;">
<%= Html.AntiForgeryToken() %>
<input type="submit" id="btnSave" value="Save" />
</div>
Quoi qu'il en soit, dans certaines parties de mon application, je fais des POST Ajax avec jQuery sur le serveur sans aucune forme. Cela se produit par exemple lorsque je laisse l'utilisateur cliquer sur une image pour effectuer une action spécifique.
Supposons que j'ai une table avec une liste d'activités. J'ai une image sur une colonne du tableau qui dit "Marquer l'activité comme terminée" et lorsque l'utilisateur clique sur cette activité, je fais le POST Ajax comme dans l'exemple suivant:
$("a.markAsDone").click(function (event) {
event.preventDefault();
$.ajax({
type: "post",
dataType: "html",
url: $(this).attr("rel"),
data: {},
success: function (response) {
// ....
}
});
});
Comment puis-je utiliser le <%= Html.AntiForgeryToken() %>
dans ces cas? Dois-je inclure l'appel d'aide dans le paramètre de données de l'appel Ajax?
Désolé pour le long post et merci beaucoup pour votre aide
MODIFIER :
Selon la réponse de jayrdub, j'ai utilisé de la manière suivante
$("a.markAsDone").click(function (event) {
event.preventDefault();
$.ajax({
type: "post",
dataType: "html",
url: $(this).attr("rel"),
data: {
AddAntiForgeryToken({}),
id: parseInt($(this).attr("title"))
},
success: function (response) {
// ....
}
});
});
Réponses:
J'utilise une simple fonction js comme celle-ci
Étant donné que chaque formulaire sur une page aura la même valeur pour le jeton, mettez simplement quelque chose comme ça dans votre page maître la plus élevée
Ensuite, dans votre appel ajax do (modifié pour correspondre à votre deuxième exemple)
la source
AddAntiForgeryToken
, comme ceci:data: AddAntiForgeryToken({ id: parseInt($(this).attr("title")) }),
ajaxSend
ou de remplacerajax
pour toujours augmenterdata
le jeton anti-contrefaçon? Peut-être en ajoutant une vérification pour vous assurer que leurl
est destiné à votre serveur.J'aime la solution fournie par 360Airwalk, mais elle peut être un peu améliorée.
Le premier problème est que si vous créez
$.post()
des données vides, jQuery n'ajoute pas d'en-Content-Type
tête et, dans ce cas, ASP.NET MVC ne parvient pas à recevoir et à vérifier le jeton. Vous devez donc vous assurer que l'en-tête est toujours là.Une autre amélioration est la prise en charge de tous les verbes HTTP avec du contenu : POST, PUT, DELETE etc. Bien que vous puissiez utiliser uniquement des POST dans votre application, il est préférable d'avoir une solution générique et de vérifier que toutes les données que vous recevez avec n'importe quel verbe ont un anti-faux jeton.
la source
.ajaxSend()
états "À partir de jQuery 1.8, la méthode .ajaxSend () ne doit être attachée qu'au document." api.jquery.com/ajaxsendoptions
produit, qui est répertorié dans laif
déclaration finale ? Merci.Je sais qu'il y a beaucoup d'autres réponses, mais cet article est agréable et concis et vous oblige à vérifier tous vos HttpPosts, pas seulement certaines d'entre elles:
http://richiban.wordpress.com/2013/02/06/validating-net-mvc-4-anti-forgery-tokens-in-ajax-requests/
Il utilise des en-têtes HTTP au lieu d'essayer de modifier la collection de formulaires.
Serveur
Client
la source
Je me sens comme un nécromancien avancé ici, mais c'est toujours un problème 4 ans plus tard dans MVC5.
Pour gérer correctement les requêtes ajax, le jeton anti-falsification doit être transmis au serveur lors des appels ajax. L'intégrer dans vos données et modèles de publication est compliqué et inutile. L'ajout du jeton en tant qu'en-tête personnalisé est propre et réutilisable - et vous pouvez le configurer de sorte que vous n'ayez pas à vous souvenir de le faire à chaque fois.
Il existe une exception - ajax discret n'a pas besoin d'un traitement spécial pour les appels ajax. Le jeton est transmis comme d'habitude dans le champ de saisie caché normal. Exactement la même chose qu'un POST ordinaire.
_Layout.cshtml
Dans _layout.cshtml, j'ai ce bloc JavaScript. Il n'écrit pas le jeton dans le DOM, il utilise plutôt jQuery pour l'extraire du littéral d'entrée caché généré par MVC Helper. La chaîne Magic qui est le nom de l'en-tête est définie comme une constante dans la classe d'attributs.
Notez l'utilisation de guillemets simples dans la fonction beforeSend - l'élément d'entrée qui est rendu utilise des guillemets doubles qui briseraient le littéral JavaScript.
JavaScript client
Lorsque cela s'exécute, la fonction beforeSend ci-dessus est appelée et l'AntiForgeryToken est automatiquement ajouté aux en-têtes de demande.
Bibliothèque de serveur
Un attribut personnalisé est requis pour traiter le jeton non standard. Cela s'appuie sur la solution de @ viggity, mais gère correctement ajax discret. Ce code peut être caché dans votre bibliothèque commune
Serveur / Contrôleur
Maintenant, vous appliquez simplement l'attribut à votre action. Encore mieux, vous pouvez appliquer l'attribut à votre contrôleur et toutes les demandes seront validées.
la source
$.ajaxSetup
de définir unbeforesend
gestionnaire d'événements général, il peut arriver que vous le remplaciez. J'ai trouvé une autre solution où vous pouvez ajouter un deuxième gestionnaire qui sera également appelé. Fonctionne bien et ne rompt pas votre implémentation.N'utilisez pas Html.AntiForgeryToken . À la place, utilisez AntiForgery.GetTokens et AntiForgery.Validate à partir de l'API Web, comme décrit dans la section Prévention des attaques CSRF (Cross-Site Request Forgery) dans l'application ASP.NET MVC .
la source
J'étais juste en train d'implémenter ce problème réel dans mon projet actuel. je l'ai fait pour tous les ajax-POST qui avaient besoin d'un utilisateur authentifié.
Tout d'abord, j'ai décidé de raccrocher mes appels jquery ajax afin de ne pas me répéter trop souvent. cet extrait javascript garantit que tous les appels ajax (post) ajouteront mon jeton de validation de demande à la demande. Remarque: le nom __RequestVerificationToken est utilisé par le framework .Net afin que je puisse utiliser les fonctionnalités anti-CSRF standard comme indiqué ci-dessous.
Dans vos vues où vous avez besoin que le jeton soit disponible pour le javascript ci-dessus, utilisez simplement le HTML-Helper commun. Vous pouvez essentiellement ajouter ce code où vous le souhaitez. Je l'ai placé dans une instruction if (Request.IsAuthenticated):
Dans votre contrôleur, utilisez simplement le mécanisme standard ASP.Net MVC Anti-CSRF. Je l'ai fait comme ça (même si j'ai utilisé du sel).
Avec Firebug ou un outil similaire, vous pouvez facilement voir comment vos requêtes POST ont désormais un paramètre __RequestVerificationToken ajouté.
la source
Je pense que tout ce que vous avez à faire est de vous assurer que l'entrée "__RequestVerificationToken" est incluse dans la requête POST. L'autre moitié des informations (c'est-à-dire le jeton dans le cookie de l'utilisateur) est déjà envoyée automatiquement avec une demande AJAX POST.
Par exemple,
la source
AntiForgeryToken
, tout est discutable de toute façon. Si c'est le cas (je ne sais pas comment vous en obtenez un dans ce cas, mais en supposant que vous l'êtes), alors ce qui précède fonctionnerait très bien. Si vous essayez de créer une page Web simple qui publiera une demande sur un serveur attendant ledit jeton et que le serveur n'a pas généré ladite page, alors vous n'avez pas de chance. C'est essentiellement le but de l'AntiForgeryToken ...Vous pouvez également le faire:
Cela utilise
Razor
, mais si vous utilisez laWebForms
syntaxe, vous pouvez tout aussi bien utiliser des<%= %>
balisesla source
Suite à mon commentaire contre la réponse de @ JBall qui m'a aidé en cours de route, c'est la réponse finale qui fonctionne pour moi. J'utilise MVC et Razor et je soumets un formulaire en utilisant jQuery AJAX afin que je puisse mettre à jour une vue partielle avec de nouveaux résultats et je ne voulais pas faire une publication complète (et un scintillement de page).
Ajoutez l'
@Html.AntiForgeryToken()
intérieur du formulaire comme d'habitude.Mon code de bouton de soumission AJAX (c'est-à-dire un événement onclick) est:
J'ai laissé l'action "succès" car elle montre comment la vue partielle est mise à jour qui contient un MvcJqGrid et comment il est actualisé (grille jqGrid très puissante et c'est un brillant wrapper MVC pour cela).
Ma méthode de contrôleur ressemble à ceci:
Je dois admettre que je ne suis pas un fan de la publication de données d'un formulaire entier en tant que modèle, mais si vous devez le faire, c'est une façon de fonctionner. MVC rend simplement la liaison de données trop facile, plutôt que de soumettre 16 valeurs individuelles (ou une FormCollection faiblement typée), cela est OK, je suppose. Si vous savez mieux, faites-le moi savoir car je veux produire un code MVC C # robuste.
la source
a trouvé cette idée très intelligente sur https://gist.github.com/scottrippey/3428114 pour chaque appel $ .ajax, il modifie la demande et ajoute le jeton.
la source
if (options.contentType != false && options.contentType.indexOf('application/json') === 0) {
pour intercepter les appels Ajax qui n'avaient pas spécifié de type de contenu1. définir la fonction pour obtenir le jeton du serveur
Obtenez le jeton et définissez l'en-tête avant de l'envoyer au serveur
3. Onserver Validation on HttpRequestBase on method you handle Post / get
la source
Je sais que cela fait un certain temps que cette question n'a pas été publiée, mais j'ai trouvé une ressource vraiment utile, qui discute de l'utilisation d'AntiForgeryToken et la rend moins gênante à utiliser. Il fournit également un plugin jquery pour inclure facilement un jeton anti-corruption dans les appels AJAX:
Recettes de demande anti-contrefaçon pour ASP.NET MVC et AJAX
Je ne contribue pas beaucoup, mais peut-être que quelqu'un le trouvera utile.
la source
la source
Voici la façon la plus simple que j'ai vue. Remarque: Assurez-vous que vous avez "@ Html.AntiForgeryToken ()" dans votre vue
la source
Légère amélioration de la solution 360Airwalk. Cela incorpore le jeton anti-contrefaçon dans la fonction javascript, donc @ Html.AntiForgeryToken () n'a plus besoin d'être inclus dans chaque vue.
la source
la source
J'utilise un message ajax pour exécuter une méthode de suppression (se trouve être à partir d'une chronologie visjs mais ce n'est pas pertinent). Voilà ce que je sis:
Ceci est mon Index.cshtml
Tout ce que j'ai ajouté ici était
@Html.AntiForgeryToken()
de faire apparaître le jeton dans la pageEnsuite, dans mon post ajax, j'ai utilisé:
Ce qui ajoute la valeur du jeton, grattée sur la page, aux champs publiés
Avant cela, j'ai essayé de mettre la valeur dans les en-têtes, mais j'ai eu la même erreur
N'hésitez pas à publier des améliorations. Cela semble certainement être une approche simple que je peux comprendre
la source
D'accord, beaucoup de messages ici, aucun d'eux ne m'a aidé, des jours et des jours de google, et toujours pas plus je suis arrivé au point d'écrire toute l'application à partir de zéro, puis j'ai remarqué ce petit nugget dans mon Web.confg
Maintenant, je ne sais pas pourquoi je l'ai ajouté, mais je l'ai remarqué depuis, il est ignoré en mode débogage et non en mode production (IE installé sur IIS quelque part)
Pour moi, la solution était l'une des 2 options, car je ne me souviens pas pourquoi je l'ai ajouté, je ne peux pas être sûr que d'autres choses n'en dépendent pas, et en second lieu le nom de domaine doit être tout en minuscules et un TLD pas comme ive done dans * .localLookup.net
Peut-être que cela aide peut-être que non. J'espère que ça aide quelqu'un
la source
La solution que j'ai trouvée n'est pas pour ASPX mais pour Razor, mais un problème tout à fait compérable.
Je l'ai résolu en ajoutant l'AntiForgery à la demande. L'assistant HTML ne crée pas d'ID HTML avec l'appel
Afin d'ajouter le jeton à la postrequest, je viens d'ajouter l'identifiant AntiForgery au champ caché avec jquery:
Cela a amené le contrôleur à accepter la demande avec l'attribut [ValidateAntiForgeryToken]
la source
AntiforgeryToken est toujours une douleur, aucun des exemples ci-dessus n'a fonctionné mot pour mot pour moi. Il y en a trop pour. Je les ai donc tous combinés. Besoin d'un @ Html.AntiforgeryToken sous une forme suspendue à iirc
Résolu comme tel:
En cas de doute, ajoutez plus de signes $
la source