1. 越权漏洞
1.1. 漏洞原理
假设有一个业务接口/getData用于用户获取用户数据data,并在接口getData上进行了权限p1的校验,业务希望只有p1权限的用户可以获取自己的数据,如下所示。
value="p1") (value="/getData", method=RequestMethod.GET) (publicDatagetData( value="id") Stringid){ (returnqueryService.getData(id); }
用户u1和u2均被赋予p1权限。
正常情况下,用户u1通过自己的id1进行数据获取,因为拥有p1权限,权限校验通过,可以获取到数据data1;用户u2通过自己的id2进行数据获取,因为拥有p1权限,权限校验通过,可以获取到数据data2。
但是不幸的是,用户u2知道了用户u1的id,即为id1,并通过id1获取到了用户u1的数据data1,造成了用户u1的数据泄露,这种情况即水平越权漏洞。造成这种情况的主要原因是因为接口只校验了接口权限,没有验证数据权限导致。
假设有一个系统,它有前台页面,也有后台管理页面,普通用户只能看到前台页面,超管用户可以看到后管页面,当普通用户猜测或获取到后管页面地址后可以直接访问后端页面,这时就产生了垂直越权漏洞。造成这种情况的主要原因是管理页面及其接口未进行权限控制。
1.2. 解决方案
1.2.1. 水平越权
除了已有的接口权限校验完,需再次进行数据归属校验,如校验用户是否有访问数据的权限。
1.2.2. 垂直越权
对页面和接口进行权限控制。
2. SQL注入
2.1. 漏洞原理
SQL注入是通过在应用API接口参数中传入恶意SQL片段,执行恶意SQL达到获取数据、破坏数据的目的。
如获取用户在前端界面上输入的类型字段type的用户本人数据时有如下业务SQL,type变量为用户从前端界面上输入的值,userId为后端系统从登录信息中自动获取。
SELECT*FROM table_1 WHERE type = ${type}AND user_id = ${userId}
正常情况下,用户A输入合法的类型字段值(如为type1),则实际执行的业务SQL如下所示,符合业务预期。
SELECT*FROM table_1 WHERE type ='type1'AND user_id ='A'
异常情况下,如果用户A进行恶意攻击,输入非法的类型字段值(如为' or 1=1 #),则实际执行的业务SQL如下所示,用户ID过滤条件被注释了,用户A获取了所有的业务数据,造成了数据泄露。
SELECT*FROM table_1 WHERE type =''or1=1 #' #AND user_id = 'A'
2.2. 解决方案
2.2.1. 预编译SQL语句
使用PreparedStatement对SQL语句进行预编译,通过变量绑定方式进行SQL执行。
如果使用MyBatis进行SQL语句的编写,则要注意变量需使用#{}进行引用,不能使用${}。因为#{}使用预编译SQL方式绑定变量并执行,${}使用字符串拼接的方式组装SQL并执行。
2.2.2. 用户输入数据参数校验
可以通过前端、后端正则校验限制用户输入数据格式,规范用户输入数据。
3. XSS跨站脚本攻击
XSS(Cross Site Scripting)跨站脚本攻击
3.1. 漏洞原理
XSS是恶意攻击者向页面里插入恶意Script脚本,当用户浏览该页面时触发执行恶意Script脚本,从而达到攻击用户的目的。
假设有一个系统的页面A,其页面URL中的参数name会直接显示到页面上,当用户给name参数赋值一段恶意Script脚本,则此恶意Script脚本会被页面渲染显示到页面A上,恶意Script脚本可能是一张空白的图片,图片的src是一段来自黑客的恶意网站的Script脚本,点击图片后用户的敏感信息cookie就会被发送到黑客的网站。攻击者可以构造带有恶意Script脚本的页面A的URL给到用户,诱使其点击,达到获取用户敏感信息cookie的目的, 这种情况称之为反射型XSS攻击。
论坛网站,用户可以对帖子进行评论,并查看历史评论。如果论坛后台系统没有对评论内容进行校验,当攻击者使用带有恶意Script脚本的内容进行评论时,系统会将此评论存入数据库。之后每次有用户查看这个帖子时恶意Script脚本都会显示到页面上。恶意Script脚本可能是一张空白的图片,图片的src是一段来自黑客的恶意网站的Script脚本,点击图片后用户的敏感信息cookie就会被发送到黑客的网站。这种情况称之为存储型XSS攻击。
3.2. 解决方案
可以通过后端正则校验限制用户输入数据格式,规范用户输入数据。
使用安全包对用户输入数据在输出时进行过滤、转义。如使用apache commons-lang包中的StringEscapeUtils.escapeHtml()方法进行HTML编码。
4. CSRF跨站请求伪造攻击
CSRF(Cross Site Request Forgery)跨站请求伪造
4.1. 漏洞原理
攻击者盗用了用户身份,在当前已登录的网站以用户的名义向某网站发起恶意请求。
例如,用户登录了某银行网站A,此时用户的浏览器中产生了网站A的Cookie。用户在没有登出网站A的情况下不小心访问了恶意网站B,恶意网站B背地里向网站A发出一个转账请求。此时浏览器会带着之前产生的Cookie访问网站。由于请求中带有用户的认证信息,网站A响应了这次请求,并把用户的钱转到了攻击者名下。
4.2. 解决方案
验证Referer:HTTP请求头中Referer字段记录了该请求的来源地址。正常情况下,请求中的Referer会是开发者已知的白名单域名,如果Referer中包含了未知的域名,则判定为攻击,予以拦截。但这种方法过于依赖浏览器,某些低版本浏览器存在漏洞,可以篡改Referer,所以不够安全。而且Referer会记录用户的访问来源,会侵犯用户的隐私权。
请求中增加token:请求方需要先调用服务端的鉴权接口获取一个token,之后的每次请求都需要在参数中带上这个token,并且token设置过期时间。