赞
踩
本文主要参考自《大型网站技术架构:核心原理与案例分析》一书第八章节和其他网络文章,如有遗漏或错误,还望海涵并指出。谢谢!
这个世界没有绝对的安全,正如没有绝对的自由一样。网站的相对安全是通过提高攻击门槛达到的。让攻击者为了获得有限的利益必须付出更大的代价,导致其得不偿失,望而却步。
–《大型网站技术架构:核心原理与案例分析》
DDos攻击中文名为分布式拒绝服务攻击,这种攻击技术的核心在于使用分布式的服务器,伪造大量请求发送到目标服务器上,使目标服务器充斥大量要求回复的信息,消耗网络带宽或系统资源,导致网络或系统不胜负荷以至于瘫痪而停止提供正常的网络服务。
为了防止DDos攻击带来的影响,一般可以采取以下措施:
Cross-Site Scripting(跨站脚本攻击)简称 XSS,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。
假设有一个搜索页面,根据 URL 参数决定关键词的内容。代码如下:
<input type="text" value="<%= getParameter("keyword") %>">
<button>搜索</button>
<div>
您搜索的关键词是:<%= getParameter("keyword") %>
</div>
这时,如果将keyword设置为"><script>alert('XSS');</script>
,
发送如下HTTP Get请求到服务器中:
http://xxx/search?keyword="><script>alert('XSS');</script>
那么在下次获取这个keyword时,浏览器会将"><script>alert('XSS');</script>
作为响应的参数填充到HTML页面:
<input type="text" value=""><script>alert('XSS');</script>">
<button>搜索</button>
<div>
您搜索的关键词是:"><script>alert('XSS');</script>
</div>
浏览器无法分辨出<script>alert('XSS');</script>
是恶意代码,因而将其执行。会在用户浏览器上输出XSS字样。
这是一个最经典的XSS攻击的例子,一般来说,XSS攻击可以分为以下两类:
1.持久型攻击
黑客将XSS脚本提交到被攻击服务器上,然后再被取出时渲染到浏览器中,如上面的例子一样,这种攻击经常出现在Web博客或论坛中。
2.反射型攻击
反射型XSS的恶意脚本存在URL里。
反射型XSS漏洞常见于通过URL传递参数的功能,如网站搜索、跳转等。
由于需要用户主动打开恶意的URL, 才能生效,攻击者往往会结合多种手段诱导用户点击。然后URL会获取到恶意脚本,并渲染到服务器中执行。
对于XSS攻击来说,防范措施主要有一下几种:
1.输入过滤
前端和后端方面对输入参数做过滤,例如<…这样的参数中的<和>进行转义处理。
2.纯前端渲染
在纯前端渲染中,我们会明确的告诉浏览器:下面要设置的内容是文本(.innerText),还是属性(.setAttribute),还是样式(.style)等等。浏览器不会被轻易的被欺骗,执行预期外的代码了。
SQL注入攻击是最常见的一种Web攻击方式了,如果不加以防范,那么可能会导致整个数据库的崩溃,以导致不能够对外提供服务。
一个简单的SQL注入例子:无视密码登录
假设前端有一个登陆页面,登录时只需要username
和password
,后端判断是否可以登陆的SQL语句为:
select count(*) from user_table where username = ? and password = ?
如果可以查询得到记录,那么说明用户账号和密码都是正确的,但是,假设我们输入一下username和password:
username = 'ARong';#
password = 'SQL注入'
那么后端接收到参数进行拼接会得到以下SQL
select count(*) from user_table where username = 'ARong';# and password = 'SQL注入'
可以看出,这条SQL语句的password条件实质上是被注释掉了,只要存在这条用户名就可以登陆成功了。
如果知道用户表的名字(例如一些报错信息提示),更狠一些,把条件改成:
username = 'ARong';drop table user_table;#
password = 'SQL注入'
那么这条SQL会被拼接成:
select count(*) from user_table where username = 'ARong';drop table user_table;# and password = 'SQL注入'
这就会造成用户表数据与结构被删除!最可怕的是,如果不存在备份的话,drop语句本身是DDL语句,并不会被日志所记录下来,那么也无法就行恢复。
防止SQL注入攻击的方法是做参数的预处理,例如JDBC中就有PreparedStatement类来对参数进行包装和教研,MyBatis中也可以使用${}来替换掉#{},以达到预处理避免SQL注入的效果,如果使用了预处理,那么上面的SQL会变为:
select count(*) from user_table where username = "'ARong';drop table user_table;#" and password = "'SQL注入'";
通过对参数两端加上引号的方式就可以避免SQL的参数成为SQL语句的一部分了。
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。
CSRF攻击的核心思路是盗用你的身份(Cookie和Session),以你的名义发送恶意请求。
1.验证HTTP Referer字段
根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址。在通常情况下,访问一个安全受限页面的请求来自于同一个网站。
2.请求中附加Token
由于CSRF攻击是通过复用Cookie和Session来达到伪造请求的目的的,那么可以在每次请求中都添加Token,并且后端接收到请求后要对Token进行校验以确保请求确实是来自客户,这样也能防止CSRF攻击。
3.验证码
在一些关键的操作上,用户必须通过验证码的方式去验证才能发送请求,这样就避免了伪造的请求被自动提交。
单向散列加密指的是对不同长度的信息通过散列计算,以获取到相同长度的输出。
由于散列函数的单向性,对同一个数据的加密都会生成同一数据,但却无法通过被加密后的数据逆向生成原数据。
应用这种技术的加密算法有MD5和SHA。
在使用单向散列加密技术,即使原数据发生了微小的变动,也会导致生成的加密数据产生很大的不同,所以单向散列加密技术又可用作信息摘要判断。
由于单向散列加密具有不可逆性,所以通常可以用来加密用户密码、银行卡密码等私密数据,以生成无法被逆向的密文。当用户登录时,可以将输入的数据做一次相同的单向散列加密,然后通过对比即可知道用户输入是否正确。这样做还有一个很重要的原因是假如发生了数据泄露,也不会将这些私密的数据暴露出来。
注意,单向散列加密技术并不是完全不可逆的。通过大数据量的收集和分析,可以构建出【彩虹表】,用彩虹表可以获取到相对简单的密文对应的原数据。
所谓对称加密,指的是可以通过同一个密钥对数据进行加密与解密。
对称加密的优点在于加密与解密效率高,适合用于大量数据的加密与解密。缺点是由于加密与解密使用的都是同一个密钥,那么如何保证密钥不被泄漏和窃取是重中之重,如果密钥泄漏了,那么数据也就没有私密可言。
常用的对称加密算法有AES、DES等。
一般情况下需要数据加密的场合都可以使用对称加密的方式。
非对称加密的特点是加密与解密使用的是不同的密钥,其中对外界开放的密钥称为公钥,另一个密钥只有所有者拥有,被称为私钥。
被公钥加密的数据只能由私钥解开,而被私钥加密的数据只能由公钥解开。并且外界不能够通过公钥来推算出密钥,不然整个加密过程也毫无意义。
非对称加密的加密和解密效率较低,但是由于分开了公钥与私钥,所以安全性会高一些,适合于少量私密数据(如传输的就是密钥)的安全传输。
非对称加密的两个使用场景:
1.客户端向服务端的信息安全传输:
当客户端向服务端传输数据时,使用公钥加密数据,服务端接收到数据时,采用私钥解密数据。这样即使数据在传输的过程中被拦截,也因为没有私钥而无法获取原数据。
2.服务端向客户端发送数字签名
当服务端向客户端发送经过私钥加密的数据时,由于私钥只存在一个并且不可被其他人知道,所以这个数据是不可抵赖、不可伪造的,客户端可以用公钥将其解密,这样就具有了签名的作用。
常用的非对称加密算法有RSA算法等。
无论是对于单向散列加密、对称加密或非对称加密,一旦加密与解密使用的密钥被窃取,那么加密过程就会完全失效了,这时的做法是对密钥进行管理,以防止密钥被窃取。
以下密钥管理的等级由低级升为高级,并且安全性越来越高:
1.密钥硬编码在程序代码中
这是最常见也是最不安全的做法,一旦获取到源文件,那么密钥就会被获取道。并且当要更换密钥时,需要修改硬编码的代码。
2.从配置文件中获取密钥
这种做法的安全性也很低,不过相对于硬编码来说,使用配置文件能够便于更换密钥。
3.将密钥单独存放在特殊的服务器中
这种做法可以大幅提高密钥的安全性,密钥被存放在特定的服务器上,并且服务器只对特定的服务器提供密钥获取服务,这样就可以很大程度上防止密钥被窃取的问题。
4.将密钥分片加密存储
将密钥存储在服务器上时,还是有可能被被黑客登入服务器直接将其获取,那么此时可以将密钥分片,并且每一片都单独加密,然后存储在不同的数据库或文件系统中,当要获取密钥时需要将所有的密钥分片都获取到,并且经过特定的加密过程以组合成完整的密钥。
一次HTTPS请求的过程就包含了各种加密技术,例如下面的图示:
Key = 公钥 【非对称加密】 随机值 = 私钥 【解密】 随机值
随机值 【对称加密】报文 = 随机值 【对称解密】密文
HTTPS中,使用非对称加密是为了保证【随机值】的安全性,确保这个随机值不会被窃取,随后由于对称加密的性能更高,所以会以这个随机值作为对称加密的共同密钥。
文本匹配是最常见的信息过滤技术,通常有两种实现:
1.双数组TrieTree
由于TrieTree这种数据结构具有天然的字符串匹配的特性,能够大大地提高字符串匹配的效率,所以文本匹配计数通常会基于前缀树或双数组前缀树的来做文本匹配。
2.多级Hashtable
可以使用多级Hashtable来构建匹配树来过滤较少的关键词,由于使用了多级哈希表,所以占用的空间比双数组TrieTree多很多。
对于少量的数据,例如用户发帖中言论出现色情、暴力等问题,这样的情况下可以由人工来进行筛选。但是若数据量很大,例如每天有数以亿记的短信在发送,怎么做到对垃圾短信的筛选与拦截呢。
这时用的方法就是利用机器学习,培养分类算法,让分类算法自动去完成垃圾信息的匹配和拦截:
目前比较常用的分类算法是贝叶斯分类算法。本身贝叶斯算法可以解决的经典概率问题就是条件概率的问题,例如从两箱红球与白球中取出一个白球,这个白球来自第一个箱子的概率是多少?
根据贝叶斯公式,设这个球来自第一个箱子的概率为P(A),球是白球的概率为P(B)、,那么这个概率可以表示为:
P(A | B) = P(AB) / P(B) = P(A) * P(B | A) / P(AB)
所以根据贝叶斯分类算法可以从概率论的角度来筛选出符合条件的垃圾信息,但是会存在一定的误判率。
对于已经被投诉的用户,我们可以将它的IP地址或账户名存储在黑名单中,当下次短信中存在该用户的IP地址,我们就可以将其拦截。
黑名单可以使用哈希表来实现,但是当IP地址过多,例如有10亿个IP地址需要放入黑名单,那么用哈希表会占用大量的空间,并且产生大量的哈希冲突,此时的做法是采用布隆过滤器来来存储黑名单数据,可以大大地减少空间的使用。但是需要注意的是,随着布隆过滤器底层数组的大小变化,其误判率也会发生变化。布隆过滤器可以精确判断【不存在】这种情况,而对于【存在】这种情况是存在误判的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。