Cookies
Cookie的由来:
HTTP 本身是一个无状态的 request/response 协议. server接收一个来自client的request, 处理完以后返回一个response。 可是这个过程中, server差点儿没有什么信息能够用来判定是哪个client(用户)发来的request, 也无法记录用户的请求顺序. Cookie是眼下识别用户。实现持久会话最好的方式。Cookie通常会跟User-Agent。Referer。X-Forwarded-For,JS等技术共同使用,为server提供更为详细的信息。简而言之,cookie就是server为了记录用户信息而给client生成的特定信息。而且保存在client,下次发送request时携带的一个信息。
Cookie的创建
首次訪问的时候server会在返回的信息头中放入set-cookietaobao中。client可能有不同的屏幕尺寸,我们会尽可能的去适应client屏幕,不同的分辨率、长宽比。给不同比例尺寸的图片。
这时,我们就须要client主动的告诉我们它的信息。在chrome里面我们能看到这样一个cookie的值。
_med參数就是表面屏幕尺寸的 html页面里面的一段javascript。当用户首次訪问taobao主站时。它并不会携带这个信息,此时server能够通过发现_med来推断client是否携带了这个cookie,假设发现没有携带。那么就会在响应的html页面中添加一段javascript
Session
保存在server端的client标志。生成过程:
1. 生成全局唯一标识符(sessionid) 2. 开辟数据存储空间。 通常会在内存中创建对应的数据结构,但这种情况下。系统一旦掉电。全部的会话数据就会丢失,假设是电子商务站点,这种事故会造成严重的后果。只是也能够写到文件中甚至存储在数据库中,这样尽管会添加I/O开销,但session能够实现某种程度的持久化,而且更有利于session的共享;
3. 将session的全局唯一标示符发送给client。 问题的关键就在服务端怎样发送这个session的唯一标识上。联系到HTTP协议,数据无非能够放到请求行、头域或Body里,基于此,一般来说会有两种经常使用的方式:cookie和URL重写。 4. 服务端仅仅要设置Set-cookie头就能够将session的标识符传送到client,而client此后的每一次请求都会带上这个标识符,因为cookie能够设置失效时间,所以一般包括session信息的cookie会设置失效时间为0,即浏览器进程有效时间。至于浏览器怎么处理这个0,每一个浏览器都有自己的方案。但区别都不会太大(一般体如今新建浏览器窗体的时候); 5. URL重写 所谓URL重写,顾名思义就是重写URL。试想,在返回用户请求的页面之前,将页面内全部的URL后面全部以get參数的方式加上session标识符(或者加在path info部分等等)。这样用户在收到响应之后。不管点击哪个链接或提交表单。都会在再带上session的标识符。从而就实现了会话的保持。读者可能会认为这种做法比較麻烦。确实是这样。可是,假设client禁用了cookie的话,URL重写将会是首选。Session的数据结构的要求:同步、易操作。因此使用ConcurrentHashMap来存放。
Application:
验证码问题,訪问/login,同一时候訪问了验证码生成页面/codeimage。此时的Session[‘codeimage’]=此时生成的验证码。要是刷新一下,serverSession存储就变成新的了。
session劫持
server生成的用以标识客户信息的cookie一般被称为sessionId,而通过一些手段获取其他用户sessionId的攻击就叫session劫持。
1)在cookie中。保存三个东西——username。登录序列,登录token。
username:明文存放。
登录序列:一个被MD5散列过的随机数,仅当强制用户输入口令时更新(如:用户修改了口令)。 登录token:一个被MD5散列过的随机数,仅一个登录session内有效,新的登录session会更新它。2)上述三个东西会存在server上。server的验证用户须要验证clientcookie里的这三个事。
3)这种设计会有什么样的效果,会有以下的效果。
a)登录token是单实例登录。意思就是一个用户仅仅能有一个登录实例。
b)登录序列是用来做盗用行为检測的。
假设用户的cookie被盗后。盗用者使用这个cookie訪问站点时。我们的系统是以为是合法用户。然后更新“登录token”,而真正的用户回来訪问时,系统发现仅仅有“username”和“登录序列”同样,可是“登录token” 不正确,这种话。系统就知道,这个用户可能出现了被盗用的情况。于是,系统能够清除并更改登录序列 和 登录token,这样就能够令全部的cookie失效,并要求用户输入口令。并给警告用户系统安全。
4)当然。上述这种设计还是会有一些问题,比方:同一用户的不同设备登录,甚至在同一个设备上使用不同的浏览器保登录。一个设备会让还有一个设备的登录token和登录序列失效。从而让其他设备和浏览器须要又一次登录,并会造成cookie被盗用的假象。所以。你在server服还须要考虑- IP 地址
XSS防范:
1. 过滤用户输入。防止XSS漏洞 2. 设置sessionId的cookie为HttpOnly(使jsclient无法获取)Token
Token,就是令牌。最大的特点就是随机性。不可预測。一般黑客或软件无法推測出来。 Token一般用在两个地方:
- 防止表单反复提交、
- anti csrf攻击(跨站点请求伪造)。 明白这个需求是,攻击者伪造链接/表单给用户目的是让server推断这个链接/表单不是正常产生的 两者在原理上都是通过session token来实现的。当client请求页面时。server会生成一个随机数Token,而且将Token放置到session其中,然后将Token发给client(一般通过构造hidden表单)。
下次client提交请求时,Token会随着表单一起提交到server端。
然后,假设应用于“anti csrf攻击”,则server端会对Token值进行验证。推断是否和session中的Token值相等,若相等,则能够证明请求有效,不是伪造的。只是。假设应用于“防止表单反复提交”。server端第一次验证同样过后。会将session中的Token值更新下。若用户反复提交,第二次的验证推断将失败,因为用户提交的表单中的Token没变,但server端session中Token已经改变了。
上面的session应用相对安全,但也叫繁琐,同一时候当多页面多请求时,必须採用多Token同一时候生成的方法,这样占用很多其他资源,运行效率会减少。因此,也可用cookie存储验证信息的方法来取代session Token。
比方。应对“反复提交”时。当第一次提交后便把已经提交的信息写到cookie中,当第二次提交时,因为cookie已经有提交记录。因此第二次提交会失败。
只是,cookie存储有个致命弱点,假设cookie被劫持(xss攻击非常easy得到用户cookie),那么又一次gameover。黑客将直接实现csrf攻击。所以。安全和高效相对的。
详细问题详细对待吧。
此外,要避免“加token但不进行校验”的情况,在session中添加了token,但服务端没有对token进行验证,根本起不到防范的作用。
还需注意的是。对数据库有修改的增删改操作,须要加token验证,对于查询操作,一定不要加token。防止攻击者通过查询操作获取token进行csrf攻击。
但并非这样攻击者就无法获得token,仅仅是增大攻击成本而已。