Le nom complet de CSRF est Cross-site request falsification, et son nom chinois est cross-site request forgery (la falsification de requêtes inter-sites [lire plus facilement] CSRF est une sorte d'application Web qui maintient les utilisateurs connectés). dans Une méthode d'attaque qui effectue des opérations involontaires. Par rapport à XSS, CSRF profite de la confiance du système dans le navigateur de pages, tandis que XSS tire parti de la confiance du système dans l'utilisateur.
attaque csrf, c'est-à-dire falsification de demande intersite falsification de demande intersite (nom de domaine), où contrefaçon signifie contrefaçon. Il existe de nombreuses introductions sur CSRF sur Internet. Par exemple, un article senior explique en détail les méthodes d'attaque de CSRF. Veuillez vous référer à cet article pour une brève explication : La réalisation des attaques CSRF repose sur un fait aussi simple : lorsque nous utilisons. un navigateur pour naviguer sur le Web, nous ouvrons généralement plusieurs onglets de navigateur (ou fenêtres). Si nous nous connectons à un site A, si le site A suit la session de l'utilisateur via des cookies, une fois que l'utilisateur s'est connecté au site A, le site A le fera. définir les paramètres sur le client de l'utilisateur, si le site A a une page siteA-page.php (ressource url) et que le site B connaît l'adresse url, et que l'adresse de cette page est intégrée dans une page siteB-page.php de site B d'une manière ou d'une autre, si A ce moment, l'utilisateur ouvre siteB-page.php du site B tout en maintenant la session du site A. Puis tant que la page siteB-page.php peut déclencher cette adresse url (demandant l'url ressource du site A), une attaque CSRF est réalisée.
L’explication ci-dessus est difficile à expliquer, donnons donc un exemple simple pour la démontrer.
1, arrière-plan et processus de demande normal
Un nom de domaine de site est html5.yang.com, il a une adresse /get-update.php?uid=uid&username=username, vous pouvez voir Cette adresse peut transmettre certains paramètres via la méthode get. Si la logique de cette page est : elle met à jour le nom d'utilisateur en jugeant si l'uid est légal. Le script de cette page est le suivant :
<.>
<?php // 这里简便起见, 从data.json中取出数据代替请求数据库 $str = file_get_contents('data.json'); $data = json_decode($str, true); // 检查cookie和请求更改的uid, 实际应检查数据库中的用户是否存在 empty($_COOKIE['uid']) ||empty($_GET['uid']) || $_GET['uid'] != $data['id'] ? die('非法用户') : ''; // 检查username参数 $data['username'] = empty($_GET['username']) ? die('用户名不能为空') : $_GET['username']; // 更新数据 $data['username'] = $_GET['username']; if(file_put_contents('data.json', json_encode($data))) { echo "用户名已更改为{$data['username']}<br>"; } else { die('更新失败'); }
<?php // 这里用一个data.json文件保存用户数据,模拟数据库中的数据 // 先初始化data.json中的数据为{"id":101,"username":"jack"}, 注意这句只让它执行一次, 然后把它注释掉 // file_put_contents('data.json','{"id":101,"username":"jack"}'); $data = json_decode(file_get_contents('data.json'), true); // 这里为了简便, 省略了用户身份验证的过程 if ($data['username']) { // 设置cookie setcookie('uid', $data['id'], 0); echo "登录成功, {$data['username']}<br>"; } ?> <a href="http://html5.yang.com/csrfdemo/get-update.php?uid=101&username=json" rel="external nofollow" > 更新用户名为json </a>
<?php ?> <img src="http://html5.yang.com/csrfdemo/get-update.php?uid=101&username=jsonp">
ci-dessous Visitez ensuite la page csrfdemo.php du site A :
Vous pouvez voir que le nom d'utilisateur a été changé en jsonp.
Une brève analyse : le csrf.php du site B utilise la balise img en HTML Nous savons tous que la balise img a un attribut src, et la valeur de l'attribut pointe vers l'adresse de l'image qui doit être utilisée. être chargé. Lorsque la page est chargée, Charger une image équivaut à lancer une requête http à l'adresse pointée par src. Tant que l'adresse de l'image est modifiée en adresse de script, l'attaque CSRF la plus simple sera naturellement réalisée. . De cette façon, le CSRF est en fait très facile à mettre en œuvre, mais tout le monde est un « gentleman », et personne ne restera inactif pour faire des choses aussi « obscènes ». Mais vous ne devez pas avoir l’intention de nuire aux autres, ni l’intention de vous prémunir contre les autres. Voyons comment empêcher simplement cette attaque CSRF la plus simple.
3. Mesures préventives simples
En fait, les mesures préventives sont relativement simples. Le site A peut déterminer la source de l'en-tête de requête dans le script get-update.php. pas le site A, il peut tronquer la requête, ajoutez du code à get-update.php ci-dessous :
<?php // 检查上一页面是否为当前站点下的页面 if (!empty($_SERVER['HTTP_REFERER'])) { if (parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) != 'html5.yang.com') { // 可以设置http错误码或者指向一个无害的url地址 //header('HTTP/1.1 404 not found'); //header('HTTP/1.1 403 forbiden'); header('Location: http://html5.yang.com/favicon.ico'); // 这里需要注意一定要exit(), 否则脚本会接着执行 exit(); } } $str = file_get_contents('data.json'); // 代码省略
但是,这样就万事大吉了吗,如果http请求头被伪造了呢?A站点升级了防御,B站点同时也可以升级攻击,通过curl请求来实现csrf,修改B站点的csrf.php代码如下:
<?php $url = 'http://html5.yang.com/csrfdemo/get-update.php?uid=101&username=jsonp'; $refer = 'http://html5.yang.com/'; // curl方法发起csrf攻击 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); // 设置Referer curl_setopt($ch, CURLOPT_REFERER, $refer); // 这里需要携带上cookie, 因为A站点get-update.php对cooke进行了判断 curl_setopt($ch, CURLOPT_COOKIE, 'uid=101'); curl_exec($ch); curl_close($ch); ?> <img src="http://html5.yang.com/csrfdemo/get-update.php?uid=101&username=jsonp">
这样同样可以实现csrf攻击的目的。那么就没有比较好的防范方法了吗?
4,小结
下面我们回到问题的开始,站点A通过cookie来跟踪用户会话,在cookie中存放了重要的用户信息uid,get-update.php脚本通过判断用户的cookie正确与否来决定是否更改用户信息,看来靠cookie来跟踪会话并控制业务逻辑是不太安全的,还有最严重的一点:get-update.php通过get请求来修改用户信息,这个是大忌。所以站点A可以接着升级防御:用session来代替cookie来跟踪用户会话信息,将修改用户信息的逻辑重写,只允许用post方法来请求用户信息。站点B同样可以升级攻击:curl可以构造post请求,劫持session等等,不过这些我还没研究过,后续再说吧。
php curl带有csrf-token验证模拟提交实例详解
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!