Web 安全之攻防总结
JTangming opened this issue · 1 comments
以下基于常见的攻击方式入手,对攻防方式和策略做一些总结。
CSRF
CSRF(Cross Site Request Forgery),即跨站请求伪造,是常见的 Web 攻击之一,攻击过程示例图如下:
CSRF 利用用户已登录的身份,在当前用户毫不知情的情况下完成非法操作,通过上图总结攻击原理如下:
- 用户正常登录过网站 A 且在本地记录了 cookie,且用户没有退出登录
- 在用户 cookie 生效的情况下,访问危险网站 B,且在 B 站点要求访问站点 A
- 根据访问 A 中记录的 cookie,访问之,前提是站点 A 没有做任何的 CSRF 防御
举个例子方便理解,用户登陆某银行网站,以 Get 请求的方式完成转账,攻击者可构造另一危险链接 B,并把该链接通过一定方式诱骗受害者用户点击。受害者用户若在浏览器打开此链接,会将之前登陆后的 cookie 信息一起发送给银行网站,服务器在接收到该请求后,确认 cookie 信息无误则完成该请求操作,造成攻击行为完成。
攻击者可以构造 CGI 的每一个参数,伪造请求,这也是存在 CSRF 漏洞的最本质原因。
CSRF 防御方式
1、验证码,在一些关键的节点操作加上验证码,但是该种方式一定程度上会降低用户体验
2、Referer Check,通过 Http header 的 referer 鉴定请求来源。但在某些情况下如从 https 跳转到 http,浏览器基于安全考虑,不会发送 referer,服务器就无法进行 check,所以这种方式不是 CSRF 的主要防御手段。
3、SameSite,可以对 Cookie 设置 SameSite 属性,但并不是所有浏览器都支持的。
4、Anti CSRF Token,比较完善的解决方案是加入 Anti-CSRF-Token。即发送请求时在 Http 请求中加入 token,并在服务器建立一个拦截器来验证 token。服务器读取浏览器当前域 cookie 中的 token 值,然后进行校验,即该请求中的 token 和 cookie 中的 token 值是否都存在且相等,才认为这是合法的请求,否则拒绝该次服务。
总结一下就是:
- Get 请求严格遵循不对数据进行修改原则
- 不让第三方网站访问到用户 Cookie
- 阻止第三方网站来源请求
- 请求时附带验证信息,比如验证码或者 Token
XSS 攻击
XSS(Cross Site Scripting),跨站脚本攻击。恶意攻击者往 Web 页面里注入恶意 Script 代码,当用户浏览这些网页时,就会执行其中的恶意代码,可造成对用户 cookie 信息盗取、会话劫持等各种攻击。
XSS 的攻击原理是往 Web 页面里插入可执行网页脚本代码,当用户浏览该页之时,嵌入其中的脚本代码会被执行,从而可以达到盗取用户信息或其他侵犯用户安全隐私的目的。有可能造成以下影响:
- 利用虚假输入表单骗取用户个人信息。
- 利用脚本窃取用户的 Cookie 值,被害者在不知情的情况下,帮助攻击者发送恶意请求。
- 显示伪造的文章或图片。
1、非持久型 XSS
非持久型 XSS 漏洞,一般是通过给在 URL 参数中添加恶意脚本,当 URL 链接被打开后,特有的恶意代码参数被 HTML 解析、执行。
非持久型 XSS 漏洞攻击有以下几点特征:
- 即时性,不经过服务器存储,直接通过 HTTP 的 GET 或 POST 请求就能完成一次攻击,拿到用户隐私数据。
- 攻击者需要诱骗点击,必须要通过用户点击链接才能发起
- 用户常常无感知,造成反馈率低,所以较难发现和响应修复
- 盗取用户敏感保密信息
预防非持久型 XSS 攻击,可以采取如下措施:
- 页面完全依赖后端返回来渲染页面。
- 尽量不要从 URL、document.referrer、document.forms 等这种 DOM API 中获取数据直接渲染。
- 尽量不要使用 eval, new Function(),document.write(),document.writeln(),innerHTML,document.createElement() 等可执行字符串的方法。
- 如果做不到以上几点,也必须对涉及 DOM 渲染的方法传入的字符串参数做 encodeURI 或 encodeURIComponent 转义。
2、持久型 XSS
该种攻击一般存在于 Form 表单交互的提交,如文章留言,提交文本信息等。即将内容经正常功能提交进入数据库持久保存,当前端页面获得后端从数据库中读出的注入代码时,恰好将其渲染执行。
与 1 中非持久型注入不一样,其来源是之前非法提交的存储在数据库中的数据,持久型 XSS 攻击不需要诱骗点击,黑客只需要在提交表单的地方完成注入即可。
防御手段如下:
- 输入过滤和输出编码,永远不要相信用户的输入,对用户输入的数据做一定的过滤(前后端都需要,避免如前端抓包工具绕过限制),如使用 js-xss 来实现。
- 内容安全策略 (CSP),是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括跨站脚本 (XSS) 和数据注入攻击等,本质上就是建立白名单。如需了解更多 CSP 属性,请查看 Content-Security-Policy 文档
- HttpOnly Cookie,这是预防XSS攻击窃取用户cookie最有效的防御手段。
SQL 注入攻击
SQL 注入即攻击者利用这个漏洞,可以访问或修改数据,或者利用潜在的数据库漏洞进行攻击。
攻击原理
攻击者将 SQL 命令插入到 Web 表单提交或在表单输入特殊字符,最终达到欺骗服务器执行恶意的 SQL命令。一次 SQL 攻击大致过程是:获取用户请求参数,拼接到代码当中,SQL语句按照我们构造参数的语义执行成功。SQL 注入可能是因为:
- 针对用户提交信息如转义字符处理不全,如输入验证和单引号处理不当
- 后台查询语句处理不当,开发者完全信赖用户的输入,未对输入的字段进行判断和过滤处理,直接调用用户输入字段访问数据库
- SQL 语句被拼接,攻击者构造精心设计拼接过的SQL语句,来达到恶意的目的。如构造语句:
select * from users where userid=123; DROP TABLE users;
直接导致 users 表被删除
如何防御
- 严格限制 Web 应用的数据库的操作权限,给用户仅提供能够满足其工作的最低权限,从而最大限度的减少注入攻击对数据库的危害
- 后端代码检查输入的数据是否符合预期,严格限制变量的类型,例如使用正则表达式进行一些匹配处理
- 对进入数据库的特殊字符(',",\,<,>,&,*,; 等)进行转义处理,或编码转换,如 lodash 的 lodash._escapehtmlchar 库
- 所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到 SQL 语句中,即不要直接拼接 SQL 语句
DoS 攻击
DoS(Denial of Service),即拒绝服务,造成远程服务器拒绝服务的行为被称为 DoS 攻击。其目的是使计算机或网络无法提供正常的服务,最常见的 DoS 攻击有计算机网络带宽攻击和连通性攻击。
为了进一步认识 DoS 攻击,需要了解 TCP 三次握手及数据段互换的过程,具体参考下图:
在 DoS 攻击中,攻击者通过伪造 ACK 数据包,希望 Server 重传某些数据包,Server 根据 TCP 重传机制,进行数据重传。攻击者通过发送大量的半连接请求,耗费 CPU 和内存资源,实现方式如下图:
Web 服务器在未收到客户端的确认包时,会重发请求包一直到链接超时,才将此条目从未连接队列删除。攻击者再配合IP欺骗,SYN 攻击会达到很好的效果。通常攻击者在短时间内伪造大量不存在的 IP 地址,向服务器不断地发送 SYN 包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的 SYN 包将长时间占用未连接队列,正常的 SYN 请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。
SYN 攻击的问题就出在 TCP 连接的三次握手中,假设一个用户向服务器发送了 SYN 报文后突然死机或掉线,那么服务器在发出 SYN+ACK 应答报文后是无法收到客户端的 ACK 报文的,从而导致第三次握手无法完成。在这种情况下服务器端一般会重试,即再次发送 SYN+ACK给 客户端,并等待一段时间后丢弃这个未完成的连接。这段时间的长度我们称为 SYN Timeout,一般来说这个时间是分钟的数量级,大约为30秒到2分钟。但如果有一个恶意的攻击者大量模拟这种情况,服务器端将为了维护一个非常大的半连接列表而消耗非常多的资源,即数以万计的半连接,将会对服务器的CPU和内存造成极大的消耗。
对于该类问题,可以做如下防范:
- 缩短SYN Timeout时间,及时将超时请求丢弃,释放被占用CPU和内存资源
- 限制同时打开的SYN半连接数目,关闭不必要的服务
- 设置SYN Cookie,给每一个请求连接的IP地址分配一个Cookie。如果短时间内连续受到某个IP的重复SYN报文,就认定是受到了攻击,以后从这个IP地址来的包会被一概丢弃
一般来说,第三种方法在防范该类问题上表现更佳。同时可以在Web服务器端采用分布式组网、负载均衡、提升系统容量等可靠性措施,增强总体服务能力。