Web安全问题XSS和sql注入 | 青训营笔记

258 阅读5分钟

这是我参与「第四届青训营 」笔记创作活动的的第6天。

今天介绍几种关乎Web安全的问题。

感兴趣的可以看看我之前的文章:红包算法之如何助你抢到大红包 | 青训营笔记 - 掘金 (juejin.cn)

XXS攻击

原理

xss又叫css(Cross-Site Scripting),全称跨站脚本攻击。它是利用网站盲目信任用户提交内容,攻击者往web页面或url里插入恶意JavaScript脚本代码,应用程序对用户输入的内容没有过滤,那么当正常用户浏览该页面时,嵌入在web页面的恶意JavaScript脚本代码会被执行,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。

最常见的几种分类:反射型(非持久型)XSS存储型(持久型)XSSDOM型XSS通用型XSS突变型XSS

其通常有以下一些特点:

  • 通常难以从UI上感知(暗地执行脚本)

  • 窃取用户信息(cookie/token)

  • 绘制UI(例如弹窗),诱骗用户点击/填写表单

反射性XSS

它是非持久型,参数型的跨站脚本。

反射性XSS的原理是:攻击者一般会通过特定手法(如电子邮件),诱使用户去访问一个包含恶意代码的 URL,当受害者点击这些专门设计的链接的时候,恶意代码会直接在受害者主机上的浏览器执行。

反射型XSS的攻击步骤是:

  1. 攻击者在正常的url后面加上恶意攻击代码,然后诱导用户点击

  2. 当用户打开带有恶意代码的URL的时候,网站服务端将恶意代码从URL中取出,拼接在html中并且返回给浏览器端。

  3. 用户浏览器接收到响应后执行解析,其中的恶意代码也会被执行到。

攻击者可以直接通过 URL (类似: https://xxx.com/xxx?default= < script > alert(document.cookie)</script> ) 注入可执行的脚本代码。

不过一些现在浏览器如Chrome其内置了一些XSS过滤器,可以防止大部分反射型XSS攻击

存储型XSS

一般存在于 Form 表单提交等交互功能,如文章留言,提交文本信息等,黑客利用的 XSS 漏洞,将内容经正常功能提交进入数据库持久保存,当前端页面获得后端从数据库中读出的注入代码时,恰好将其渲染执行。

存储型 XSS 攻击不需要诱骗点击,黑客只需要在提交表单的地方完成注入即可。

攻击成功需要同时满足以下几个条件:

  • POST 请求提交表单后端没做转义直接入库。
  • 后端从数据库中取出数据没做转义直接输出给前端。
  • 前端拿到后端数据没做转义直接渲染成 DOM。

DOM型XSS

DOM型XSS是基于DOM文档对象模型的。对于浏览器来说,DOM文档就是一份XML文档,当有了这个标准的技术之后,通过JavaScript就可以轻松的访问DOM。当确认客户端代码中有DOM型XSS漏洞时,诱使(钓鱼)一名用户访问自己构造的URL,利用步骤和反射型很类似,但是唯一的区别就是,构造的URL参数不用发送到服务器端,可以达到绕过WAF、躲避服务端的检测效果。

防御措施

CSP 本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规则,如何拦截是由浏览器自己实现的。我们可以通过这种方式来尽量减少 XSS 攻击

sql 注入

SQL 注入(SQL Injection),是 Web 开发中最常见的一种安全漏洞。

可以用它来从数据库获取敏感信息、利用数据库的特性执行添加用户、导出文件等一系列恶意操作,甚至有可能获取数据库乃至系统用户最高权限。

原因

程序没有有效过滤用户的输入,使攻击者成功的向服务器提交恶意的 SQL 脚本,程序在接收后错误的将攻击者的输入作为 SQL 语句的一部分执行,导致原始的查询逻辑被改变,执行了攻击者的恶意 SQL 语句。

比如从用户表根据用户名和密码查询用户信息

select * from user where username = 'username' and password = '123'

恶意修改用户名:XXX' or 1=1 –

select * from user where username = 'XXX' or 1=1 --' and password = 'XXX'

如果上面这个 SQL 被执行,就可以让攻击者在不知道任何用户名和密码的情况下成功登录。

预防sql注入方法

严格限制 Web 应用的数据库的操作权限,给连接数据库的用户提供满足需要的最低权限,最大限度的减少注入攻击对数据库的危害

校验参数的数据格式是否合法(可以使用正则或特殊字符的判断)

对进入数据库的特殊字符进行转义处理,或编码转换

预编译 SQL(Java 中使用 PreparedStatement),参数化查询方式,避免 SQL 拼接


如有不对之处,欢迎指出~