1.1 XSS
1.2 CSRF
1.3 同源策略
1.4 跨域访问
1.4 cookie的安全性
2.1 token和session,两种认证方式
2.2 存token的解决方案
Cross Site Scripting, 简称XSS (跨站脚本攻击)。
参考:百度百科
解释: XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。 这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。
原理: HTML是一种超文本标记语言,通过将一些字符特殊地对待来区别文本和标记,例如,小于符号(<)被看作是HTML标签的开始,与之间的字符是页面的标题等等。当动态页面中插入的内容含有这些特殊字符(如<)时,用户浏览器会将其误认为是插入了HTML标签,当这些HTML标签引入了一段JavaScript脚本时,这些脚本程序就将会在用户浏览器中执行。所以,当这些特殊字符不能被动态页面检查或检查出现失误时,就将会产生XSS漏洞。
我的总结:
使用httpOnly的cookie 可以避免cookie受到XSS攻击,而没有使用httpOnly的cookie和Web Storage则容易受到XSS攻击。使用了httpOnly的cookie是js无法访问控制的(document.cookie是获取不到的),而Web Storage(例如localStorage)是可以被js访问控制的,所以从这一点来看cookie相较于Web Storage更加安全。
Cross-site request forgery, 简称CSRF或XSRF (跨站请求伪造)。
参考:百度百科,[写bug博客]https://segmentfault.com/a/1190000015597029
解释:CSRF 是一种挟制用户在当前已登录的Web应用上执行非本意的操作的攻击方法。跟XSS相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对浏览器的信任
原理:我们都知道,当我们访问一个网站或向它发出请求时,浏览器会自动携带cookie,假如cookie中保存了登录状态信息,请看下面的例子:
1.你登录了A银行网站,用一个账号名称为Jacy的账号进行了转账操作,URL是:http://www.examplebank.com/withdraw?account=Jacy&amount=1000&for=SomeBody
2.在你还未退出A银行网站,即保存在cookie中的登录信息有效情况下,你访问了B网站,若这个B网站放入了恶意js代码:http://www.examplebank.com/withdraw?account=Jacy&amount=1000&for=Badman。 B网站在你浏览网站时在背后发送了这个请求,此时浏览器会把带有A网站登录信息的cookie发送给A银行系统,A银行系统会判断cookie认为你是登录/认证的用户,就会执行转账操作,那么你的Jacy账号将损失1000元。
我的总结:
从CSRF来看,cookie是不安全的,但现在浏览器都具备同源策略,所以这种跨域的请求就会被拒绝。若使用token认证技术并将token存在localStorage中,每次请求时从localStorage中取出token放在请求头中,则可以有效避免CSRF。所以从这一点来看localStorage的策略比cookie更安全
站点A的域名:www.aaa.com,站点B的域名:www.bbb.com。
假设前端网页是部署在A上,服务端是部署在站点B上。 现在我要从A用ajax给B发请求,这个时候B会拒绝A的请求,这个就是浏览器的同源策略。同源策略是一种保护机制,保护用户不受CSRF攻击。
那么问题来了,假如我的项目时前后端分离,那么我该怎么部署或者说怎么消除同源策略的限制?请看下面的跨域访问
这个可以参考我的另一篇博客:[待完成]
参考博客:
[阮一峰CORS] https://www.ruanyifeng.com/blog/2016/04/cors.html
[如何设置Access-Control-Allow-Origin] https://www.jianshu.com/p/89a377c52b48
服务端设置响应头:
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Credentials: true
前端ajax设置请求头:withCredentials : true
参考文章
[cookie详解]https://zh.javascript.info/cookie
[同源策略、跨域和cookie的安全性]https://segmentfault.com/a/1190000015597029
后端操作cookie和session, 采用session认证技术
JSON Web Token (JWT)是一个开放标准(RFC 7519),简单讲jwt是一项技术规范,遵循这个规范可以生成一个token,token本质就是一串字符,例如:
这是一个很长的字符串,中间有.
隔开,表示token是由3部分组成。(注:token字符串是不换行的,上述例子仅为了方面展示才换行显示)
这个token包含了用户的登录信息(包含用户id等,注:敏感信息是非常不建议放token里的)。客户端登录后就能拿到token,之后需要认证的请求都可以带上token发请求,服务端拿到带token的请求后验证token的正确性并判断是哪个用户。session技术是将登录信息放在服务端(服务端有状态),而token技术是将登录信息放在客户端(也就是服务端是无状态的)。
关于jwt详细分析,可以参考阮老师的博客 https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
我认为相较于session认证,token技术的优缺点:
优点:
缺点:
下面的问题值得讨论:客户端的token存哪里?
1.用localStorage存token
2.用cookie存token
如果是前端自己手动将cookie存token,那么问题和上面用localStorage是一样的。但是,如果是将cookie交给服务端管理,前端不能操作cookie,那么会更加安全。
参考博客:
http://blog.itpub.net/10742815/viewspace-2142725/
https://segmentfault.com/q/1010000022581000
在Web服务应用中,后端通过Set-cookie把token放在cookie中,对cookie设置httpOnly(使js不能访问cookie)。这样做也就是把token交给服务端维护,前端不用管。
我的观点:
一个完善的后端,包含了对Web网页和APP应用提供API,此时后端应该把token放在两处,当用户登录成功后,一方面通过Set-cookie设置token(供Web网页使用),另一方面在返回的json数据中放置token字段(供APP应用使用)。
1)Web服务可以采用上述的方案。
2)但在APP中则有些不同:对APP来说用户的登录状态维持时间应该更长,此时需要两个token,一个是认证用的auth_token,另一个是刷新token的refresh_token (名字不是固定的,表意即可)
APP把两个token保存在本地,每次请求需要取auth_token放置到请求头,当token失效时APP需要取refresh_token去刷新从而获得新的auth_token。其中refresh_token的有效期要比auth_token长,假设auth_token有效期是7天,则可以将refresh_token的有效期设置为14天(token的有效期也不易过长)。