这是我参与「第四届青训营 」笔记创作活动的的第9天,今天的课程是「Web开发的安全之旅」,老师主要讲解了 常见的攻击手段 、 如何应对这些攻击 、 这些攻击的常见方式 等内容。
从两个角度看Web安全
攻击篇
最常见的攻击手段——跨站脚本攻击
Cross-Site Scripting(跨站脚本攻击)简称 XSS,开发者会将恶意脚本注入进来。
XSS一般会用于某些会盲目信任用户提交内容的网站,直接将用户提交的内容转换成DOM,从而给了攻击者钻空子的机会,将恶意脚本放在本该是用户提交内容的地方,进而对网站造成攻击。
XSS的一些特点
1、通常难以从UI上感知(暗地执行脚本)
2、窃取用户信息(cookie/token)
3、绘制UI(例如弹窗),诱骗用户点击/填写表单
XSS Demo
图中的代码在用户点击提交按钮时,直接将用户提交的内容保存在数据库中,并在渲染页面时直接将内容取出调用。两个过程中都没有对用户提交的内容进行检测和过滤,导致用户提交的内容直接被用于显示,这样就给了攻击者攻击网站的机会。
例如下图中,用户提交了一行JS语句,然而这行语句没有被检测和过滤掉,在调用的时候就以代码的方式插入网页之中,从而造成攻击和破坏。
存储型XSS
XSS攻击的恶意脚本通常被存储在数据库中,而当用户访问页面,也就是读数据的时候,就会对网站造成攻击,而这攻击的危害非常大,因为该攻击对全部用户可见。
反射型XSS攻击
当用户访问一个带有XSS代码的URL请求时,服务器端接收数据后处理,然后把带有XSS代码的数据发送到浏览器,浏览器解析这段带有XSS代码的数据后,最终造成XSS漏洞。
反射型XSS包括GET类型和POST类型。
GET类型一般就是直接在url后面插入,或者搜索框插入。POST类型原理跟GET类型一样,只不过是以POST类型传参。
基于DOM的XSS攻击
这种攻击方式完全不需要服务器的参与,恶意攻击的发起和执行全在浏览器完成。
DOM型XSS其实是一种特殊类型的反射型XSS,它是基于DOM文档对象模型的一种漏洞。
反射型和基于DOM型的区别
反射型XSS需要经过服务器,而DOM型直接在浏览器中完成不需要经过服务器。
反射型XSS顺序:攻击者引导用户点击恶意url后,浏览器向服务器发送请求,服务器再将带有恶意脚本的网页返回,最后浏览器执行恶意脚本,发起请求携带用户Cookie。
DOM型XSS顺序:攻击者引导用户点击恶意url之后直接执行恶意脚本,发起请求携带用户Cookie。
基于Mutation的XSS攻击(突变型XSS)
这种攻击方式利用了浏览器渲染DOM的特性(独特优化),不同浏览器会有区别(按浏览器进行攻击)。
XSS漏洞是由浏览器解释HTML标准的方式不同造成的。由于浏览器的不同,很难对服务器上的用户输入进行清理。服务器不仅需要考虑浏览器之间的所有差异,还需要考虑它们的版本之间的所有差异。对输入进行过滤以防止XSS的最有效的方法是让浏览器解释输入而不实际执行它。
跨站伪造请求
CSRF,Cross-site request forgery,即跨站伪造请求。
在用户不知情的情况下,利用用户权限(cookie),构造HTTP请求,窃取或修改用户敏感信息。
SQL注入
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
SQL是操作数据库数据的结构化查询语言,网页的应用数据和后台数据库中的数据进行交互时会采用SQL。而SQL注入是将Web页面的原URL、表单域或数据包输入的参数,修改拼接成SQL语句,传递给Web服务器,进而传给数据库服务器以执行数据库命令。如Web应用程序的开发人员对用户所输入的数据或cookie等内容不进行过滤或验证(即存在注入点)就直接传输给数据库,就可能导致拼接的SQL被执行,获取对数据库的信息以及提权,发生SQL注入攻击。
SQL注入Demo
SSRF(服务端伪造请求)
SSRF是由一种攻击者构造请求,由服务器端发起请求的安全漏洞。一般情况下SSRF的攻击目标是外网无法访问到的内部系统。(正因为请求是由服务器发起的,所以服务器端能请求到与自身相连而与外网隔离的内部系统。)SSRF的形成大多是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。
SSRF Demo
服务拒绝
指通过某种方式(构造特定请求)导致服务器资源被显著消耗,来不及响应更多请求,导致请求挤压,进而雪崩效应。
DoS是Denial of Service的简称,即拒绝服务,造成DoS的攻击行为被称为DoS攻击,其目的是使计算机或网络无法提供正常的服务。最常见的DoS攻击有计算机网络宽带攻击和连通性攻击。 DoS攻击是指故意的攻击网络协议实现的缺陷或直接通过野蛮手段残忍地耗尽被攻击对象的资源,目的是让目标计算机或网络无法提供正常的服务或资源访问,使目标系统服务系统停止响应甚至崩溃,而在此攻击中并不包括侵入目标服务器或目标网络设备。这些服务资源包括网络带宽,文件系统空间容量,开放的进程或者允许的连接。这种攻击会导致资源的匮乏,无论计算机的处理速度多快、内存容量多大、网络带宽的速度多快都无法避免这种攻击带来的后果。
正则表达式——贪婪模式
基于正则表达式的DoS
DDoS
Distributed DoS,DDoS,指短时间内来自大量僵尸设备的请求流量,服务器不能及时完成全部请求,导致请求堆积,进而雪崩效应,无法响应新请求。
这种攻击特点是直接访问IP,任意API,消耗大量带宽(耗尽)。
分布式拒绝服务攻击可以使很多的计算机在同一时间遭受到攻击,使攻击的目标无法正常使用,分布式拒绝服务攻击已经出现了很多次,导致很多的大型网站都出现了无法进行操作的情况,这样不仅仅会影响用户的正常使用,同时造成的经济损失也是非常巨大的。
分布式拒绝服务攻击方式在进行攻击的时候,可以对源IP地址进行伪造,这样就使得这种攻击在发生的时候隐蔽性是非常好的,同时要对攻击进行检测也是非常困难的,因此这种攻击方式也成为了非常难以防范的攻击。
中间人攻击
中间人攻击(Man-in-the-MiddleAttack,简称“MITM攻击”)中间人攻击很早就成为了黑客常用的一种古老的攻击手段,并且一直到如今还具有极大的扩展空间。在网络安全方面,MITM攻击的使用是很广泛的,曾经猖獗一时的SMB会话劫持、DNS欺骗等技术都是典型的MITM攻击手段。在黑客技术越来越多的运用于以获取经济利益为目标的情况下时,MITM攻击成为对网银、网游、网上交易等最有威胁并且最具破坏性的一种攻击方式。
防御篇
XSS
不要相信用户提交的内容,不要将用户提交的内容直接转换成DOM,而是转换成字符串对待。前端主流框架默认防御XSS,如google-closure-library,服务端(Node)可使用DOMPurify。
CSP
CSP指的是内容安全策略,为了缓解很大一部分潜在的跨站脚本问题,浏览器的扩展程序系统引入了内容安全策略(CSP)的一般概念。这将引入一些相当严格的策略,会使扩展程序在默认情况下更加安全,开发者可以创建并强制应用一些规则,管理网站允许加载的内容。
CSP以白名单的机制对网站加载或执行的资源起作用。在网页中,这样的策略通过 HTTP 头信息或者 meta 元素定义。CSP虽然提供了强大的安全保护,但是他也造成了如下问题:Eval及相关函数被禁用、内嵌的JavaScript代码将不会执行、只能通过白名单来加载远程脚本。这些问题阻碍CSP的普及,如果要使用CSP技术保护自己的网站,开发者就不得不花费大量时间分离内嵌的JavaScript代码和做一些调整,参考文献汇总的Content Security Policy 1.0 研究的技术可以自动化分离代码和数据,帮助网站支持CSP技术避免潜在的跨站攻击。
CSRF的防御
1、重要数据交互采用POST进行接收,当然是用POST也不是万能的,伪造一个form表单即可破解
2、使用验证码,只要是涉及到数据交互就先进行验证码验证,这个方法可以完全解决CSRF。但是出于用户体验考虑,网站不能给所有的操作都加上验证码。因此验证码只能作为一种辅助手段,不能作为主要解决方案。
3、验证HTTP Referer字段,该字段记录了此次HTTP请求的来源地址,最常见的应用是图片防盗链,PHP中可以采用APache URL重写规则进行防御。
4、为每个表单添加令牌token并验证(可以使用cookie或者session进行构造。当然这个token仅仅只是针对CSRF攻击,在这前提需要解决好XSS攻击,否则这里也将会是白忙一场,因为XSS可以偷取客户端的cookie)
CSRF攻击之所以能够成功,是因为攻击者可以伪造用户的请求,该请求中所有的用户验证信息都存在于Cookie中,因此攻击者可以在不知道这些验证信息的情况下直接利用用户自己的Cookie来通过安全验证。由此可知,抵御CSRF攻击的关键在于:在请求中放入攻击者所不能伪造的信息,并且该信息不存在于Cookie之中。
鉴于此,我们将为每一个表单生成一个随机数秘钥,并在服务器端建立一个拦截器来验证这个token,如果请求中没有token或者token内容不正确,则认为可能是CSRF攻击而拒绝该请求。
由于这个token是随机不可预测的并且是隐藏看不见的,因此恶意攻击者就不能够伪造这个表单进行CSRF攻击了。
SAMESITE VS CORS
SameSite:
- Cookie发送
- domain vs 页面域名
- 可以用俗话说就是“我跟你说个事儿,出这屋我可就不认了”
CORS:
- 资源读写(HTTP请求)
- 资源域名 vs 页面域名
- 白名单
防御CSRF
不要使用CASE BY CASE 的防御手段,而是应该编写应该中间件专门用于防御CSRF,并设计可能遇到的情况。
注入
1.(简单又有效的方法)PreparedStatement
采用预编译语句集,它内置了处理SQL注入的能力,只要使用它的setXXX方法传值即可。
使用好处:
(1)代码的可读性和可维护性。
(2)PreparedStatement尽最大可能提高性能。
(3)最重要的一点是极大地提高了安全性。
原理:
sql注入只对sql语句的准备(编译)过程有破坏作用,而PreparedStatement已经准备好了,执行阶段只是把输入串作为数据处理,而不再对sql语句进行解析、准备、因此也就避免了sql注入问题。
SQL注入
2.使用正则表达式过滤传入的参数
要引入的包:
import Java.util.regex.*;
正则表达式:
private String CHECKSQL = “^(.+)\\sand\\s(.+)|(.+)\\sor(.+)\\s$”;
判断是否匹配:
Pattern.matches(CHECKSQL,targerStr);
Regex DoS
- Code Review ×
- 代码扫描 + 正则性能测试
- 用户提供的使用正则 ×
Logical DoS
- 不是非黑即白
- 有些case,只有在请求量大到一定之后才会体现
- 分析代码中的性能瓶颈
- 同步调用
- 串行逻辑
- CPU密集型操作
- 限流
DDoS
防御中间人
HTTPS的一些特性