{"id":2493,"date":"2020-03-25T20:58:39","date_gmt":"2020-03-25T12:58:39","guid":{"rendered":"http:\/\/www.yuguoxy.com\/geekhome\/?p=2493"},"modified":"2020-03-25T20:58:39","modified_gmt":"2020-03-25T12:58:39","slug":"web%e5%ae%89%e5%85%a8%e5%b0%8f%e6%80%bb%e7%bb%93xsscsrf%e5%8f%8a%e5%85%b6%e9%98%b2%e5%be%a1","status":"publish","type":"post","link":"https:\/\/ai.zhousir.top\/?p=2493","title":{"rendered":"Web\u5b89\u5168\u5c0f\u603b\u7ed3:XSS,CSRF\u53ca\u5176\u9632\u5fa1"},"content":{"rendered":"<div>\n<h1 class=\"heading\" data-id=\"heading-0\">\u524d\u8a00<\/h1>\n<p>\u5176\u5b9e, \u524d\u7aef\u7684\u5b89\u5168\u5e76\u6ca1\u6709\u5f88\u591a, \u4e0d\u8fc7\u77e5\u9053\u4e86, \u8d77\u7801\u540e\u7aef\u5144\u5f1f\u4e0d\u4f1a\u90a3\u4e48\u7d2f\u4e86\u3002<br \/>\n\u672c\u6587\u4e3b\u8981\u8ba8\u8bba\u4ee5\u4e0b\u51e0\u79cd\u653b\u51fb\u65b9\u5f0f :<\/p>\n<ul>\n<li><strong>XSS\u65b9\u5f0f<\/strong><\/li>\n<li><strong>CSRF\u65b9\u5f0f<\/strong><\/li>\n<li><strong>\u70b9\u51fb\u52ab\u6301<\/strong><\/li>\n<\/ul>\n<p>\u5e0c\u671b\u5927\u5bb6\u5728\u9605\u8bfb\u5b8c\u6587\u672c\u4e4b\u540e, \u80fd\u591f\u5f88\u597d\u5730\u56de\u7b54\u4ee5\u4e0b\u7684\u51e0\u4e2a\u95ee\u9898:<\/p>\n<ul>\n<li><strong>\u524d\u7aef\u7684\u653b\u51fb\u65b9\u5f0f\u6709\u54ea\u4e9b?<\/strong><\/li>\n<li><strong>\u4ec0\u4e48\u662fXSS\u65b9\u5f0f? XSS\u653b\u51fb\u6709\u51e0\u79cd\u7c7b\u578b?\u5982\u4f55\u9632\u8303XSS\u653b\u51fb?<\/strong><\/li>\n<li><strong>\u4ec0\u4e48\u662fCSRF\u653b\u51fb?\u5982\u4f55\u9632\u8303CSRF\u653b\u51fb?<\/strong><\/li>\n<li><strong>\u5982\u4f55\u68c0\u6d4b\u7f51\u7ad9\u662f\u5426\u5b89\u5168?<\/strong><\/li>\n<\/ul>\n<h2 class=\"heading\" data-id=\"heading-1\">1. XSS\u65b9\u5f0f<\/h2>\n<p>XSS(Cross-Site-Scripting),\u8de8\u7ad9\u811a\u672c\u653b\u51fb\u662f\u4e00\u79cd\u4ee3\u7801\u6ce8\u5165\u653b\u51fb\u3002\u653b\u51fb\u8005\u5728\u76ee\u6807\u7f51\u7ad9\u4e0a\u6ce8\u5165\u6076\u610f\u4ee3\u7801,\u5f53\u88ab\u653b\u51fb\u8005\u767b\u5f55\u7f51\u7ad9\u65f6\u5c31\u4f1a\u6267\u884c\u8fd9\u4e9b\u6076\u610f\u4ee3\u7801, \u8fd9\u4e9b\u811a\u672c\u53ef\u4ee5\u8bfb\u53d6 cookie ,session tokens , \u6216\u8005\u5176\u4ed6\u654f\u611f\u7684\u7f51\u7ad9\u6d88\u606f,\u5bf9\u7528\u6237\u8fdb\u884c\u9493\u9c7c\u6b3a\u8bc8,\u751a\u81f3\u53d1\u8d77\u8815\u866b\u653b\u51fb\u7b49\u3002<\/p>\n<p><strong>XSS\u7684\u672c\u8d28:\u6076\u610f\u4ee3\u7801\u672a\u7ecf\u8fc7\u6ee4,\u4e0e\u7f51\u7ad9\u6b63\u5e38\u7684\u4ee3\u7801\u6df7\u5728\u4e00\u8d77;\u6d4f\u89c8\u5668\u65e0\u6cd5\u5206\u8fa8\u54ea\u4e9b\u811a\u672c\u662f\u53ef\u4fe1\u7684,\u5bfc\u81f4\u6076\u610f\u811a\u672c\u88ab\u6267\u884c\u3002\u7531\u4e8e\u76f4\u63a5\u5728\u7528\u6237\u7684\u7ec8\u7aef\u6267\u884c,\u6076\u610f\u4ee3\u7801\u80fd\u591f\u76f4\u63a5\u83b7\u53d6\u7528\u6237\u7684\u4fe1\u606f,\u5229\u7528\u8fd9\u4e9b\u4fe1\u606f\u5192\u5145\u7528\u6237\u5411\u7f51\u7ad9\u53d1\u8d77\u653b\u51fb<\/strong><\/p>\n<p>XSS\u7684\u5206\u7c7b:<\/p>\n<ul>\n<li>\u5b58\u50a8\u578b<\/li>\n<li>\u53cd\u5c04\u578b<\/li>\n<li>DOM \u578b<\/li>\n<\/ul>\n<h3 class=\"heading\" data-id=\"heading-2\">1.1 \u53cd\u5c04\u578bXSS<\/h3>\n<p>\u5f53\u7528\u6237\u70b9\u51fb\u4e00\u4e2a\u6076\u610f\u94fe\u63a5, \u6216\u8005\u63d0\u4ea4\u4e00\u4e2a\u8868\u5355, \u6216\u8005\u8fdb\u5165\u4e00\u4e2a\u6076\u610f\u7f51\u7ad9\u65f6, \u6ce8\u5165\u811a\u672c\u8fdb\u5165\u88ab\u653b\u51fb\u8005\u7684\u7f51\u7ad9\u3002Web \u670d\u52a1\u5668\u5c06\u6ce8\u5165\u811a\u672c,\u6bd4\u5982\u4e00\u4e2a\u9519\u8bef\u4fe1\u606f, \u641c\u7d22\u7ed3\u679c\u7b49 , \u672a\u8fdb\u884c\u8fc7\u6ee4\u76f4\u63a5\u8fd4\u56de\u5230\u7528\u6237\u7684\u6d4f\u89c8\u5668\u4e0a\u3002<\/p>\n<p>\u53cd\u5c04\u578bXSS\u7684\u653b\u51fb\u6b65\u9aa4:<\/p>\n<ul>\n<li>1.\u653b\u51fb\u8005\u6784\u9020\u51fa\u7279\u6b8a\u7684URL, \u5176\u4e2d\u5305\u542b\u6076\u610f\u4ee3\u7801<\/li>\n<li>2.\u7528\u6237\u6253\u5f00\u5e26\u6709\u6076\u610f\u4ee3\u7801\u7684URL\u65f6, \u7f51\u7ad9\u670d\u52a1\u7aef\u5c06\u6076\u610f\u4ee3\u7801\u4ece URL\u4e2d\u53d6\u51fa, \u62fc\u63a5\u5728 HTML\u4e2d\u8fd4\u56de\u7ed9\u6d4f\u89c8\u5668<\/li>\n<li>3.\u7528\u6237\u6d4f\u89c8\u5668\u63a5\u6536\u5230\u54cd\u5e94\u540e\u89e3\u6790\u6267\u884c, \u6df7\u5728\u5176\u4e2d\u7684\u6076\u610f\u4ee3\u7801\u4e5f\u88ab\u6267\u884c\u3002<\/li>\n<li>4.\u6076\u610f\u4ee3\u7801\u7a83\u53d6\u7528\u6237\u6570\u636e\u5e76\u53d1\u9001\u5230\u653b\u51fb\u8005\u7684\u7f51\u7ad9, \u6216\u8005\u5192\u5145\u7528\u6237\u7684\u884c\u4e3a, \u8c03\u7528\u76ee\u6807\u7f51\u7ad9\u63a5\u53e3\u6267\u884c\u653b\u51fb\u8005\u6307\u5b9a\u7684\u64cd\u4f5c\u3002<\/li>\n<\/ul>\n<p>\u53cd\u5c04\u578b XSS \u6f0f\u6d1e\u5e38\u89c1\u4e8e URL \u4f20\u9012\u53c2\u6570\u7684\u529f\u80fd , \u5982\u7f51\u7ad9\u641c\u7d22 , \u8df3\u8f6c\u7b49\u3002\u7531\u4e8e\u9700\u8981\u7528\u6237\u4e3b\u52a8\u6253\u5f00\u6076\u610f\u7684 URL \u624d\u80fd\u751f\u6548 , \u653b\u51fb\u8005\u5f80\u5f80\u4f1a\u7ed3\u5408\u591a\u79cd\u624b\u6bb5\u8bf1\u5bfc\u7528\u6237\u70b9\u51fb<\/p>\n<p>POST \u7684\u5185\u5bb9\u4e5f\u53ef\u4ee5\u89e6\u53d1\u53cd\u5c04\u578b XSS , \u53ea\u4e0d\u8fc7\u5176\u89e6\u53d1\u6761\u4ef6\u6bd4\u8f83\u82db\u523b (\u9700\u8981\u6784\u9020\u8868\u5355\u63d0\u4ea4\u9875\u9762 , \u5e76\u5f15\u5bfc\u7528\u6237\u70b9\u51fb),\u6240\u4ee5\u975e\u5e38\u5c11\u89c1\u3002<\/p>\n<p><strong>\u8bdd\u4e0d\u591a\u8bf4 , \u6211\u4eec\u6765\u4e3e\u4e2a\u4f8b\u5b50<\/strong><\/p>\n<figure><figcaption><\/figcaption><\/figure>\n<pre><code class=\"copyable\">\/\/\u524d\u7aef\u4ee3\u7801\r\n\/\/ index.html\r\n\/\/ \u7531\u4e8e\u5fc5\u987b\u8bf1\u5bfc\u7528\u6237\u70b9\u51fb,\u6240\u4ee5\u53ef\u80fd\u662f\u8fd9\u6837\u7684\r\n&lt;button id=\"btn\" onclick=\"test()\"&gt;\r\n    \/\/\u8fd9\u662f\u4e00\u5f20\u5f88\u597d\u770b\u7684\u56fe\u7247\r\n    &lt;img src=\"https:\/\/ss1.bdstatic.com\/70cFvXSh_Q1YnxGkpoWK1HF6hhy\/it\/u=1136880418,2628684495&amp;fm=15&amp;gp=0.jpg\" alt=\"\"&gt;\r\n&lt;\/button&gt;\r\n&lt;script&gt;\r\n    var test = function() {\r\n    \/\/ \u6784\u9020\u51fa\u7684\u7279\u6b8a\u7684 url , \u5176\u4e2d\u5305\u542b\u6076\u610f\u4ee3\u7801\r\n    let url = `\/welcome?type=&lt;script&gt;alert('\u6076\u610f\u5185\u5bb9')&lt;\\\/script&gt;`;\r\n    location.href = url;\r\n}\r\n&lt;\/script&gt;\r\n\r\n\/\/ \u540e\u7aef\u4ee3\u7801\r\n\/\/ server.js\r\nconst express = require('express');\r\nconst app = express();\r\napp.use(express.static(path.join(__dirname)))\r\napp.get('\/welcome',function(req, res) {\r\n    \/\/ \u628a\u6076\u610f\u4ee3\u7801\u5f53\u505a\u5b57\u7b26\u4e32, \u4f20\u8f93\u56de\u6d4f\u89c8\u5668\r\n    res.send(`${req.query.type}`);\r\n    res.end();\r\n})\r\n\r\napp.listen(3000, ()=&gt; {\r\n    console.log('server is running at port 4000')\r\n});\r\n\r\n<\/code><\/pre>\n<p><strong>\u5982\u679c\u4e0d\u5e0c\u671b\u88ab\u524d\u7aef\u62ff\u5230 cookie, \u540e\u7aef\u53ef\u4ee5\u8bbe\u7f6e httpOnly (\u4e0d\u8fc7\u8fd9\u4e2a\u4e0d\u662f XSS \u7684\u89e3\u51b3\u65b9\u6848 , \u53ea\u80fd\u964d\u4f4e\u53d7\u635f\u8303\u56f4)<\/strong><\/p>\n<h4 class=\"heading\" data-id=\"heading-3\">\u5982\u4f55\u9632\u8303\u53cd\u5c04\u578b XSS\u653b\u51fb?<\/h4>\n<p><strong>\u5bf9\u5b57\u7b26\u4e32\u8fdb\u884c\u7f16\u7801<\/strong><br \/>\n\u5bf9url\u7684\u67e5\u8be2\u53c2\u6570\u8fdb\u884c\u8f6c\u4e49\u540e\u518d\u8f93\u51fa\u5230\u9875\u9762<\/p>\n<pre><code class=\"copyable\">app.get('\/welcome',function(req,res) {\r\n    \/\/\u5bf9\u67e5\u8be2\u53c2\u6570\u8fdb\u884c\u7f16\u7801\uff0c\u907f\u514d\u53cd\u5c04\u578b XSS\u653b\u51fb\r\n    res.send(`${encodeURIComponent(req.query.type)}`); \r\n})\r\n<\/code><\/pre>\n<p><strong>\u603b\u7ed3:\u7b80\u5355\u6765\u8bf4,\u524d\u7aef\u5411\u540e\u7aef\u53d1\u9001GET\u8bf7\u6c42\u6570\u636e,\u540e\u7aef\u8fd4\u56de\u7ed3\u679c\u4e4b\u524d,\u5fc5\u987b\u5148\u5bf9url\u67e5\u8be2\u53c2\u6570\u8fdb\u884c\u7f16\u7801\u518d\u8f93\u51fa\u5230\u9875\u9762<\/strong><\/p>\n<h3 class=\"heading\" data-id=\"heading-4\">1.2 DOM\u578bXSS<\/h3>\n<p>DOM\u578b XSS \u653b\u51fb , \u5b9e\u9645\u4e0a\u5c31\u662f\u524d\u7aef javaScript \u4ee3\u7801\u4e0d\u591f\u4e25\u8c28 , \u628a\u4e0d\u53ef\u4fe1\u7684\u5185\u5bb9\u63d2\u5165\u5230\u4e86\u9875\u9762 \u3002\u5728\u4f7f\u7528 .innerHTML , .outerHTML , appendChild , document.write()\u7b49 API \u65f6\u8981\u7279\u522b\u5c0f\u5fc3 , <strong>\u4e0d\u8981\u628a\u4e0d\u53ef\u4fe1\u7684\u6570\u636e\u4f5c\u4e3a\u4e3a HTML \u63d2\u5165\u5230\u9875\u9762\u4e0a<\/strong> , \u5c3d\u91cf\u4f7f\u7528 .innerText , .textContent , setAttribute()\u7b49\u3002<\/p>\n<h4 class=\"heading\" data-id=\"heading-5\">DOM\u578bXSS \u7684\u653b\u51fb\u6b65\u9aa4:<\/h4>\n<ul>\n<li>1.\u653b\u51fb\u8005\u6784\u9020\u51fa\u7279\u6b8a\u6570\u636e , \u5176\u4e2d\u5305\u542b\u6076\u610f\u4ee3\u7801<\/li>\n<li>2.\u7528\u6237\u6d4f\u89c8\u5668\u6267\u884c\u6076\u610f\u4ee3\u7801<\/li>\n<li>\u6076\u610f\u4ee3\u7801\u7a83\u53d6\u7528\u6237\u6570\u636e\u5e76\u53d1\u9001\u5230\u653b\u51fb\u8005\u7684\u7f51\u7ad9 , \u6216\u8005\u5192\u5145\u7528\u6237\u7684\u884c\u4e3a , \u8c03\u7528\u76ee\u6807\u7f51\u7ad9\u63a5\u53e3\u6267\u884c\u653b\u51fb\u8005\u6307\u5b9a\u7684\u64cd\u4f5c\u3002<\/li>\n<\/ul>\n<h4 class=\"heading\" data-id=\"heading-6\">\u5982\u4f55\u9632\u8303 DOM\u578bXSS\u653b\u51fb<\/h4>\n<p>\u9632\u8303 DOM \u578b XSS\u653b\u51fb\u7684\u6838\u5fc3\u5c31\u662f\u5bf9\u8f93\u5165\u5185\u5bb9\u8fdb\u884c\u8f6c\u4e49 (DOM \u4e2d\u7684\u5185\u8054\u4e8b\u4ef6\u76d1\u542c\u5668\u548c\u94fe\u63a5\u8df3\u8f6c\u90fd\u80fd\u628a\u5b57\u7b26\u4e32\u4f5c\u4e3a\u4ee3\u7801\u8fd0\u884c, \u9700\u8981\u5bf9\u5176\u5185\u5bb9\u8fdb\u884c\u68c0\u67e5)<\/p>\n<ol>\n<li>\u5bf9\u4e8e url \u94fe\u63a5(\u4f8b\u5982\u56fe\u7247\u7684src\u5c5e\u6027), \u90a3\u4e48\u76f4\u63a5\u4f7f\u7528 encodeURIComponent\u6765\u8f6c\u4e49<\/li>\n<li>\u975e url , \u6211\u4eec\u53ef\u4ee5\u8fd9\u6837\u8fdb\u884c\u7f16\u7801\n<pre><code class=\"copyable\"> function encodeHtml(str) {\r\n     return str.replace(\/\"\/g, '&amp;quot;')\r\n             .replace(\/'\/g, '&amp;apos;')\r\n             .replace(\/&lt;\/g, '&amp;lt;')\r\n             .replace(\/&gt;\/g, '&amp;gt;');\r\n }\r\n\r\n<\/code><\/pre>\n<\/li>\n<\/ol>\n<p>DOM\u578b XSS\u653b\u51fb\u4e2d , \u53d6\u51fa\u548c\u6267\u884c\u6076\u610f\u4ee3\u7801\u7531\u6d4f\u89c8\u5668\u7aef\u5b8c\u6210 , \u5c5e\u4e8e\u524d\u7aef javaScript \u81ea\u8eab\u7684\u5b89\u5168\u6f0f\u6d1e<\/p>\n<p><strong>\u518d\u4e3e\u4e2a\u4f8b\u5b50<\/strong><\/p>\n<pre><code class=\"copyable\">\/\/\u524d\u7aef\r\n&lt;form onsubmit=\"return false\"&gt;\r\n    &lt;div class=\"form-group\"&gt;\r\n        &lt;label for=\"comments\"&gt;\u5546\u54c1\u8bc4\u8bba&lt;\/label&gt;\r\n        &lt;input class=\"form-control\" type=\"text\" id=\"comments\" \/&gt;\r\n    &lt;\/div&gt;\r\n    &lt;div class=\"form-group\"&gt;\r\n        &lt;input class=\"btn btn-danger\" type=\"button\" id=\"attck\" value=\"\u4f1a\u88ab\u653b\u51fb\" \/&gt;\r\n        &lt;input class=\"btn btn-primary\" type=\"button\" id=\"security\" value=\"\u6211\u5f88\u5b89\u5168\" \/&gt;\r\n    &lt;\/div&gt;\r\n&lt;\/form&gt;\r\n&lt;form&gt;\r\n    &lt;ul class=\"list-group\"&gt;&lt;\/ul&gt;\r\n&lt;\/form&gt;\r\n&lt;script src=\"\/node_modules\/jquery\/dist\/jquery.js\"&gt;&lt;\/script&gt;\r\n&lt;script&gt;\r\n    \/\/ DOM\u578b XSS \u653b\u51fb\r\n    $('#attck').click(function () {\r\n        let commend = $('#comments').val();\r\n        console.log(commend);\r\n        if ($.trim(commend)) {\r\n            $('.list-group').append(`&lt;li class=\"list-group-item\"&gt;${commend}&lt;\/li&gt;`);\r\n            $('#comments').val('');\r\n        }\r\n    })\r\n    \/\/ HTML \u7f16\u7801\r\n    function encodeHtml(str) {\r\n        return str.replace(\/\"\/g, '&amp;quot;')\r\n            .replace(\/'\/g, '&amp;apos;')\r\n            .replace(\/&lt;\/g, '&amp;lt;')\r\n        replace(\/&gt;\/g, '&amp;gt;')\r\n    }\r\n\r\n    $('#security').click(function () {\r\n        let commend = $('#comments').val();\r\n        console.log(commend)\r\n        \/\/ \u5bf9\u5185\u5bb9\u8fdb\u884c\u8f6c\u4e49\r\n        \/\/ \u5982\u679c\u662furl \u5730\u5740 , \u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528 encodeURIComponent \u8fdb\u884c\u8f6c\u4e49\r\n        if ($.trim(commend)) {\r\n            $('.list-group').append(`&lt;li class=\"list-group-item\"&gt;${encodeHtml(commend)}&lt;\/li&gt;`);\r\n            $('#comments').val('');\r\n        }\r\n    })\r\n&lt;\/script&gt;\r\n\r\n<\/code><\/pre>\n<p><strong>\u603b\u7ed3:\u5c31\u662f\u4e0d\u8981\u76f8\u4fe1\u7528\u6237\u8f93\u5165\u7684\u5185\u5bb9,\u5982\u679c\u975e\u8981\u5728\u9875\u9762\u4e0a\u63d2\u5165 HTML,\u5c31\u5fc5\u987b\u5148\u8f6c\u4e49\u518d\u63d2\u5165\u3002\u5bf9\u4e8eURL\u53ef\u4ee5\u4f7f\u7528encodeURIComponent,\u5bf9\u4e8e\u975eURL\u53ef\u4ee5\u4f7f\u7528\u4e0a\u9762\u7684\u65b9\u6cd5<\/strong><\/p>\n<h3 class=\"heading\" data-id=\"heading-7\">1.3 \u5b58\u50a8\u578b XSS<\/h3>\n<p>\u6076\u610f\u811a\u672c\u6c38\u4e45\u5b58\u50a8\u5728\u76ee\u6807\u670d\u52a1\u5668\u4e0a\u3002\u5f53\u6d4f\u89c8\u5668\u8bf7\u6c42\u6570\u636e\u65f6, \u811a\u672c\u4ece\u670d\u52a1\u5668\u4f20\u56de\u5e76\u6267\u884c,\u5f71\u54cd\u8303\u56f4\u6bd4\u53cd\u5c04\u578b\u548c DOM\u578b XSS\u66f4\u5927\u3002 \u5b58\u50a8\u578bXSS\u653b\u51fb\u7684\u539f\u56e0\u4ecd\u7136\u662f\u6ca1\u6709\u505a\u597d\u6570\u636e\u8fc7\u6ee4;<\/p>\n<ul>\n<li>\u524d\u7aef\u63d0\u4ea4\u6570\u636e\u5230\u670d\u52a1\u7aef\u65f6 , \u6ca1\u6709\u505a\u597d\u8fc7\u6ee4;<\/li>\n<li>\u670d\u52a1\u7aef\u5728\u63a5\u53d7\u5230\u6570\u636e\u65f6 , \u5728\u5b58\u50a8\u4e4b\u524d , \u6ca1\u6709\u505a\u597d\u8fc7\u6ee4<\/li>\n<li>\u524d\u7aef\u4ece\u670d\u52a1\u7aef\u8bf7\u6c42\u5230\u6570\u636e , \u6ca1\u6709\u8fc7\u6ee4\u8f93\u51fa\u3002<\/li>\n<\/ul>\n<p><strong>\u5b58\u50a8\u578bXSS\u7684\u653b\u51fb\u6b65\u9aa4<\/strong><\/p>\n<ul>\n<li>1.\u653b\u51fb\u8005\u5c06\u6076\u610f\u4ee3\u7801\u63d0\u4ea4\u5230\u76ee\u6807\u7f51\u7ad9\u7684\u6570\u636e\u5e93\u4e2d<\/li>\n<li>2.\u7528\u6237\u6253\u5f00\u76ee\u6807\u7f51\u7ad9\u65f6 , \u7f51\u7ad9\u670d\u52a1\u7aef\u5c06\u6076\u610f\u4ee3\u7801\u4ece\u6570\u636e\u5e93\u53d6\u51fa, \u62fc\u63a5\u5728 HTML\u4e2d\u8fd4\u56de\u7ed9\u6d4f\u89c8\u5668<\/li>\n<li>3.\u7528\u6237\u6d4f\u89c8\u5668\u63a5\u6536\u5230\u54cd\u5e94\u540e\u89e3\u6790\u6267\u884c, \u6df7\u5728\u5176\u4e2d\u7684\u6076\u610f\u4ee3\u7801\u4e5f\u88ab\u6267\u884c\u3002<\/li>\n<li>4.\u6076\u610f\u4ee3\u7801\u7a83\u53d6\u7528\u6237\u6570\u636e\u5e76\u53d1\u9001\u5230\u653b\u51fb\u8005\u7684\u7f51\u7ad9, \u6216\u8005\u5192\u5145\u7528\u6237\u7684\u884c\u4e3a, \u8c03\u7528\u76ee\u6807\u7f51\u7ad9\u63a5\u53e3\u6267\u884c\u653b\u51fb\u8005\u6307\u5b9a\u7684\u64cd\u4f5c<\/li>\n<\/ul>\n<p>\u8fd9\u79cd\u653b\u51fb\u5e38\u89c1\u4e8e\u5e26\u6709\u7528\u6237\u4fdd\u5b58\u6570\u636e\u7684\u7f51\u7ad9\u529f\u80fd, \u5982\u8bba\u575b\u53d1\u5e16, \u5546\u54c1\u8bc4\u8bba, \u7528\u4e8e\u79c1\u4fe1\u7b49\u3002<\/p>\n<p><strong>\u5982\u4f55\u9632\u8303\u5b58\u50a8\u578b XSS\u653b\u51fb<\/strong><\/p>\n<ul>\n<li>1.\u524d\u7aef\u6570\u636e\u4f20\u9012\u7ed9\u670d\u52a1\u5668\u4e4b\u524d, \u5148\u8f6c\u4e49\/\u8fc7\u6ee4(\u9632\u8303\u4e0d\u4e86\u6293\u5305\u4fee\u6539\u6570\u636e\u7684\u60c5\u51b5)<\/li>\n<li>2.\u670d\u52a1\u7aef\u63a5\u6536\u5230\u6570\u636e, \u5728\u5b58\u50a8\u5230\u6570\u636e\u5e93\u4e4b\u524d, \u8fdb\u884c\u8f6c\u4e49\/\u8fc7\u6ee4<\/li>\n<li>3.\u524d\u7aef\u63a5\u6536\u5230\u670d\u52a1\u5668\u4f20\u9012\u8fc7\u6765\u7684\u6570\u636e, \u5728\u5c55\u793a\u5230\u9875\u9762\u524d, \u5148\u8fdb\u884c\u8f6c\u4e49\/\u8fc7\u6ee4<\/li>\n<\/ul>\n<p><strong>\u6765\u4e00\u4e2a\u4f8b\u5b50, \u53ef\u80fd\u957f\u4e00\u70b9 , \u767b\u5f55\u7528\u4e86\u4e00\u4e0b cookie<\/strong><\/p>\n<pre><code class=\"copyable\">\/\/ \u524d\u7aef\r\n\/\/ index.html\r\n&lt;div class=\"panel-heading\"&gt;\r\n    &lt;h3&gt;\u8bba\u575b&lt;\/h3&gt;\r\n&lt;\/div&gt;\r\n&lt;ul class=\"list-group\"&gt;&lt;\/ul&gt;\r\n    &lt;form&gt;\r\n        &lt;div class=\"form-group\"&gt;\r\n            &lt;label for=\"comments\"&gt;\u6253\u4e2a\u62db\u547c\u5427&lt;\/label&gt;\r\n            &lt;input class=\"form-control\" type=\"text\" id=\"comments\" \/&gt;\r\n        &lt;\/div&gt;\r\n        &lt;div class=\"form-group\"&gt;\r\n            &lt;input class=\"btn btn-primary\" type=\"button\" id=\"publish\" value=\"\u53d1\u5e16\" \/&gt;\r\n        &lt;\/div&gt;\r\n    &lt;\/form&gt;\r\n&lt;script src=\"\/node_modules\/jquery\/dist\/jquery.js\"&gt;&lt;\/script&gt;\r\n&lt;script&gt;\r\n\/\/ \u5b58\u50a8\u578b XSS \u653b\u51fb\r\n$(document).ready(function () {\r\n\r\n    \/\/\u83b7\u53d6\u5e16\u5b50\u5217\u8868\r\n    function getList() {\r\n        $.get('\/getComments2').then(res =&gt; {\r\n            if (res.code === 0) {\r\n                let lists = '';\r\n                $.each(res.comments, (index, comment) =&gt; {\r\n                    \/\/ \u524d\u7aef\u63a5\u6536\u5230\u670d\u52a1\u5668\u4f20\u9012\u8fc7\u6765\u7684\u6570\u636e, \u5728\u5c55\u793a\u5230\u9875\u9762\u4e4b\u524d, \u8fdb\u884c\u8f6c\u4e49\r\n                    content = encodeHtml(comment.content);\r\n                    console.log(comment.content , content)\r\n                    lists += `&lt;li class=\"list-group-item\"&gt;&lt;span&gt;${comment.username}:&lt;\/span&gt; ${content}&lt;\/li&gt;`;\r\n                });\r\n                $('.list-group').html(lists);\r\n            }\r\n        });\r\n    };\r\n    getList();\r\n    \/\/Html \u7f16\u7801\r\n    function encodeHtml(str) {\r\n        return str.replace(\/\"\/g, '&amp;quot;')\r\n            .replace(\/'\/g, '&amp;apos;')\r\n            .replace(\/&lt;\/g, '&amp;lt;')\r\n            .replace(\/&gt;\/g, '&amp;gt;');\r\n    }\r\n    \/\/Html \u89e3\u7801\r\n    function decodeHtml(str) {\r\n        return str.replace(\/&amp;quot;\/g, '\\\"')\r\n            .replace(\/&amp;apos;\/g, '\\'')\r\n            .replace(\/&amp;lt;\/g, '&lt;')\r\n            .replace(\/&amp;gt;\/g, '&gt;');\r\n    }\r\n    $('#publish').click(function () {\r\n        let comment = $('#comments').val();\r\n        \/\/ \u524d\u7aef\u6570\u636e\u4f20\u9012\u7ed9\u670d\u52a1\u5668\u4e4b\u524d , \u5148\u8f6c\u4e49\/\u8fc7\u6ee4(\u9632\u8303\u4e0d\u4e86\u6293\u5305\u4fee\u6539\u6570\u636e\u7684\u60c5\u51b5)\r\n        $.post('\/addComment2', { comment: encodeHtml(comment) }).then(res =&gt; {\r\n            if (res.code === 1) {\r\n                \/\/\u8df3\u53bb\u767b\u5f55\u9875\r\n                location.href = '\/login.html';\r\n            } else {\r\n                \/\/\u83b7\u53d6\u65b0\u7684\u5e16\u5b50\u5217\u8868\r\n                getList();\r\n                $('#comments').val('');\r\n            }\r\n        });\r\n    });\r\n});\r\n&lt;\/script&gt;\r\n\r\n\/\/\u524d\u7aef login.html\r\n&lt;div class=\"panel-heading\"&gt;\r\n    &lt;h3&gt;\u767b\u5f55&lt;\/h3&gt;\r\n&lt;\/div&gt;\r\n&lt;form onsubmit=\"return false\"&gt;\r\n    &lt;div class=\"form-group\"&gt;\r\n        &lt;label for=\"username\"&gt;\u7528\u6237\u540d&lt;\/label&gt;\r\n        &lt;input class=\"form-control\" type=\"text\" id=\"username\" \/&gt;\r\n    &lt;\/div&gt;\r\n    &lt;div class=\"form-group\"&gt;\r\n        &lt;label for=\"password\"&gt;\u5bc6\u7801&lt;\/label&gt;\r\n        &lt;input class=\"form-control\" type=\"text\" id=\"password\" \/&gt;\r\n    &lt;\/div&gt;\r\n    &lt;div class=\"form-group\"&gt;\r\n        &lt;input class=\"btn btn-primary\" type=\"submit\" id=\"login\" value=\"\u767b\u5f55\" \/&gt;\r\n    &lt;\/div&gt;\r\n&lt;\/form&gt;\r\n&lt;script src=\"\/node_modules\/jquery\/dist\/jquery.js\"&gt;&lt;\/script&gt;\r\n&lt;script&gt;\r\n    $(document).ready(function () {\r\n        $('#login').click(function () {\r\n            let username = $('#username').val();\r\n            let password = $('#password').val();\r\n\r\n            $.post('\/api\/login', {\r\n                username,\r\n                password\r\n            }).then(res =&gt; {\r\n                if (res.code === 0) {\r\n                    \/\/\u767b\u5f55\u6210\u529f\u9875\r\n                    location.href = `\/welcome?type=&lt;script&gt;alert('\u6076\u610f\u5185\u5bb9')&lt;\\\/script&gt;`;\r\n                } else {\r\n                    \/\/\u767b\u5f55\u5931\u8d25(\u5982\u679c\u662f\u7528\u6237\u767b\u5f55\u6210\u529f\u65f6\uff0c\u8fd8\u80fd\u591f\u83b7\u53d6\u5230\u7528\u6237\u7684cookie)\r\n                    location.href = `\/error?type=&lt;script&gt;alert('\u6076\u610f\u5185\u5bb9')&lt;\\\/script&gt;`;\r\n                }\r\n            })\r\n        })\r\n    })\r\n&lt;\/script&gt;\r\n\r\n\/\/ \u540e\u7aef server.js\r\nconst express = require('express');\r\nconst app = express();\r\nconst path = require('path');\r\nconst bodyParser = require('body-parser');\r\nconst cookieParser = require('cookie-parser');\r\n\r\n\r\n\/\/\u8bbe\u7f6e\u8def\u5f84\r\napp.use(express.static(path.join(__dirname, 'src')));\r\napp.use(express.static(path.join(__dirname, '..\/')));\r\n\/\/\u5c06\u53c2\u6570\u8f6c\u6362\u6210\u5bf9\u8c61\r\napp.use(bodyParser.urlencoded({ extended: true }));\r\n\/\/req.cookie[xxx] \u83b7\u53d6cookie\r\napp.use(cookieParser());\r\n\r\n\/\/\u7528\u6237\u5217\u8868\r\nlet userList = [{ username: 'zs', password: '123456' }, { username: 'star', password: 'star' }];\r\n\r\nlet SESSION_ID = 'connect.sid';\r\nlet session = {};\r\n\/\/\u767b\u5f55\u63a5\u53e3\r\napp.post('\/api\/login', (req, res) =&gt; {\r\n    let { username, password } = req.body;\r\n    let user = userList.find(item =&gt; item.username === username &amp;&amp; item.password === password);\r\n    if (user) {\r\n        \/\/\u7528\u6237\u767b\u5f55\u540e\uff0c\u7ed9\u4e00\u4e2a\u6807\u8bc6(cookie\u767b\u5f55)\r\n        const cardId = Math.random() + Date.now();\r\n        session[cardId] = { user };\r\n        res.cookie(SESSION_ID, cardId);\r\n        res.json({ code: 0 });\r\n    } else {\r\n        res.json({ code: 1, error: `${username} does not exist or password mismatch` });\r\n    }\r\n\r\n});\r\n\r\n\/\/1.\u53cd\u5c04\u578bXSS\u653b\u51fb: http:\/\/localhost:3000\/error?type=&lt;script&gt;alert('\u6076\u610f\u5185\u5bb9')&lt;\/script&gt;\r\napp.get('\/error', function (req, res) {\r\n    res.send(`${req.query.type}`); \/\/\u62ff\u5230 url \u4e0a\u7684 type \u53c2\u6570\uff0c\u5e76\u8fd4\u56de\u7ed9\u524d\u7aef    \r\n});\r\n\r\napp.get('\/welcome', function (req, res) {\r\n    \/\/\u5bf9\u67e5\u8be2\u53c2\u6570\u8fdb\u884c\u7f16\u7801\uff0c\u907f\u514dXSS\u653b\u51fb\r\n    res.send(`${encodeURIComponent(req.query.type)}`);\r\n    \/\/\u5bf9type\u67e5\u8be2\u53c2\u6570\u8fdb\u884c\u7f16\u7801\uff0c\u5373\u53ef\u89e3\u51b3\u5f53\u524d\u7684XSS\u653b\u51fb(\u53ef\u91cd\u542f\u670d\u52a1\u67e5\u770b)\r\n    \/\/ res.send(`${encodeURIComponent(req.query.type)}`);\r\n});\r\n\r\n\/\/\u5b89\u5168\u7684\u8bc4\u8bba\u5217\u8868\r\nlet comments2 = [\r\n    { username: 'zs', content: '\u6211\u662fzs' },\r\n    { username: 'hw', content: '\u6211\u662fhw' },\r\n    { username: 'star', content: '\u5927\u5bb6\u597d\uff0c\u6211\u662fStar' },\r\n]\r\napp.get('\/getComments2', function (req, res) {\r\n    res.json({ code: 0, comments: comments2 });\r\n});\r\nfunction encodeHtml(str) {\r\n    return str.replace(\/\"\/g, '&amp;quot;')\r\n            .replace(\/'\/g, '&amp;apos;')\r\n            .replace(\/&lt;\/g, '&amp;lt;')\r\n            .replace(\/&gt;\/g, '&amp;gt;');\r\n}\r\napp.post('\/addComment2', function (req, res) {\r\n    \/\/cardId (req.cookies[SESSION_ID])\u8981\u6d3e\u4e0a\u7528\u573a\u5566~\r\n    let info = session[req.cookies[SESSION_ID]];\r\n    if (info) {\r\n        \/\/\u7528\u6237\u5df2\u7ecf\u767b\u5f55\r\n        let username = info.user.username;\r\n        \/\/  \u670d\u52a1\u5668\u63a5\u6536\u5230\u6570\u636e\u540e , \u5728\u5b58\u50a8\u5230\u6570\u636e\u5e93\u4e4b\u524d , \u8fdb\u884c\u8f6c\u4e49\/\u8fc7\u6ee4\r\n        comments2.push({ username, content: encodeHtml(req.body.comment) });\r\n        res.json({ code: 0, comments: comments2 });\r\n    } else {\r\n        res.json({ code: 1, error: 'user not logged in.' });\r\n    }\r\n});\r\n\r\napp.listen(3000);\r\n\r\n<\/code><\/pre>\n<p><strong>\u603b\u7ed3:<\/strong><\/p>\n<ul>\n<li>1.\u6076\u610f\u811a\u672c\u5982\u679c\u672a\u7ecf\u8fc7\u8f6c\u6362, \u5b58\u50a8\u5230\u4e86\u540e\u53f0\u3002\u4efb\u4f55\u7528\u6237\u8bbf\u95ee\u6b64\u9875\u9762, \u90fd\u4f1a\u6267\u884c\u6076\u610f\u811a\u672c<\/li>\n<li>2.\u8bf4\u767d\u4e86\u5c31\u662f\u589e\u52a0\u5b57\u7b26\u4e32\u7684\u8fc7\u6ee4:\n<ul>\n<li>\u524d\u7aef\u8f93\u5165\u65f6\u8fc7\u6ee4<\/li>\n<li>\u670d\u52a1\u7aef\u589e\u52a0\u65f6\u8fc7\u6ee4<\/li>\n<li>\u524d\u7aef\u8f93\u51fa\u65f6\u8fc7\u6ee4<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3 class=\"heading\" data-id=\"heading-8\">1.4 JSONP\u4e2d\u5b58\u5728\u7684 XSS \u5b89\u5168\u95ee\u9898<\/h3>\n<pre><code class=\"copyable\">    \/\/\u4e00\u4e2a jsonp\u51fd\u6570\u5927\u6982\u662f\u8fd9\u6837\r\n    function jsonp({ url, params, callback }) {\r\n        return new Promise((resolve, reject) =&gt; {\r\n            let script = document.createElement('script');\r\n            params = JSON.parse(JSON.stringify(params));\r\n            let arrs = [];\r\n            for (let key in params) {\r\n                arrs.push(`${key}=${params[key]}`);\r\n            }\r\n            arrs.push(`callback=${callback}`);\r\n            script.src = `${url}?${arrs.join('&amp;')}`;\r\n            document.body.appendChild(script);\r\n            console.log(callback)\r\n            window[callback] = function (data) {\r\n                resolve(data);\r\n                document.body.removeChild(script);\r\n            }\r\n        })\r\n    }\r\n\/\/\u5982\u679c\u6211\u8fd9\u6837\u8c03\u7528 ,\u5c31\u4f1a XSS\u5b89\u5168\u95ee\u9898\r\njsonp({\r\n    url: 'http:\/\/localhost:3000\/say',\r\n    params: {\r\n        wd: 'I Love you'\r\n    },\r\n    callback: 'alert(1)'\r\n}).then(data =&gt; {\r\n    alert(data.username)\r\n    console.log(data)\r\n})\r\n\r\n<\/code><\/pre>\n<p><strong>\u7b80\u5355\u6765\u8bf4\u5c31\u662f\u628a jsonp\u4e2d\u56de\u8c03\u51fd\u6570\u7684\u53c2\u6570\u8bbe\u7f6e\u4e3a\u6076\u610f\u4ee3\u7801<\/strong><\/p>\n<h4 class=\"heading\" data-id=\"heading-9\">\u5e38\u89c1\u7684\u9884\u9632\u64cd\u4f5c<\/h4>\n<ul>\n<li>\u5c06\u91cd\u8981\u7684cookie\u6807\u8bb0\u4e3ahttp only,\u8fd9\u6837\u7684\u8bddJavascript \u4e2d\u7684document.cookie\u8bed\u53e5\u5c31\u4e0d\u80fd\u83b7\u53d6\u5230cookie\u4e86\u3002<\/li>\n<li>\u53ea\u5141\u8bb8\u7528\u6237\u8f93\u5165\u6211\u4eec\u671f\u671b\u7684\u56de\u8c03\u53c2\u6570\n<pre><code class=\"copyable\">  let { callback} = req.query;\r\n  if(callback === 'show') {\r\n    callback = 'show';\r\n  } else {\r\n    res.end('error')\r\n  }\r\n\r\n<\/code><\/pre>\n<\/li>\n<li>\u8fc7\u6ee4\u6216\u79fb\u9664\u7279\u6b8a\u7684Html\u6807\u7b7e\n<pre><code class=\"copyable\">  &lt;script&gt;,&lt;iframe&gt;\u7b49\r\n\r\n<\/code><\/pre>\n<\/li>\n<\/ul>\n<h2 class=\"heading\" data-id=\"heading-10\">2. CSRF\u65b9\u5f0f<\/h2>\n<p>CSRF(Cross-site-request-forgery) \u8de8\u7ad9\u8bf7\u6c42\u4f2a\u9020: \u653b\u51fb\u8005\u8bf1\u5bfc\u53d7\u5bb3\u8005\u8fdb\u5165\u7b2c\u4e09\u65b9\u7f51\u7ad9, \u5728\u7b2c\u4e09\u65b9\u7f51\u7ad9\u4e2d , \u5411\u88ab\u653b\u51fb\u7f51\u7ad9\u53d1\u8d77\u8de8\u57df\u8bf7\u6c42\u3002\u5229\u7528\u53d7\u5bb3\u8005\u5728\u88ab\u653b\u51fb\u7f51\u7ad9\u5df2\u7ecf\u83b7\u53d6\u7684\u6ce8\u518c\u51ed\u8bc1 , \u7ed5\u8fc7\u540e\u53f0\u7684\u7528\u6237\u9a8c\u8bc1, \u8fbe\u5230\u5192\u5145\u7528\u6237\u5bf9\u88ab\u653b\u51fb\u7684\u7f51\u7ad9\u6267\u884c\u67d0\u9879\u64cd\u4f5c\u7684\u76ee\u7684\u3002<\/p>\n<h3 class=\"heading\" data-id=\"heading-11\">\u5178\u578b\u7684CSRF\u653b\u51fb\u6d41\u7a0b<\/h3>\n<ul>\n<li>1.\u53d7\u5bb3\u8005\u767b\u5f55 A \u7ad9\u70b9 , \u5e76\u4fdd\u7559\u4e86\u767b\u5f55\u51ed\u8bc1(Cookie)<\/li>\n<li>2.\u653b\u51fb\u8005\u8bf1\u5bfc\u53d7\u5bb3\u8005\u8bbf\u95ee\u4e86\u7ad9\u70b9B<\/li>\n<li>3.\u7ad9\u70b9B\u5411\u7ad9\u70b9A\u53d1\u9001\u4e86\u4e00\u4e2a\u8bf7\u6c42, \u6d4f\u89c8\u5668\u4f1a\u9ed8\u8ba4\u643a\u5e26\u7ad9\u70b9A\u7684Cookie\u4fe1\u606f\u3002<\/li>\n<li>4.\u7ad9\u70b9A\u63a5\u6536\u5230\u8bf7\u6c42\u540e,\u5bf9\u8bf7\u6c42\u8fdb\u884c\u9a8c\u8bc1,\u5e76\u786e\u8ba4\u662f\u53d7\u5bb3\u8005\u7684\u51ed\u8bc1,\u8bef\u4ee5\u4e3a\u662f\u65e0\u8f9c\u7684\u53d7\u5bb3\u8005\u53d1\u9001\u7684\u8bf7\u6c42\u3002<\/li>\n<li>5.\u7ad9\u70b9A\u4ee5\u53d7\u5bb3\u8005\u7684\u540d\u4e49\u6267\u884c\u4e86\u7ad9\u70b9B\u7684\u8bf7\u6c42<\/li>\n<li>\u653b\u51fb\u5b8c\u6210,\u653b\u51fb\u8005\u5728\u53d7\u5bb3\u8005\u4e0d\u77e5\u60c5\u7684\u60c5\u51b5\u4e0b,\u5192\u5145\u53d7\u5bb3\u8005\u5b8c\u6210\u4e86\u653b\u51fb<\/li>\n<\/ul>\n<figure><a href=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2020\/03\/QQ\u255c\u256a\u2550\u255d20200325205549.png\" rel=\"fancybox\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-2494\" src=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2020\/03\/QQ\u255c\u256a\u2550\u255d20200325205549.png\" alt=\"QQ\u255c\u256a\u2550\u255d20200325205549\" width=\"1253\" height=\"632\" \/><\/a><\/figure>\n<figure>SRF\u7684\u7279\u70b9<\/figure>\n<ul>\n<li>1.\u653b\u51fb\u901a\u5e38\u5728\u7b2c\u4e09\u65b9\u7f51\u7ad9\u53d1\u8d77,\u5982\u56fe\u4e0a\u7684\u7ad9\u70b9B,\u7ad9\u70b9A\u65e0\u6cd5\u9632\u6b62\u653b\u51fb\u53d1\u751f\u3002<\/li>\n<li>2.\u653b\u51fb\u5229\u7528\u53d7\u5bb3\u8005\u5728\u88ab\u653b\u51fb\u7f51\u7ad9\u7684\u767b\u5f55\u51ed\u8bc1,\u5192\u5145\u53d7\u5bb3\u8005\u63d0\u4ea4\u64cd\u4f5c;\u5e76\u4e0d\u4f1a\u53bb\u83b7\u53d6cookie\u4fe1\u606f(<strong>cookie\u6709\u540c\u6e90\u7b56\u7565<\/strong>)<\/li>\n<li>3.\u8de8\u7ad9\u8bf7\u6c42\u53ef\u4ee5\u5229\u7528\u5404\u79cd\u65b9\u5f0f:\u56fe\u7247URL,\u8d85\u94fe\u63a5,CORS, Form\u63d0\u4ea4\u7b49\u7b49(\u6765\u6e90\u4e0d\u660e\u7684\u8fde\u63a5,\u4e0d\u8981\u70b9\u51fb)<\/li>\n<\/ul>\n<h3 class=\"heading\" data-id=\"heading-13\">CSRF\u653b\u51fb\u9632\u5fa1<\/h3>\n<h4 class=\"heading\" data-id=\"heading-14\">1.\u6dfb\u52a0\u9a8c\u8bc1\u7801(\u4f53\u9a8c\u4e0d\u597d)<\/h4>\n<p>\u9a8c\u8bc1\u7801\u80fd\u591f\u9632\u5fa1CSRF\u653b\u51fb, \u4f46\u662f\u6211\u4eec\u4e0d\u53ef\u80fd\u6bcf\u4e00\u6b21\u4ea4\u4e92\u90fd\u9700\u8981\u9a8c\u8bc1\u7801,\u5426\u5219\u7528\u6237\u7684\u4f53\u9a8c\u4f1a\u975e\u5e38\u5dee,\u4f46\u662f\u6211\u4eec\u53ef\u4ee5\u5728\u8f6c\u8d26,\u4ea4\u6613\u7b49\u64cd\u4f5c\u65f6, \u589e\u52a0\u9a8c\u8bc1\u7801, \u786e\u4fdd\u6211\u4eec\u7684\u8d26\u6237\u5b89\u5168\u3002<\/p>\n<h4 class=\"heading\" data-id=\"heading-15\">2.\u5224\u65ad\u8bf7\u6c42\u7684\u6765\u6e90:\u68c0\u6d4bReferer(\u5e76\u4e0d\u5b89\u5168,Referer\u53ef\u4ee5\u88ab\u66f4\u6539)<\/h4>\n<p>Referer \u53ef\u4ee5\u4f5c\u4e3a\u4e00\u79cd\u8f85\u52a9\u624b\u6bb5,\u6765\u5224\u65ad\u8bf7\u6c42\u7684\u6765\u6e90\u662f\u5426\u662f\u5b89\u5168\u7684, \u4f46\u662f\u9274\u4e8e Referer \u672c\u8eab\u662f\u53ef\u4ee5\u4fee\u6539\u7684 , \u56e0\u6b64\u4e0d\u80fd\u664b\u4ec5\u4f9d\u8d56\u4e8e Referer<\/p>\n<h4 class=\"heading\" data-id=\"heading-16\">3.\u4f7f\u7528Token(\u4e3b\u6d41)<\/h4>\n<p>CSRF\u653b\u51fb\u4e4b\u6240\u4ee5\u80fd\u591f\u6210\u529f, \u662f\u56e0\u4e3a\u670d\u52a1\u5668\u8bef\u628a\u653b\u51fb\u8005\u53d1\u9001\u7684\u8bf7\u6c42\u5f53\u6210\u4e86\u7528\u6237\u81ea\u5df1\u7684\u8bf7\u6c42\u3002\u90a3\u4e48\u6211\u4eec\u53ef\u4ee5\u8981\u6c42\u6240\u6709\u7684\u7528\u6237\u8bf7\u6c42\u90fd\u643a\u5e26\u4e00\u4e2aCSRF\u653b\u51fb\u8005\u65e0\u6cd5\u83b7\u53d6\u5230\u7684 Token\u3002\u670d\u52a1\u5668\u901a\u8fc7\u6821\u9a8c\u8bf7\u6c42\u662f\u5426\u643a\u5e26\u6b63\u786e\u7684Token , \u6765\u628a\u6b63\u5e38\u7684\u8bf7\u6c42\u548c\u653b\u51fb\u8bf7\u6c42\u533a\u5206\u5f00\u3002\u8ddf\u9a8c\u8bc1\u7801\u7c7b\u4f3c,\u53ea\u662f\u7528\u6237\u65e0\u611f\u77e5<\/p>\n<p><strong>\u6b65\u9aa4:<\/strong><\/p>\n<ul>\n<li>\u670d\u52a1\u7aef\u7ed9\u7528\u6237\u751f\u6210\u4e00\u4e2atoken, \u52a0\u5bc6\u540e\u4f20\u9012\u7ed9\u7528\u6237\u3002<\/li>\n<li>\u7528\u6237\u5728\u63d0\u4ea4\u8bf7\u6c42\u65f6, \u9700\u8981\u643a\u5e26\u8fd9\u4e2atoken<\/li>\n<li>\u670d\u52a1\u7aef\u9a8c\u8bc1token\u662f\u5426\u6b63\u786e<\/li>\n<\/ul>\n<p><strong>\u8fd9\u4e2a\u6bd4\u8f83\u5e38\u7528,\u6211\u5c31\u6765\u4e3e\u4e2a\u4f8b\u5b50\u5427<\/strong><\/p>\n<pre><code class=\"copyable\">\/\/login.html \u767b\u5f55\u9875\r\n&lt;div class=\"panel-heading\"&gt;\r\n    &lt;h3&gt;\u767b\u5f55&lt;\/h3&gt;\r\n&lt;\/div&gt;\r\n&lt;div class=\"panel-body\"&gt;\r\n    &lt;form onsubmit=\"return false\"&gt;\r\n        &lt;div class=\"form-group\"&gt;\r\n            &lt;label for=\"username\"&gt;\u7528\u6237\u540d&lt;\/label&gt;\r\n            &lt;input class=\"form-control\" type=\"text\" id=\"username\" \/&gt;\r\n        &lt;\/div&gt;\r\n        &lt;div class=\"form-group\"&gt;\r\n            &lt;label for=\"password\"&gt;\u5bc6\u7801&lt;\/label&gt;\r\n            &lt;input class=\"form-control\" type=\"text\" id=\"password\" \/&gt;\r\n        &lt;\/div&gt;\r\n        &lt;div class=\"form-group\"&gt;\r\n            &lt;input class=\"btn btn-primary\" type=\"submit\" id=\"login\" value=\"\u767b\u5f55\" \/&gt;\r\n        &lt;\/div&gt;\r\n    &lt;\/form&gt;\r\n&lt;\/div&gt;\r\n&lt;script src=\"\/node_modules\/jquery\/dist\/jquery.js\"&gt;&lt;\/script&gt;\r\n&lt;script&gt;\r\n$('#login').click(function () {\r\n    let username = $('#username').val();\r\n    let password = $('#password').val();\r\n    console.log(username,password)\r\n    $.post('\/api\/login', {\r\n        username,\r\n        password\r\n    }).then(res =&gt; {\r\n        if(res.code === 0) {\r\n            \/\/ \u767b\u5f55\u6210\u529f\u9875\r\n            location.href = '\/safe3.html'\r\n        } else {\r\n\r\n        }\r\n    })\r\n})\r\n&lt;\/script&gt;\r\n\r\n\/\/safe.html \u663e\u793a\u9875\u9762\r\n&lt;div class=\"panel-heading\"&gt;\r\n    &lt;h3&gt;\u8f6c\u8d26&lt;\/h3&gt;\r\n    &lt;h5&gt;\r\n        &lt;p&gt;\u7528\u6237\uff1a&lt;span id='username'&gt;&lt;\/span&gt;&lt;\/p&gt;\r\n        &lt;p&gt;\u4f59\u989d\uff1a&lt;span id='account'&gt;&lt;\/span&gt;&lt;\/p&gt;\r\n    &lt;\/h5&gt;\r\n&lt;\/div&gt;\r\n&lt;div class=\"panel-body\"&gt;\r\n    &lt;form onsubmit=\"return false\"&gt;\r\n        &lt;div class=\"form-group\"&gt;\r\n            &lt;label for=\"payee\"&gt;\u6536\u6b3e\u4eba&lt;\/label&gt;\r\n            &lt;input class=\"form-control\" type=\"text\" id=\"payee\" \/&gt;\r\n        &lt;\/div&gt;\r\n        &lt;div class=\"form-group\"&gt;\r\n            &lt;label for=\"amount\"&gt;\u91d1\u989d&lt;\/label&gt;\r\n            &lt;input class=\"form-control\" type=\"text\" id=\"amount\" \/&gt;\r\n        &lt;\/div&gt;\r\n        &lt;div class=\"form-group\"&gt;\r\n            &lt;input class=\"btn btn-primary\" type=\"submit\" id=\"transfer\" value=\"\u8f6c\u8d26\" \/&gt;\r\n        &lt;\/div&gt;\r\n    &lt;\/form&gt;\r\n&lt;\/div&gt;\r\n&lt;button&gt;\r\n    &lt;a href=\"\/fish3.html\"&gt;\u9493\u9c7c\u8fde\u63a5&lt;\/a&gt;\r\n&lt;\/button&gt;\r\n&lt;\/body&gt;\r\n&lt;script src=\"\/node_modules\/jquery\/dist\/jquery.js\"&gt;&lt;\/script&gt;\r\n&lt;script&gt;\r\n    function getUserInfo () {\r\n        $.get('\/api\/userinfo').then(res =&gt; {\r\n            if(res.code === 1) {\r\n                location.href = '\/login.html';\r\n            } else {\r\n                let { username , account } = res.info;\r\n                $('#username').text(username);\r\n                $('#account').text(account);\r\n            }\r\n        })\r\n    }\r\n\r\n    getUserInfo();\r\n    $('#transfer').click(function() {\r\n        let payee = $('#payee').val(); \/\/ \u6536\u6b3e\u4eba\r\n        let amount = $('#amount').val(); \/\/ \u8f6c\u8d26\u91d1\u989d\r\n        \r\n        \/\/ \u751f\u6210 token\r\n        let token = document.cookie.match(\/connect.sid=([^;]*)\/) || [];\r\n        \r\n        $.post('\/api\/transfer3', {\r\n            payee,\r\n            amount,\r\n            token : 'my_token_' + token[1]\r\n        }).then(res =&gt; {\r\n            if(res.code === 0) {\r\n                \/\/ \u91cd\u65b0\u83b7\u53d6\u7528\u6237\u4fe1\u606f\r\n                getUserInfo();\r\n            } else {\r\n            }\r\n        })\r\n    })\r\n    &lt;\/script&gt;\r\n\r\n\/\/\u9493\u9c7c\u9875\u9762\r\n&lt;img width=\"600\"\r\n        src=\"http:\/\/b4-q.mafengwo.net\/s12\/M00\/FE\/AE\/wKgED1v772uAa_VkAA3UNOJhbkE35.jpeg?imageMogr2%2Fthumbnail%2F1360x%2Fstrip%2Fquality%2F90\" \/&gt;\r\n&lt;p&gt;\u4f60\u7684\u94b1\u4e0d\u5b89\u5168\u4e86~&lt;\/p&gt;\r\n&lt;a href=\"http:\/\/localhost:3001\/safe.html\"&gt;\u8fd4\u56de\u67e5\u770b\u4f59\u989d&lt;\/a&gt;\r\n&lt;iframe src=\"http:\/\/localhost:3002\/fake1.html\" style=\"display: none\"&gt;&lt;\/iframe&gt;\r\n\r\n\/\/\u6076\u610f\u7ad9\u70b9\r\n\/\/ fake1.html\r\n&lt;body&gt;\r\n&lt;form name=\"sneak1\" action=\"http:\/\/localhost:3001\/api\/transfer3\" method=\"post\"&gt;\r\n    &lt;input type=\"text\" name=\"payee\" value=\"loki\" \/&gt;\r\n    &lt;input type=\"text\" name=\"amount\" value=\"2000\" \/&gt;\r\n&lt;\/form&gt;\r\n&lt;\/body&gt;\r\n&lt;script&gt;\r\n    window.onload = function () {\r\n        document.sneak1.submit();   \/\/\u6709\u9a8c\u8bc1\u7801\u7684\u60c5\u51b5\r\n    }\r\n&lt;\/script&gt;\r\n\r\n\/\/\u540e\u7aef server1.js\r\nconst express = require('express');\r\nconst app = express();\r\nconst path = require('path');\r\nconst bodyParser = require('body-parser');\r\nconst cookieParser = require('cookie-parser');\r\n\r\n\/\/\u5c06\u53c2\u6570\u8f6c\u6362\u6210\u5bf9\u8c61\r\napp.use(bodyParser.urlencoded({ extended: true }));\r\n\/\/req.cookie[xxx] \u83b7\u53d6cookie\r\napp.use(cookieParser());\r\n\r\n\/\/\u8bbe\u7f6e\u8def\u5f84\r\napp.use(express.static(path.join(__dirname, 'src')));\r\n\r\n\r\n\/\/\u7528\u6237\u5217\u8868\r\nlet userList = [{ username: 'hw', password: '123456', account: 1000 }, { username: 'loki', password: 'loki', account: 100000 }];\r\n\r\nlet SESSION_ID = 'connect.sid';\r\nlet session = {};\r\n\/\/\u767b\u5f55\u63a5\u53e3\r\napp.post('\/api\/login', (req, res) =&gt; {\r\n    let { username, password } = req.body;\r\n    let user = userList.find(item =&gt; item.username === username &amp;&amp; item.password === password);\r\n    if (user) {\r\n        \/\/\u7528\u6237\u767b\u5f55\u540e\uff0c\u7ed9\u4e00\u4e2a\u6807\u8bc6(cookie\u767b\u5f55)\r\n        const cardId = Math.random() + Date.now();\r\n        session[cardId] = { user };\r\n        res.cookie(SESSION_ID, cardId);\r\n        res.json({ code: 0 });\r\n    } else {\r\n        res.json({ code: 1, error: `${username} does not exist or password mismatch` });\r\n    }\r\n\r\n});\r\n\r\n\/\/\u83b7\u53d6\u4fe1\u606f\r\napp.get('\/api\/userinfo', (req, res) =&gt; {\r\n    let info = session[req.cookies[SESSION_ID]];\r\n    if (info) {\r\n        \/\/\u7528\u6237\u5df2\u7ecf\u767b\u5f55\r\n        let username = info.user.username;\r\n        res.json({ code: 0, info: { username : username, account: info.user.account} });\r\n    } else {\r\n        res.json({ code: 1, error: 'user not logged in.' });\r\n    }\r\n})\r\n\r\n\/\/\u8f6c\u8d26\u524d, \u5148\u9a8c\u8bc1 token\r\napp.post('\/api\/transfer3', (req, res) =&gt; {\r\n    let info = session[req.cookies[SESSION_ID]];\r\n    if(info) {\r\n        \/\/ \u7528\u6237\u5df2\u7ecf\u767b\u5f55\r\n        let { payee , amount , token } = req.body;\r\n        console.log(token);\r\n        console.log('my_token_' + req.cookies[SESSION_ID]);\r\n        \/\/ \u6821\u9a8c token\r\n         if(token === 'my_token_' + req.cookies[SESSION_ID] &amp;&amp; Number(amount)) {\r\n            \/\/ token \u6b63\u786e\r\n            let username = info.user.username;\r\n            userList.forEach(user =&gt; {\r\n                if(user.username === username) {\r\n                    user.account -= amount;\r\n                }\r\n                if(user.username === payee) {\r\n                    user.account += amount;\r\n                }\r\n            });\r\n            res.json({ code : 0})\r\n        }\r\n    } else {\r\n        res.json({code : 1, error : 'user not logged in'})\r\n    }\r\n})\r\n\r\n\r\napp.listen(3001, () =&gt; {\r\n    console.log('Server is running at port 3001')\r\n})\r\n\r\n\/\/\u540e\u7aef server2.js\r\nconst express = require('express');\r\nconst app = express();\r\nconst path = require('path');\r\nconst bodyParser = require('body-parser');\r\nconst cookieParser = require('cookie-parser');\r\n\r\n\/\/\u5c06\u53c2\u6570\u8f6c\u6362\u6210\u5bf9\u8c61\r\napp.use(bodyParser.urlencoded({ extended: true }));\r\n\/\/req.cookie[xxx] \u83b7\u53d6cookie\r\napp.use(cookieParser());\r\n\r\n\/\/\u8bbe\u7f6e\u8def\u5f84\r\napp.use(express.static(path.join(__dirname, 'dest')));\r\n\r\napp.listen(3002, () =&gt; {\r\n    console.log('Server is running at port 3002')\r\n})\r\n\r\n<\/code><\/pre>\n<p><strong>\u603b\u7ed3:<\/strong><\/p>\n<ul>\n<li>\u5728\u767b\u5f55\u4e4b\u540e,\u8fdb\u5165 safe.html \u8f6c\u8d26\u9875\u9762<\/li>\n<li>\u5728\u8f6c\u8d26\u9875\u9762\u5982\u679c\u70b9\u51fb \u9493\u9c7c\u8fde\u63a5, \u5c06\u88ab\u653b\u51fb, \u7b2c\u4e09\u65b9\u7f51\u7ad9\u5c06\u7531\u4e8e\u643a\u5e26 \u7528\u6237cookie, \u6240\u6709\u53ef\u4ee5\u7ed5\u5f00\u9a8c\u8bc1, \u5192\u7528\u88ab\u653b\u51fb\u8005\u7684\u8eab\u4efd, \u505a\u4e00\u4e9b\u653b\u51fb\u8005\u6307\u5b9a\u7684\u64cd\u4f5c\u3002<\/li>\n<\/ul>\n<h4 class=\"heading\" data-id=\"heading-17\">4.Samesite Cookie\u5c5e\u6027<\/h4>\n<p>\u4e3a\u4e86\u4ece\u6e90\u5934\u4e0a\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898, Google \u8d77\u8349\u4e86\u4e00\u4efd\u8349\u6848\u6765\u6539\u8fdb HTTP\u534f\u8bae , \u4e3a Set-Cookie \u54cd\u5e94\u5934\u65b0\u589e Samesite \u5c5e\u6027 , \u5b83\u7528\u6765\u8868\u660e\u8fd9\u4e2a Cookie \u662f\u4e2a &#8220;\u540c\u7ad9Cookie&#8221; , \u540c\u7ad9 Cookie\u53ea\u80fd\u4f5c\u4e3a\u7b2c\u4e00\u65b9 Cookie, \u4e0d\u80fd\u4f5c\u4e3a\u7b2c\u4e09\u65b9 Cookie, Samesite \u6709\u4e24\u4e2a\u5c5e\u6027\u503c , \u5206\u522b\u662f Strict \u548c Lax\u3002<br \/>\n<strong>\u90e8\u7f72\u7b80\u5355, \u5e76\u80fd\u6709\u6548\u9632\u5fa1 CSRF \u653b\u51fb , \u4f46\u662f\u5b58\u5728\u517c\u5bb9\u6027\u95ee\u9898<\/strong><\/p>\n<h5 class=\"heading\" data-id=\"heading-18\">Samesite=Strict<\/h5>\n<p>Samesite=Strict \u88ab\u6210\u4e3a\u662f\u4e25\u683c\u6a21\u5f0f , \u8868\u660e\u8fd9\u4e2a Cookie \u5728\u4efb\u4f55\u60c5\u51b5\u90fd\u4e0d\u53ef\u80fd\u4f5c\u4e3a\u7b2c\u4e09\u65b9\u7684 Cookie, \u6709\u80fd\u529b\u963b\u6b62\u6240\u6709 CSRF\u653b\u51fb\u3002\u6b64\u65f6 , \u6211\u4eec\u5728B \u7ad9\u70b9\u4e0b\u53d1\u8d77\u5bf9 A \u7ad9\u70b9\u7684\u4efb\u4f55\u8bf7\u6c42, A\u7ad9\u70b9\u7684 Cookie \u90fd\u4e0d\u4f1a\u5305\u542b\u5728 cookie\u8bf7\u6c42\u5934\u4e2d\u3002<\/p>\n<h1 class=\"heading\" data-id=\"heading-19\">\u5b89\u5168\u626b\u63cf\u5de5\u5177<\/h1>\n<p>\u5728\u6ca1\u6709\u5b89\u5168\u90e8\u95e8, \u6216\u8005\u6211\u4eec\u524d\u7aef\u53ef\u4ee5\u5148\u8fdb\u884c\u7c97\u7565\u7684\u5b89\u5168\u626b\u63cf<\/p>\n<ol>\n<li><strong>w3af<\/strong><br \/>\n<a href=\"http:\/\/w3af.org\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">w3af<\/a><\/li>\n<li><strong>Arachni<\/strong><br \/>\n<a href=\"https:\/\/www.arachni-scanner.com\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Arachni<\/a><\/li>\n<\/ol>\n<h1 class=\"heading\" data-id=\"heading-20\">\u6700\u540e<\/h1>\n<figure><figcaption><\/figcaption><\/figure>\n<h1 class=\"heading\" data-id=\"heading-21\">\u5f15\u7528\u6587\u7ae0<\/h1>\n<p><a href=\"https:\/\/juejin.im\/post\/5cd6ad7a51882568d3670a8e\" target=\"_blank\" rel=\"\">\u5bd2\u51ac\u6c42\u804c\u4e4b\u4f60\u5fc5\u987b\u8981\u61c2\u7684Web\u5b89\u5168<\/a><\/p>\n<\/div>\n<p>\u94fe\u63a5\uff1ahttps:\/\/juejin.im\/post\/5e75c6a5e51d45271b74922c<br \/>\n\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u524d\u8a00 \u5176\u5b9e, \u524d\u7aef\u7684\u5b89\u5168\u5e76\u6ca1\u6709\u5f88\u591a, \u4e0d\u8fc7\u77e5\u9053\u4e86, \u8d77\u7801\u540e\u7aef\u5144\u5f1f\u4e0d\u4f1a\u90a3\u4e48\u7d2f\u4e86\u3002 \u672c\u6587\u4e3b\u8981\u8ba8\u8bba\u4ee5\u4e0b\u51e0\u79cd\u653b\u51fb\u65b9\u5f0f  [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[105,113],"tags":[114],"_links":{"self":[{"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/posts\/2493"}],"collection":[{"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2493"}],"version-history":[{"count":2,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/posts\/2493\/revisions"}],"predecessor-version":[{"id":2503,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/posts\/2493\/revisions\/2503"}],"wp:attachment":[{"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2493"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2493"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2493"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}