5. 架构优化-安全性
道高一尺,魔高一丈。没有攻不破的网站,只有攻击成本大于攻击收益的网站,所以我们需要根据网站的价值提升其安全性。
5.1 常用攻击手段和防范技术
(1) XSS攻击
Cross Site Script
跨站脚本攻击是一种古老却花样频出的攻击方式。通过在用户浏览的页面的html
里嵌入恶意的脚本或者恶意脚本的url
,用户触发脚本后浏览器就会解释执行这些脚本,做出我们不想做的操作。一般可以分为两种:
- 反射型攻击:在网站上发布一个含有恶意脚本(或者包含脚本的
url
,脚本本身存放在攻击者的服务器)的链接,诱使用户点击,然后浏览器就会执行攻击者的恶意脚本。 - 持久型攻击:这种方法常用于论坛、博客,在提交的数据里嵌入恶意脚本然后被存放到网站的数据库,之后恶意脚本就会包含在正常的页面里,用户浏览对应的页面就会中招。
应对方法常用的有:
- 消毒:为了防止持久型的XSS攻击,即防止别人在提交的数据里嵌入脚本,我们需要扫描用户提交的数据,如:
"<img src="
这样的,正经用户怎么会输入这种奇怪的文本,所以可以对<
进行转义为:"<"
。消毒几乎是网站必备手段。 - HttpOnly:将
cookie
设置为httOnly
,不是为了防止XSS而是防止中了XSS攻击时cookie
不能被脚本劫持,即不会被恶意脚本拿到cookie
的数据。
(2) 注入攻击
- SQL注入:后端有一条语句:
delete from table1 where id = ${id}
,id
由用户填写,这是如果用户填写1 or 1 = 1
,那么这条语句就会把数据删光了。当然想做到这些并不容易,攻击者需要知道网站库表结构,一般的获取方式有:网站使用开源软件搭建,库表结构是公开的;错误回显,通过输入不同参数获得的错误反馈猜测库表结构;盲注,通过页面的变化请求入参数结构猜测,难度很大。 - 其他注入如
os
注入,编程语言注入,都可以利用漏洞达到攻击目的。
应对SQL注入的方法一般有:
- 消毒,采用正则匹配去检查是否用户的输入了
SQL
命令。 - 参数绑定:
ORM
框架大多有这个功能,先对语句预编译:delete from table1 where id = #{id}
,使用#
号占位符表示这里仅仅代表一个参数而不是命令,因为命令都已经预先编译了就等把值注入进来,SQL
注入的攻击方式行不通了。
(3) CSRF攻击
跨站请求伪造就是攻击者冒充某个用户发起一些请求,损害真实用户的利益,核心是利用 cookie
、session
机制盗用用户身份。防御手段核心就是识别真实用户,一般有如下手段:
- 表单token:每一个页面表单都设置一个随机
token
,每次响应后的页面token
都不同,用户发起请求时除了正常的参数外还要带上这个token
才能合法访问,这时攻击者虽然可以伪造请求参数但是无法获得当前正确的表单token
。 - 验证码:简单有效,但是降低用户体验,一般关键功能使用,如交易支付。
- referer check:检查请求头里的
refere
字段的值,是否由合法url
发来这个请求。很多网站都用这种技术防止图片盗用,即其他网站的页面白嫖发起请求想我的服务器存放的图片时,直接拒绝。
(4) 其他要注意的手段
- ErrorCode: 大多服务器默认打开异常信息输出的,即服务器未处理的异常堆栈信息都会输出到浏览器,攻击者故意构造非法输入查看各种异常堆栈信息猜测程序漏洞。一般可以配置服务器发生错误时跳转到专门的页面。
- html注释:
PHP
、JSP
页面开发时为了方便打了html
注释语法的注释,上线后攻击者查看网页源代码时会看到这些注释,则有可能为其提供了便利。一般上线前需要扫描,防止html
注释。 - 文件上传:一般网站都有文件上传的功能,但是攻击者如果上传了可执行程序并且该程序获得了服务器端执行的命令,那么攻击者几乎可以为所欲为,还可以以此为跳板攻击集群其他机器。一般防御手段时:限制上传文件类型,对上传的文件重命名为其他类型,使用专门的存储手段。
- 目录遍历:攻击者在请求的
url
使用相对路径,如../ ~/
等,访问系统不开放的目录和文件,一般防御方法是将js
,css
静态资源放到独立服务器,其他文件不适应静态url
访问,动态参数不包含文件路径信息。
5.2 加密技术和密钥安全
(1) 加密技术
- 单向散列加密: 单向加密的意思是对明文加密后就不能够再解密了,一般用于数据库存放一些敏感信息时使用。我们熟知的
md5
就是单向散列加密,这种技术还有个特点就是原文只要有一点变动生成的密文就会大不同,因此也适合做摘要算法。 - 对称加密:加密、解密是一个密钥,加密简单快速,适合大量数据的加密,但是密钥的安全传输是一个问题。
- 非对称加密:一对密钥,分为公钥、私钥,一方加密则只能用另一方解密,私钥不公开,公钥公开,所以除了加密外还可以用这种技术做数字签名。
https
的第三方机构的证书防伪就是使用私钥加密生成签名,浏览器获得签名后用公钥解密成功即可说明这个证书确实是正确的机构颁发的。
(2) 密钥安全管理
很多人喜欢将密钥写到配置文件中,甚至直接写在源码里,这样是很不安全的,至少公司内部很多人都能看到。一种较好的方案是设立一台服务器专门保存密钥,并将密钥分成几部分存到不同的存储介质中,派专人管理。
5.3 信息过滤和反垃圾
(1) 文本匹配
- 网站维护一份敏感词列表,正则表达式匹配文本中是否含有敏感词,性能有点低。
- 当数据量很大时,正则就不能用了,可以用
Trie
算法。
(2) 分类算法:将信息分类,从而更好的管理。
- 朴素贝叶斯算法:对数据进行分析,提取特征值,根据分类模型判断这个信息的分类。分类模型可以由大量的已分类信息经过分类算法训练得来,例如经过训练得到的模型认为有特征值"茶叶"是垃圾邮件的概率为30%,当然朴素贝叶斯的判断是通过概率,所以有可能误判。但由于其处理快速、简单,依然是分类算法的首选。
- 朴素贝叶斯的"朴素"这个名是因为假设了各个特征值没有联系,现实中的特征值很多时候是关联的,这时可以用TAN、ARCS算法分类。
(3) 黑名单
对于一些确定喜欢发一些垃圾信息、有害信息的用户,可以根据ip
,用户名建立一个黑名单,某段时间内禁止其发信息。
- Hash表实现:简单、查找复杂度小,但是黑名单很多时会占用不少内存。
- 布隆过滤器:如果对于过滤精确度要求没那么高,黑名单又有很多时可以用。申请一块大内存作为bit数组,对于一个目标A,决定要将A加入黑名单时对A进行一个算法运算得到8个随机数,将以这8个随机数为下标的bit置为1。判断A是否为黑名单时,就检查他运算出的8个随机数为下标的bit数组是否全为1,是则认为A是黑名单。这种有误判,但是概率很小。