Question

Ceci est lié à une autre question que j'ai posée.En résumé, j'ai un cas particulier d'URL où, lorsqu'un formulaire y est posté, je ne peux pas compter sur les cookies pour l'authentification ou pour maintenir la session de l'utilisateur, mais j'ai besoin d'une manière ou d'une autre de savoir qui ils sont, et j'ai besoin pour savoir qu'ils sont connectés !

Je pense avoir trouvé une solution à mon problème, mais elle doit être approfondie.Voici ce que je pense.Je crée un champ de formulaire caché appelé "nom d'utilisateur" et y place le nom d'utilisateur de l'utilisateur, crypté.Ensuite, lorsque le formulaire est POST, même si je ne reçois aucun cookie du navigateur, je sais qu'ils sont connectés car je peux décrypter le champ caché du formulaire et obtenir le nom d'utilisateur.

La faille de sécurité majeure que je vois concerne les attaques par relecture.Comment puis-je empêcher quelqu'un de mettre la main sur cette chaîne cryptée et de la publier en tant qu'utilisateur ?Je sais que je peux utiliser SSL pour rendre plus difficile le vol de cette chaîne, et peut-être que je peux faire pivoter la clé de cryptage régulièrement pour limiter la durée pendant laquelle la chaîne est valable, mais j'aimerais vraiment trouver une solution à l'épreuve des balles. solution.Quelqu'un a des idées?L'ASP.Net ViewState empêche-t-il la relecture ?Si oui, comment font-ils ?

Modifier:J'espère une solution qui ne nécessite rien de stocké dans une base de données.L'état de l'application serait correct, sauf qu'elle ne survivra pas à un redémarrage d'IIS ni ne fonctionnera du tout dans un scénario de batterie de serveurs ou de jardin Web.J'accepte la réponse de Chris, pour l'instant, car je ne suis pas convaincu qu'il soit même possible de sécuriser cela sans base de données.Mais si quelqu'un propose une réponse qui n'implique pas la base de données, je l'accepterai !

Était-ce utile?

La solution

Si vous hachez un horodatage avec le nom d'utilisateur et le mot de passe, vous pouvez fermer la fenêtre des attaques par rejeu en quelques secondes.Je ne sais pas si cela répond à vos besoins, mais c'est au moins une solution partielle.

Autres conseils

Si vous ne souhaitez vraiment stocker aucun état, je pense que le mieux que vous puissiez faire est de limiter les attaques par rejeu en utilisant des horodatages et un délai d'expiration court.Par exemple, le serveur envoie :

{Ts, U, HMAC({Ts, U}, Ks)}

Où Ts est l'horodatage, U est le nom d'utilisateur et Ks est la clé secrète du serveur.L'utilisateur renvoie cela au serveur, et le serveur le valide en recalculant le HMAC sur les valeurs fournies.S'il est valide, vous savez quand il a été émis et pouvez choisir de l'ignorer s'il date de plus de, disons, 5 minutes.

Une bonne ressource pour ce type de développement est Les choses à faire et à ne pas faire en matière d'authentification client sur le Web

Il y a plusieurs bonnes réponses ici et c’est en les réunissant toutes que se trouve finalement la réponse :

  1. Le chiffrement par bloc chiffre (avec AES-256+) et hache (avec SHA-2+) toutes les informations relatives à l'état/nonce qui sont envoyées à un client.Autrement, les pirates se contentent de manipuler les données, de les visualiser pour apprendre les modèles et contourner tout le reste.Souviens-toi ...il suffit d'une seule fenêtre ouverte.

  2. Générez un nom occasionnel aléatoire et unique par requête qui est renvoyé avec la requête POST.Cela fait deux choses :Il garantit que la réponse POST accompagne CETTE requête.Il permet également de suivre l'utilisation unique d'un ensemble donné de paires get/POST (empêchant la relecture).

  3. Utilisez des horodatages pour rendre le pool de noms occasionnels gérable.Stockez l'horodatage dans un cookie crypté comme indiqué au point 1 ci-dessus.Jetez toutes les demandes antérieures au temps de réponse ou à la session maximum pour l'application (par exemple, une heure).

  4. Stockez une empreinte numérique « raisonnablement unique » de la machine effectuant la demande avec les données d'horodatage cryptées.Cela empêchera une autre astuce dans laquelle l'attaquant vole les cookies des clients pour effectuer un piratage de session.Cela garantira que la demande reviendra non seulement une fois, mais aussi depuis la machine (ou suffisamment proche pour rendre pratiquement impossible la copie par l'attaquant) à laquelle le formulaire a été envoyé.

Il existe des applications basées sur des filtres de sécurité ASPNET et Java/J2EE qui effectuent tout ce qui précède sans aucun codage.La gestion du pool de données occasionnelles pour les grands systèmes (comme une société de bourse, une banque ou un site sécurisé à volume élevé) n'est pas une entreprise triviale si les performances sont essentielles.Je recommanderais d'examiner ces produits plutôt que d'essayer de programmer cela pour chaque application Web.

Vous pouvez utiliser une sorte de chaîne de défi aléatoire utilisée avec le nom d'utilisateur pour créer le hachage.Si vous stockez la chaîne de défi sur le serveur dans une base de données, vous pouvez alors vous assurer qu'elle n'est utilisée qu'une seule fois et uniquement pour un utilisateur particulier.

Dans l'une de mes applications pour arrêter les attaques par « relecture », j'ai inséré des informations IP dans mon objet de session.Chaque fois que j'accède à l'objet de session dans le code, je m'assure de lui transmettre le Request.UserHostAddress, puis je compare pour m'assurer que les adresses IP correspondent.Si ce n'est pas le cas, alors évidemment quelqu'un d'autre que la personne a fait cette demande, donc je renvoie null.Ce n'est pas la meilleure solution mais c'est au moins un obstacle supplémentaire pour arrêter les attaques par rejeu.

Pouvez-vous utiliser de la mémoire ou une base de données pour maintenir n'importe lequel des informations sur l'utilisateur ou une demande ?

Si tel est le cas, sur demande de formulaire, j'inclurais un champ de formulaire masqué dont le contenu est un nombre généré aléatoirement.Enregistrez ce jeton dans le contexte de l'application ou dans une sorte de magasin (une base de données, un fichier plat, etc.) lorsque la demande est rendue.Lorsque le formulaire est soumis, vérifiez le contexte de l'application ou la base de données pour voir si ce numéro généré aléatoirement est toujours valide (quelle que soit la manière dont vous définissez valide - il peut peut-être expirer après X minutes).Si tel est le cas, supprimez ce token de la liste des « tokens autorisés ».

Ainsi, toute requête rejouée inclurait ce même token qui n'est plus considéré comme valide sur le serveur.

Je suis nouveau dans certains aspects de la programmation Web, mais je lisais ce sujet l'autre jour.Je crois que tu dois utiliser un Occasionnellement.

(Les attaques par relecture peuvent facilement concerner une usurpation d'adresse IP/MAC, et vous êtes en outre confronté à des problèmes sur des adresses IP dynamiques.)

Ce n’est pas seulement une rediffusion que vous recherchez ici, car isolément, cela n’a aucun sens.Utilisez simplement SSL et évitez de fabriquer quoi que ce soit à la main.

ASP.Net ViewState est un gâchis, évitez-le.Même si la PKI est lourde et volumineuse, elle fonctionne au moins sans avoir à inventer vos propres « schémas » de sécurité.Donc, si je le pouvais, je l'utiliserais et j'opterais toujours pour une authentification mutuelle.L'authentification uniquement sur le serveur est tout à fait inutile.

Le ViewState inclut des fonctionnalités de sécurité.Voir Cet article sur certaines des fonctionnalités de sécurité intégrées dans ASP.NET .Il effectue une validation par rapport à la machineKey du serveur dans le fichier machine.config sur le serveur, ce qui garantit que chaque publication est valide.

Plus bas dans l'article, vous voyez également que si vous souhaitez stocker des valeurs dans vos propres champs masqués, vous pouvez utiliser l'option LosFormatter classe pour coder la valeur de la même manière que ViewState utilise pour le chiffrement.

private string EncodeText(string text) {
  StringWriter writer = new StringWriter();
  LosFormatter formatter = new LosFormatter();
  formatter.Serialize(writer, text);
  return writer.ToString();
}

Si vous n'acceptez chaque clé qu'une seule fois (par exemple, faites de la clé un GUID, puis vérifiez quand elle revient), cela empêcherait les rediffusions.Bien sûr, si l'attaquant répond d'abord, alors vous avez un nouveau problème...

S'agit-il de WebForms ou de MVC ?S'il s'agit de MVC, vous pouvez utiliser le jeton AntiForgery.Cela semble similaire à l'approche que vous mentionnez, sauf qu'elle utilise essentiellement un GUID et définit un cookie avec la valeur guid pour cette publication.Pour en savoir plus, consultez le blog de Steve Sanderson : http://blog.codeville.net/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/

Autre chose, avez-vous pensé à vérifier le référent sur la publication ?Ce n’est pas à l’épreuve des balles mais cela peut aider.

Utilisez https...il intègre une protection contre la relecture.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top