前言

对于网站开发,我们不得不面对各种网络攻击。而网络攻击的方式千姿百态,这次我们就将学习下常见的三种方式 —— XSS、CSRF、API接口攻击。

XSS介绍

维基百科: 跨站脚本(英语:Cross-site scripting,通常简称为:XSS)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。

比如,一个网站的评论区,用户可以输入script标签,如图

点击submit发送内容,如果前端后端都没有做任何处理的话,这段评论在提交以后就会原封不动地展示在html上。而这个时候,script里的代码执行了,导致所有访问这个页面的用户的cookie都发送到了黑客指定的API。

解决思路

前端

提交过程

前端对于这种情况好像在发送到后端的过程中无能为力,即使在流程中加上前端转译,黑客也可以通过直接在控制台执行js的方式来提交评论。

渲染过程

前端倒是在渲染的时候可以做相应的处理,比如可以用以下方法处理:

processedContent(comment) {	
    return comment	
        .replace(/&/g, "&")	
    .replace(/</g, "<")	
        .replace(/>/g, ">")	
    .replace(/"/g, """)	
    .replace(/'/g, "'")	
}

这样就能处理掉非法符号了(代码仅列举了部分符号)。 &amp;&lt;&gt;这些字符叫做字符实体因为比如 < >这样的字符游览器会认为是标签,所以,如果想正常显示 < >,那么就得转成字符实体,而游览器默认也认识这些字符,在展示的时候,还是展示成字符实体对应的符号。 对于渲染阶段,像react,vue这样的库,又或者是juicer,ejs这样的前端模板,都会默认处理非法符号为字符实体。

字符实体详解可以看这里>> http://www.w3school/html/html_entities.asp

后端

提交过程

后端在收到前端的提交以后,直接存起来就好。

渲染过程

这里的渲染指的是后端模板渲染,渲染模板可能是smarty,可能是laravel的blade,可能是node做中间层用的ejs,亦可能是vue或react的SSR。这些后端模板都自己内部会做转义。 转义的实现方法也无非是通过正则匹配,然后进行替换。

例外

在遇到富文本编辑器的时候,处理方法就不同了。因为,在前端展示的时候,我们自然是有什么标签就展示什么标签,而不是转为字符实体,不然得到的不都是文本了嘛。 这种情况的话,就需要后端进行非法字符过滤了,把比如script这种标签给过滤掉,或者转义掉。当然,其实富文本还有很多过滤条件,比如,非本站的网页地址过滤,非法字符过滤等。

XSS总结

总之,无论是后端模板还是前端模板,其实都是前端的范畴。 上面也说了,现在的前端库、前端模板、后端模板,都已经内部做了转译了,开发者愉快的使用就好了。 所以,其实除了遇到富文本编辑器的情况(工作量在后端),我们几乎不用做任何额外的工作。但是,还是理解内部机制比较好。

CSRF介绍

跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。

简单的说,就是利用游览器对用户的信任,比如,用户已经登录了ww.aaa,自然aaa这个网站就会将用户的登录状态session存在cookie中; 然后,aaa这个网页有一个对作品点赞的功能,点赞提交地址为 aaa.com/api.like?id=777; 这时,另外一个叫www.bbb的网站,放了这样一个元素 <imgsrc="aaa/api.like?id=888">,我们知道,请求静态资源用的是get方法,这样的话,一旦用户进入这个bbb页面,就会请求aaa这个网站的点赞接口,而且点赞的用户对象是888; 最后因为用户的登录信息尚未过期,那就等于给id为888这个作品点赞了,然而,用户并不知情。

防御方式

有两种方法:

  1. 后端判断referer是否合法(不推荐) 通过HTTP的referer可知道,用户是通过哪个网站发送这个请求的。但是referer的判断并不是好方法,有各种方式可以绕过的方法,具体可见 CSRF 花式绕过Referer技巧>>

    https://www.ohlinge/web/csrf_referer.html

  2. 每次请求带上token 比如laravel,在后端模板渲染的时候会提供一个csrf的token,这样的话,不同域的网站是拿不到token的,所以也就防止了csrf了。

补充

使用iframe会引出一些不安全的问题,比如绕过referer验证,比如资源盗用等,所以,很多网站会设置 X-Frame-OptionsDENY,这也是一个安全的补充点。

Q&A

问:既然请求静态资源都是get请求,那么要是后端把点赞接口改为post的方式也可以吧?

答:不可以。因为,bbb网站完全可以设置一个form表单,action为bbb,method为post,接着input的name为id,value为888,然后,script代码直接submit表单。为了页面不重定向,还可以在form外层加一个iframe。由于form表单其实是直接跳转,所以不存在跨域的问题。

CSRF总结

防止CSRF的最好方法还是带token吧~

API接口攻击

相信很多网站都会遇到也不知道是谁,毫无目的刷网站的接口的事情。 尤其是短信接口,好像所有网站都会被人刷接口,十有八九都是短信接口的提供商找人干的。。。 其次,登录接口也是经常被刷地方,因为可以被破坏者用来爆破用户的密码。 然后,注册接口也是,不过因为国家强制要求手机号注册的原因,现在还好刷注册接口很难了。

防御方式

1、监控异常ip,发现异常ip,直接封ip(这种方法要是遇到使用肉鸡刷的人就没什么办法了) 2、使用验证码(这种方法缺点就是降低用户体验) 在实际项目中,这两种防御方式会一起使用。

这两种防御方式同样应用在爬虫的防御上。由于验证码这东西市面上有很多种,而好的交互和用户的体验息息相关,那么,现在有哪些种类的验证码呢,我们又该怎么选择呢?

验证码分类

1、图形验证码(已淘汰)

缺点:用户体验差;攻击者可以用图像识别算法识别字母

2、坐标验证码(不推荐)

缺点:用户体验差;同样可以通过算法识别,然后模拟点击定位

3、滑块验证码

前几年比较火,几乎所有大网站都用了这种方法,但是也有问题 缺点:要是攻击者有了整套的图片资源,也能破解。极验验证码之前就因为滑块图片泄露,导致很多用他们家服务的网站被攻击了。后来他们紧急更新了滑块包和SDK(偷偷地),当时我们CTO打电话给他们才给我们说他们滑块资源被盗了,居然不也通知我们,我们问了才说,造成了公司的损失,浪费了人员的精力。

4、无感知验证码

最为代表性的就是谷歌的reCAPTCHA了,但是毕竟是谷歌服务,国内用起来还是很鸡肋的。 不过,国内也有了这样的解决方案,比如极验就出了这项云服务了,不过名字叫做“智能验证码”。

API接口攻击总结

无感知验证码可以说是目前最好的验证码解决方案了。 然而很多公司还是停留在图形验证码的阶段 ╮(╯_╰)╭

总结

名称发生场景列举解决方案
XSS用户图文编辑非法标签过滤
CSRF骗赞csrf token
API接口攻击发送短信无感知验证码

 热 文 推 荐 

☞ 可能这些是你想要的 H5 软键盘兼容方案

☞ React 中的高阶组件及其应用场景

☞ 从0到1完成一个Babel插件

☞ 如何优雅处理前端的异常?

☞ 面试官:自己搭建过vue开发环境吗?

你也“在看”吗?

更多推荐

网络安全之XSS、CSRF、API接口攻击