- 这是我参与「第四届青训营」笔记创作活动的第3天
上一篇我们介绍了一些常见的攻击方式,今天我们继续在web的安全之旅中了解这些常用攻击的防御方式,想作为一位合格的开发人员我们将学习如何防止我们的用户信息被泄露,防止我们的服务器被攻击。
防御篇
防御xss
在攻击篇里我们了解到攻击者利用的是
- 开发人员盲目信用用户提交的内容。
- 开发者将字符串直接转化生成Dom tree。
那么对于xss的防御便是我们永远不能相信用户的输入 ❗ ❗
我们更应该将用户所输入的当作string来对待。
xss防御的现成工具:
在前端方面:
- 主流框架默认防御XSS(因为使用那些框架已经不需要我们手动操作DOM了)
- google-closure-library(如果需要可以使用这个第三方库)
服务端方面:
- DOMPurify(npm包)
但如果有用户需求一定要动态生成DOM一定要注意
比如说用户传过来一些副文本
比如说这里调用了一个DOMparser()这里我们就一定要注意,要对string进行转义。
又或者是:
我们如果允许用户上传svg文件那么我们要对svg文件进行扫描。因为按照规范,svg之中可以插入script标签。那也就是说svg图片如果被加载script就会被执行。
还有就是自定义的跳转链接:
要做好过滤 ❗ ❗自定义跳转链接是可以传递JavaScript代码的
比如说这里有一个输入项让用户去填写他的具体收入,假如有攻击者传入了一个自定义的样式。
如上图,只有某一个radio标签被选中的时候才会触发一个背景图的请求。也就是说只有指定送入的用户才会触发这个get请求。这个用户的收入情况也就暴露给了恶意攻击者。
知识插播
浏览器同源策略 Same-origin Policy
同源:
- 协议
- 域名
- 端口号
都相同才能被称做同源。有一个不相同我们都称之为跨域
如图中的三个HTML都是不同源的。
内容安全策略 Content Security Policy(CSP)
举个具体例子:
根据script的src我们设置成了self,这个页面中任何script标签必须是同源我们才允许执行,如果是非同源的话就不被允许执行。
在这个例子中,我们在同源之外我们还允许了另外一个域名的script标签去执行,此外其他的所以域名通通不可以。我们就通过了域名来限制了恶意攻击。
CSRF的防御
CSRF是跨站伪造请求,在用户不知情的前提下 利用用户权限(cookie) 构造指定HTTP请求,窃取或修改用户敏感信息。
我们可以通过限制这些来源来防御CSRF攻击。可以根据origin或者referer进行校验,如果origin或者referer是我的域名,那么我就放行这个请求。注意:同源请求中get和head的请求是不会发送origin这个字段。
我们还可以通过token来识别源和用户:
由页面先向服务器发送页面请求,server在回复一个页面与具体的token,之后浏览器在请求api的时候会把这个token带上,服务器端对token进行校验,如果校验通过就返回具体数据。要注意,这里的token往往是和具体的用户进行绑定的,因为攻击者也可能是一个合法的注册用户,他可以用自己的token去模拟试探。然后token有一个过期时间,以保证合法用户的token丢失时被窃取利用。 😾
iframe防御
iframe式的攻击可以绕过origin请求。
攻击者会构造一个页面,页面上有一个button标签,button标签下面会盖着一个页面iframe,也就是我们的合法页面,在用户点击这个button后,由于button标签设置了css属性点击行为会穿越,导致iframe中发送了一个HTTP请求从而绕过了origin和referer完成了攻击。 😈
日常开发中,经常把GET请求和POST请求都当成GET请求来出来,其实这是不好的习惯,如果被攻击,不光是用户的隐私数据被泄露,甚至用户的数据都会被篡改。不能偷懒哦 🙃
我们还可以通过SameSite Cookie 属性来防御
当我页面的cookie只能为我所用,页面向我发出请求都不能带上我的cookie,这也就是从根源上解决了CSRF的攻击方式。
假如我有一个页面,页面对应的域名为A,domain属性为A的cookie我们都称为第一方cookie也就是SameSite Cookie,其他的是第三方cookie,当我们发出请求时,所有的第一方cookie都可以被带上,而第三方的cookie都不会带给域名A的服务器(默认情况下)。如果我们的页面有依赖到cookie的第三方服务,我们可以在服务器端进行Site cookie操作的时候可以把SameSite Cookie的属性设置为none,但同时我们要表明这个第三方cookie时secure的,以确保安全。
SameSite Cookie 🆚 CORS
SamesSite限制于在当前的页面,而CORS类似于白名单。
防御CSRF的正确方式
我们应当从中间件进行防御,我们应该建立一个中间件,专门生成防御CSRF的策略就在一处,保证web对CSRF的防御
injection注入类型防御
- 找到使用SQL的地方
- 使用 prepared statement(将库中的语句进行提前的编译导致注入式的攻击不能够完成。)
对于injection攻击的原则
一定要过滤和拒绝-rm行为 🚫 🚫 🚫
防御DOS
一定不能写出具有贪婪匹配的正则表达式,并且拒绝使用用户提供的正则表达式,并对代码中的正则表达式进行测试。
防御DDOS
要注意经行流量的识别,把能够识别出来是恶意攻击的进行过滤。也可以通过前置CDN,所以流量都要通过CDN再到我们具体的服务。我们还可以在检测到有流量激增的情况下进行快速的自动扩容,并且降低非核心服务的等级,进行扛量。
中间人防御
我们可以通过HTTPS来对中间人的攻击进行防御。
HTTPS的特点:
- 加密避免了明文传输。(还有用到hash值,通过对比hash的值来判断有无篡改行为)
- 通过MAC校验规则防止了篡改。
- 通过数字签名绑定了身份。(执行者用privatekey对内容进行计算生成一个对应的签名,有publickey的可以对签名进行校验)
如图:TLS握手分为非对称加密于对称加密。非对称加密过程中,浏览器会把自己支持的加密套件选项传给服务端,服务器端会选用具体的加密套件并把证书返还到浏览器端,浏览器会先对证书进行校验,如果证书校验通过就会根据定好的加密算法与随机数等设定一个sessionKey。对称加密在非对称加密后浏览器与服务器端通过sessionKey进行加密传输。
有关证书:
每个浏览器都会内置大量的CA的证书,这些证书里面就会包含CA的publickey。
首先呢,浏览器测会向服务器端发有关https的请求,服务器接收到请求就会返回一个Strict(如图)的头部,并且传递了一个值(
max-age=3600)也就是在这个时间范围内,之后如果浏览器发出的是http请求都会被转为https协议。
如果我们的cdn被攻击,我们可以通过对比hash值(利用sri),保证我们静态资源的内容没有被篡改
总结
网络安全不是小事,攻击者的攻击方式不断更新,我们的防御手段也要不停进步,保持学习,注重web安全才是保证web开发安全的长久之计 。📚 📚