Maison >développement back-end >tutoriel php >Les mesures préventives de yii2 contre les attaques CSRF

Les mesures préventives de yii2 contre les attaques CSRF

不言
不言original
2018-07-10 15:06:362027parcourir

Cet article présente principalement les mesures préventives contre les attaques CSRF dans yii2. Il a une certaine valeur de référence. Maintenant, je le partage avec vous. Les amis dans le besoin peuvent s'y référer

Aujourd'hui, frère Bei le vulgarisera. tout le monde. Qu’est-ce que csrf ? Si vous le savez déjà, vous pouvez simplement faire défiler l’article jusqu’en bas et lui donner un like. Le

CSRF (Cross-site request forgery) est une utilisation malveillante de sites Web et a été répertorié dans le top 20 des menaces de sécurité Internet en 2007. L'un des dangers cachés.

À propos de CSRF, commençons par une histoire~

L'incident de la perte d'argent de Lao Wang

Cette histoire commence avec la perte de 10 000 yuans du programmeur Lao Wang. un voleur, mais il a été retrouvé en vain. Après avoir perdu l'argent, Lao Wang n'arrêtait pas de penser : Comment a-t-il perdu l'argent, pourquoi a-t-il perdu l'argent, pourquoi ai-je perdu l'argent ~~

Plus tard, Lao Wang a développé de sérieux problèmes psychologiques. Décidé de se venger de la société.

Lao Wang a d'abord étudié le système bancaire en ligne, et il a découvert que le transfert était sous la forme de GET

https://bank.abc.com/withdraw?account=liuxiaoer&amount=1000&to=abei

Cela signifie que les 1 000 yuans de liuxiaoer a été transféré à abei, bien sûr lorsque la demande atteint le serveur bancaire, le programme vérifiera si la demande provient d'une session légitime et que l'utilisateur de la session est liuxiaoer et s'est connecté dans.

Lao Wang lui-même a également un compte bancaire wang2 Il a essayé de se connecter et a envoyé une demande à la banque via le navigateur. Le code est le suivant

https://bank.abc.com/withdraw?account=liuxiaoer&amount=1000&to=wang2
<.>Cela a échoué~car la connexion actuelle Le compte est Lao Wang lui-même. Après avoir envoyé la demande, le serveur a constaté que l'utilisateur wang2 et account=liuxiaoer auquel appartenait la session n'étaient pas la même personne, elle a donc été rejetée.

En d'autres termes, cette opération doit être effectuée par

liuxiaoer vous-même. Le pouvoir de vengeance est terrible. Lao Wang a trouvé le liuxiaoer à travers Facebook à travers des couches et des couches, qui est le numéro de compte bancaire du coursier M. Liu.

C'est ainsi qu'un grand plan est né, le plan de Lao Wang était comme ça.

1. Créez d'abord une page Web, ajoutez le code suivant à la page Web

src="https://bank.abc.com/withdraw?account=liuxiaoer&amount=1000&to=wang2"
Laissez ensuite Liu (liuxiaoer) visiter cette page Web à travers divers scénarios.

2. Lorsque Lao Liu (liuxiaoer) visite cette page Web, la demande ci-dessus sera envoyée à la banque et, à ce moment-là, elle contiendra également les informations relatives aux cookies du navigateur de Lao Liu (liuxiaoer). , ce n'est généralement pas le cas. Cela réussira car le serveur bancaire constate que Liu (liuxiaoer) n'est pas connecté.

3. Lao Wang a pensé à une astuce. Il a trouvé un homme d'affaires gris Lao Li sur Taobao et lui a demandé d'utiliser diverses méthodes. En bref, il a demandé à Lao Liu (liuxiaoer) de transférer de l'argent à Lao Li via le. navigateur.

4. Dans les 2 minutes suivant la troisième étape, Lao Wang a réussi à laisser Lao Liu (liuxiaoer) visiter à nouveau la page Web qu'il a créée. Comme vous le savez, Lao Liu (liuxiaoer) est actuellement à la banque. la session n'a pas expiré. Après que la page Web de Lao Wang ait envoyé une demande au serveur de la banque, la vérification a réussi et le paiement a réussi.

5. Lao Wang a reçu le paiement. Lao Liu (liuxiaoer) ne savait pas tout cela pour la banque, c'était un virement normal.

Il s'agit d'une attaque CSRF et ne peut pas être interceptée par le navigateur.

Caractéristiques des attaques CSRF

Sur la base de l'histoire sanglante ci-dessus, nous résumons plusieurs caractéristiques des attaques CSRF.

  • Les pirates utilisent le cookie de la victime et d'autres informations du navigateur pour tromper les nouveaux utilisateurs du serveur. Le pirate ne peut pas obtenir le cookie, etc.

  • En raison de la politique de même origine du navigateur, les pirates ne peuvent pas obtenir les résultats de la réponse de l'attaque. Tout ce qu'ils peuvent faire est de lancer une requête. Vous souvenez-vous encore que de nombreux sites Web de phishing simulent une connexion. des boîtes ?

  • Les attaques CSRF envoient principalement des requêtes de modification de données.

Objet de défense CSRF

Donc, ce que nous voulons protéger, ce sont toutes les demandes des clients qui peuvent entraîner des modifications de données, telles que des nouvelles, des mises à jour et des suppressions.

Solution de défense CSRF

Sur la base des caractéristiques des attaques CSRF, il existe actuellement trois stratégies principales pour se défendre contre les attaques CSRF dans l'industrie :

  • Vérifiez le champ HTTP Referer ;

  • Ajoutez un jeton dans l'adresse de la demande et vérifiez-le

  • Personnalisez l'attribut dans l'en-tête HTTP et vérifiez-le ; .

HEEP Referer

Lors d'une requête http, il y a un champ appelé Referer dans l'en-tête, qui enregistre l'adresse source de cette requête. Par conséquent, le serveur peut déterminer si la demande est légale en fonction du fait que ce champ correspond au même nom de domaine, car le référent de la demande initiée par la propre page Web du client est un site Web de pirate informatique.

Cette méthode est la plus simple et ne nécessite pas de modifier le code métier. Il suffit d'intercepter et d'analyser chaque requête arrivant sur le serveur.

Cependant, les inconvénients de cette méthode sont également évidents, car la valeur du Referer appartient au navigateur. Bien que le protocole HTTP ne permette pas la modification, si le navigateur lui-même présente des failles, cela peut entraîner la disparition du Referer. réglé manuellement

Pas sûr.

Par exemple, IE6 peut falsifier la valeur Referer via des méthodes.

Cette méthode n'est pas absolument disponible, même dans les navigateurs les plus récents. Elle implique la confidentialité des utilisateurs. De nombreux utilisateurs configureront le navigateur pour ne pas fournir de référent, de sorte que le serveur ne peut pas le faire de manière imprudente s'il ne peut pas obtenir le service Refuser. il est possible qu'il s'agisse d'une demande légitime.

添加Token

CSRF攻击之所以能成功,是因为黑客完全伪造了一次用户的正常请求(这也是浏览器无法拦截的原因),并且cookie信息就是用户自己的,那么我们如果在请求中放入一些黑客无法去伪造的信息(不存在与cookie中),不就可以抵御了么!

比如在请求前生成一个token放到session中,当请求发生时,将token从session拿出来和请求提交过来的token进行对比,如果相等则认证通过,否则拒绝。token时刻在变化,黑客无法去伪造。

针对于不同类型的请求一般方案是

  • GET 放到url中,比如http://url?csrftoken=xxxx

  • POST 放到表单的隐藏域

对于GET请求,这里有一点要说明,在一个网站中请求的url很多,一般情况我们是通过js对dom的所有节点进行遍历,发现a链接就在其href中增加token。

这里存在一个问题,比如黑客将自己网站的链接发到了要攻击页面,则黑客网站链接后面会有一个token,此刻客户可以通过编写自己网站代码得到这个token,然后用这个token立刻构造表单,发起CSRF攻击,因此在js遍历的时候,如果发现不是本站的链接,可以不加token。

在HTTP头部增加属性

这个方法在思路上和上面的token方式一样,只不过将token放到了HTTP头部中,不再参数传递,通过XMLHttpRequest类可以一次性的给所有请求加上csrftoken这个HTTP头属性并设置值。

这种方法适合上面批量添加token不方便的情况,一次性操作,不过局限性也比较大,XMLHttpRequest请求通常用在ajax方法中,并非所有请求都适合。

Yii2

首先要说的是每种CSRF防范措施都有其弊端,无论你的防范多么严密,黑客拥有更多的攻击手段,因此在重要逻辑上(必须写入和删除)必须非常小心,接下来我们把yii2框架在csrf上的部署说一下。

我们以yii2.0.14为解说版本。

在CSRF这块,yii2框架采取了HTTP头部和参数token并行的方式,针对于每个请求,在beforeAction都会做一次判断,如下

// vendor/yiisoft/yii2/web/Controller.php
public function beforeAction($action) {
    
    if (parent::beforeAction($action)) {
        if ($this->enableCsrfValidation && Yii::$app->getErrorHandler()->exception === null && !Yii::$app->getRequest()->validateCsrfToken()) {
            throw new BadRequestHttpException(Yii::t('yii', 'Unable to verify your data submission.'));
        }

        return true;
    }

    return false;
}

如果我们没有设置 enableCsrfValidation 为false,并且没有报错,则会进行csrf验证,核心方法就是

Yii::$app->getRequest()->validateCsrfToken()

该方法存在于 vendor/yiisoft/yii2/web/Request.php 中,我们看一看它。

public function validateCsrfToken($clientSuppliedToken = null) {
    // 省略上面代码
    return $this->validateCsrfTokenInternal($this->getBodyParam($this->csrfParam), $trueToken)
        || $this->validateCsrfTokenInternal($this->getCsrfTokenFromHeader(), $trueToken);
}

validateCsrfToken函数代码我们只需要看最后的返回,getBodyParam或getCsrfTokenFromHeader方法得到的token,只要有一种验证通过,就认为合法。

以上是整体的思路,为了让你看的更清晰,我画一个图并增加一些名词解释。

Les mesures préventives de yii2 contre les attaques CSRF

以上是yii2的csrf策略部署,当然我还是推荐你使用 xdebug等调试工具 一步一步看看这个过程。

最后我在把上图的关键函数进行说明

  • generateCsrfToken() 该函数生成token并存到cookie或session中,该值不会随页面刷新而变化,它更多充当钥匙的作用,根绝它生成具体的csrfToken。

  • getCsrfToken() 生成具体的csrfToken,就是你在表单隐藏域中看到的那个值,这个值将来会传到服务器和真实的csrfToken进行对比,验证是否合法。

  • validateCsrfToken()  进行合法性验证,该函数得到一个真实的csrfToken然后和客户端上传来的csrfToken进行对比。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

如何在yii2-wx中使用try_catch

关于Yii2中GridView的用法总结

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn