8
votes

Comment fournir plus de sécurité pour vérifier la source de la demande

Je développe une application Web PHP, je souhaite fournir plus de sécurité à l'application afin que personne ne puisse facilement casser la fonctionnalité.

Brève explication sur mon problème: Dans un module, il y a une étape où je vérifie la source de la demande (à partir de laquelle cette demande provient de)

Actuellement, j'utilise http_referrer variable (disponible en PHP). Je vérifie cette valeur de variable avec une URL spécifique (par exemple, http://www.example.com/test. php ). Si la correspondance exacte existe, seulement j'appelle des actions supplémentaires.

Je suis un peu confus avec l'approche ci-dessus, si je dois utiliser http_referrer ou vérifier avec l'adresse IP (demande valide si elle provenait d'une adresse IP spécifique)?

Je veux aussi connaître de meilleures approches pour fournir une sécurité.

Est-ce que quelqu'un a une idée alors s'il vous plaît partager?

Merci d'avance


1 commentaires

Http_referer n'a rien à voir avec la source de demande. Vous feriez mieux de vérifier une adresse IP à la place


3 Réponses :


7
votes

Leçon n ° 1 en sécurité Web: Ne faites jamais confiance à l'utilisateur de l'utilisateur. Et quand je dis jamais, je veux dire jamais. ;) Y compris le http_refer var in php, ce qui est facilement compromis avec un en-tête HTTP (source: http://www.mustap.com/phpzone_post_62_how-to-bypass-the-referer-se )

Une solution possible dans la vérification de la source est l'utilisation d'un jeton de formulaire (protection CSRF): http://www.thespannerner.co.uk / 2007/04/12 / ponctuel-formes-jetons / mais n'est-ce pas non plus et n'est possible qu'avec votre propre source. P>

Un CSRF simple (demande croisée Forage) Exemple de protection: (D'où le simple. Pour une solution plus sûre / robuste, reportez-vous à la réponse de la ROOK) P>

1) dans votre page de formulaire, créez une sorte de jeton et mettez votre session et dans un champ de forme caché: p> xxx pré>

2) dans votre vérification du gestionnaire de formulaire si le jeton est valide. P>

<?php
   session_start();
   if($_POST['csrfKey'] != $_SESSION['csrfKey']) {
      die("Unauthorized source!");
   }
?>


8 commentaires

Merci pour une réponse rapide, @Treeur: mon cas de test valide est: Je pose des valeurs telles que "Age", "ID", "Description", "Remarques" à l'aide de la méthode de formulaire simple. Je pose cela sur une URL spécifique qui passe en réalité sur ces valeurs qui doivent être sécurisées. Alors, ici, je veux vérifier où la source de la demande est valide ou non. ?


Dans ce cas, vous souhaitez utiliser une sorte de protection CSRF. J'ai mis à jour ma réponse avec un exemple simple


-1 La référence est sûre pour la protection de la CSRF et votre génération de jeton CSRF est très insécurité, c'est mieux: Uniqid (mt_rand (), vrai); L'attaquant va savoir le temps, après tout Il peut contrôler quand la demande est envoyée.


Peu importe s'il sait le temps, car il est combiné avec un sel "secret". Je l'ai appelé un exemple simple exprès;)


@Treeur Ouais, votre droit n'est pas trivial de contourner, mais vous devriez toujours avoir plus d'entropie, même appeler mt_rand () serait mieux. En utilisant une valeur connue telle que le temps ou l'URL me dérange. J'ai ajouté des espaces avec votre message juste pour emporter le -1.


@TREUR J'ai pensé à une autre attaque contre votre CSRFey . Si l'attaquant crée et compte et se connecte alors il connaîtra l'exact microtime () , à l'aide de cette valeur connue, il peut ensuite utiliser John the Ripper vers Brute Force The MD5 () Hash pour obtenir la valeur du sel. En bref, cette génération de jeton CSRF n'est pas bonne et vous devriez changer ce message.


@Le tour. Vrai. Toutefois. Je me demande. Je ne suis pas vraiment dans le fonctionnement intérieur des générateurs de nombres aléatoires pseudo. (MT_RAND) Ne sont-ils pas basés sur le microtime également une fois en théorie également traçable? (Mais peut-être que je devrais demander cela dans une question distincte)


Je sais que c'est vieux, mais le 2e code Snippet a une faute de frappe. devrait être $ _ session ['csrftoken']



3
votes

Vérification du http_referrer pour le CSRF est une forme de protection valide. Bien qu'il soit trivial à utiliser cette en-tête HTTP sur votre propre navigateur Il est impossible de se multiplier sur un autre navigateur de personnes à l'aide de CSRF parce qu'il enfreint le Règles .

Selon le département de la sécurité intérieure, j'ai trouvé le Vulnérabilité la plus dangereuse du CSRF jamais trouvé et est dans les 1 000 top 1 000 vulnérabilités les plus dangereuses de tous les temps. Motorola a corrigé cette faille à l'aide d'un chèque de référateur et de son communication de vue sur cette méthode de protection sur le matériel réseau incorporé car la mémoire est rare.

Une méthode plus commune et plus sécurisée consiste à stocker un Sansce cryptographique à l'intérieur d'un $ _ Session variable et vérifiez ceci pour chaque demande sensible. Une approche facile consiste à utiliser post pour toutes les demandes sensibles (comme changer votre mot de passe) et assurez-vous que cette nonce cryptographique est valide pour tous les messages dans un fichier d'en-tête PHP, s'il n'est pas valide, alors non défini ($ _ post); . Cette méthode fonctionne car bien qu'un attaquant puisse forcer votre navigateur à envoyer des demandes d'obtention / post, il ne peut pas afficher la réponse, et il ne peut pas lire ce jeton nécessaire pour forger la demande. Ce jeton peut être obtenu avec XSS, alors assurez-vous de Testez votre site pour XSS < / a>.

Un bon procédé de génération d'un jeton CSRF est MD5 (UNIQID (MT_RAND (), True)); Cela devrait être suffisant pour arrêter la CSRF. MD5 () est utilisé pour obscurcir la manière dont le sel est généré. Gardez à l'esprit que l'heure actuelle est non un secret, l'attaquant sait exactement à quelle heure la demande du CSRF est produite et peut s'interroger lorsque la session a été créée. Vous devez supposer que l'attaquant peut faire de nombreuses suppositions , et dans la pratique, cela est simple à accomplir en écrivant un tas d'iframes à la page.


8 commentaires

Désolé, mais que l'utilisation de l'en-tête de référent n'est pas une protection CSRF valide. L'en-tête de référent est facultatif et peut être omis par le navigateur à tout moment (RFC2616, HTTP 1.1) et il est possible de plongeez-le.


Oh, et utiliser une variable de session n'est pas en sécurité non plus. Considérez l'affaire suivante: Lorsque l'utilisateur entre dans la page avec le formulaire, vous créez votre jeton secret et définissez-le comme une variable de session, lorsque l'utilisateur soumet le formulaire, le script vérifie le jeton, s'il est valide, l'action est exécutée. . Cela peut être attaqué simplement en utilisant un iframe et un autre JavaScript. L'attaquant peut tromper l'utilisateur à Visintg un site malveillant. Le site malveillant contient un iframe qui charge le formulaire du site cible (jeton est maintenant défini). L'attaquant utilise une minuterie JavaScript pour changer la source de l'iframe (continue)


(suite au commentaire précédent) à l'URL csRF cible. L'URL est demandée et la variable de session est définie, l'action est donc traitée.


@Kim l Alors combien d'exploits de CSRF avez-vous écrit? J'écris beaucoup d'entre eux, et c'est pourquoi je sais ce que vous décrivez est une violation claire de la même politique d'origine. Vous devez lire le manuel Google Browser SEC, puis essayer cette attaque. (Ça ne marchera jamais :)


@Kim l Autre chose, Motorola Surfboard Les modems sont très populaires, chances que vous avez dans votre maison. Allez à 192.168.100.1 et essayez d'écrire une exploitement CSRF pour redémarrer le modem.


@Le Rook, désolé, re-lisez votre message et ce que vous avez décrit fonctionnera comme il est essentiellement la même chose que j'ai décrit dans ma réponse, une autre stratégie pour créer le jeton secret. Je lis d'abord que votre message portait sur une forme multi-pages, que j'ai décrit une attaque pour (cela fonctionnera si les pages sont prévisibles et qu'il n'est donc pas nécessaire de lire la réponse HTTP). Mon attaque est valable et ne conflit pas avec la même politique d'origine, car elle n'a jamais besoin de lire la réponse. En d'autres termes, mon mauvais. Si vous pensez toujours que mon attaque n'est pas valide, je peux vous fournir une épreuve de concept :)


@KIM L Le référenant ne peut pas être modifié par l'attaquant à l'aide de CSRF et je ne sais pas comment une iframe aide à cette attaque.


@Le Rook, comme je l'ai dit, j'ai mal interprété votre réponse et mon commentaire portait sur des formes multi-pages. L'IFrame ne peut qu'en attaquer des formes multi-pages, il n'avait rien à voir avec l'en-tête de référateur. Voici un exemple de la manière dont une application peut être trompé dans la pensée du référent est autre chose que ce que c'est réellement. Cette attaque n'écarchait pas réellement l'en-tête de référateur, mais démontre plutôt que tout n'est pas exactement ce que vous pensez que c'est. Assurez-vous de lire un autre blog posté lié au début. blog.quaji.com/2009/08/... < / a>



2
votes

TREUR a eu raison, mais je veux toujours clarifier quelques choses et vous fournir certaines sources de matière de référence. Comme le dit TREUR, ne faites jamais confiance à des données d'entrée utilisateur, qui inclut tous les en-têtes envoyés par le navigateur.

Ce que vous décrivez, est une attaque de falsification typique de la demande. Vérification de l'en-tête de référent n'est pas une protection valide contre les attaques CSRF, car, selon le RFC2616 ( Hyper Text Transfer Protocole 1.1 ), l'en-tête de référateur est facultatif et peut donc être omis par le navigateur à tout moment. Si vous utilisez SSL, l'en-tête de référateur est toujours omis par des navigateurs. Deuxièmement, il s'agit d'une valeur définie par l'utilisateur et ne doit donc pas être approuvée.

La protection recommandée contre les attaques CSRF consiste à utiliser le motif de jeton synchronisé. Cela signifie que vous devriez créer un jeton secret qui est intégré comme champ caché sous votre forme. Lorsque le formulaire est affiché, vous vérifiez que le jeton secret est présent et qu'il est valide. Il existe de multiples stratégies pour créer des jetons de sécurité. Je vais décrire une façon de créer les jetons:

Pour chaque action dans votre application, créez un nom d'action unique pour eux. Par exemple, "delete_user", "add_user" ou "sauvegarde_user_profile". Disons que le formulaire que vous avez décrit a le nom d'action "foobar". Concaténer le nom d'action avec l'ID de session de l'utilisateur et une valeur secrète.

$ stringvalue = "foobar". "valeur secrète". ID de session();

Pour créer le jeton de sécurité, créez un hachage de la chaîne concaténée, vous pouvez utiliser SHA1 pour créer le hachage. Pour diminuer le risque d'attaques de force brute, utilisez une clé plus grande dans le hachage, par exemple SHA 512.

$ secrettokt = hachage ("Sha5125", $ stringvalue);

Définissez ce jeton dans le champ caché de votre formulaire. Lorsque le formulaire est soumis, recréez le jeton et vérifiez qu'il correspond à celui soumis sous la forme. Ce jeton est valable pour une session utilisateur. On peut discuter, qu'il existe une fenêtre d'opportunité où un attaquant peut réutiliser le jeton car il n'est pas régénéré à chaque demande. Toutefois, avec des stratégies de gestion de la session appropriées, cela ne devrait pas vraiment être une préoccupation.

Comme je l'ai dit, une bonne gestion de la session est nécessaire. Cela signifie que vous ne devriez pas garder les sessions vivantes à long terme. Notamment Fixation de session Vulnérabilités annulera les mesures de protection du CSRF, car l'attaquant est alors en contrôle de la session d'utilisateur et peut donc "prédire" les jetons secrets.

Voici quelques liaisons que je vous recommande de lire:


0 commentaires