[有书共享]JavaWeb高级编程
JavaWeb高级编程 -- 篇5
使用会话维持状态
HTTP请求自身是完全无状态的。从服务器的角度来说,当用户的Web浏览器打开第一个连接到服务器的套接字时请求就开始了,直到服务器返回最后一个数据包关闭连接时,该请求结束。此时,在用户的浏览器和服务器之间不再有任何联系,当下一个连接开始时,无法将新的请求与之前的请求关联起来。
使用会话可以:
- 维持请求和请求之间的状态
- 记住用户
- 启动应用程序的工作流
在Web会话理论中,会话是由服务器或Web应用程序管理的某些文件、内存片段、对象或者容器,它包含了分配给它的各种不同的数据。用户浏览器中不需要保持或维持任何此类数据。它们只有服务器或Web应用程序代码管理。容器和用户浏览器之间将通过某种方式连接起来。处于此原因,通常会话将被赋予一个随机生成的字符串,成为会话ID。第一次创建会话时,创建的会话ID将会作为响应的一部分返回到用户浏览器中。接下来从该用户浏览器中发出的请求都将通过某种方式包含该会话ID。当应用程序收到含有会话ID的请求时,它可以通过该ID将现有会话与当前请求关联起来。
其中需要注意的是如何将会话ID从服务器返回到浏览器中,并在之后的请求中包含该ID。目前有两种技术用于完成该任务:会话cookie和URL重写。
HTTP 1.1中给出解决方案:HTTP cookie。
cookie是一种必要的通信机制,可以通过Set-Cookie响应头在服务器和浏览器之间传递任意数据,并存储在用户计算机中,然后再通过请求头Cookie从浏览器返回到服务器。cookie可以有各种不同的特性:
Domain将告诉浏览器应该将cookie发送到哪个域名中
Path进一步将cookie限制在相对于域的某个特定URL中。每次浏览器发出请求时,它都将找到匹配该域和路径的所有cookie,然后将cookie随着请求一起发送到服务器。
Expires定义了cookie的绝对过期日期
Max-Age定义了cookie在过期之前所需的秒数
Secure表示浏览器将只会通过HTTPS发送cookie
HTTPOnly将把cookie限制在浏览器请求中,这样其他技术如:JavaScript和Flash将无法访问cookie。
在Java EE应用服务器中,会话cookie的名字默认为JSESSIONID。
另一种传输会话ID的流行方式是通过URL。Web或应用服务器知道如何查找URL中包含了会话ID的特定模式,如果找到了,就从URL中获得会话。
不同的技术对如何在URL中内嵌和定位会话ID使用不同的策略:
PHP,使用名为PHPSESSID的查询参数:
http://www.example.com/support?PHPSESSID=xxxxxxx&foo=bar
Java,使用矩阵参数:
http://www.exaple.com/support;JSESSIONID=xxxxxxx?foo=bar
当使用这种方法的时候,必须将会话ID内嵌在应用程序返回的所有URL中,包括页面的链接、表单操作以及302重定向。
会话是存在漏洞的,在执行重要任务、含有敏感数据的应用程序中,使用某些商业的扫描器检测应用程序中的漏洞是更加明智的选择。
会话漏洞及解决方案:
- 复制并粘贴错误
漏洞:用户复制并粘贴地址栏中的URL
方案:完全禁止在URL中内嵌会话ID - 会话固定:
攻击者可能会首先找到一些允许在URL中内嵌会话ID的网站。通过此种方式获得一个会话,然后将含有会话ID的URL发送给目标用户,此时,如果用户点击链接进入网站,它的会话ID就变成了URL中含有的固定ID--攻击者已经持有该ID。如果用户接着在该会话期间登录网站,那么攻击者也可以登录成功,因为这个会话ID是他共享的。
解决方案:- 禁止在URL中内嵌会话ID
- 在登录后采用会话迁移
- 跨站脚本和会话劫持
漏洞:使用JavaScript读取会话cookie的内容
解决方案:- 不要在网站中使用跨站脚本
- 在所有的cookie中使用HttpOnly特性
- 不安全的cookie
中间人攻击(MitM攻击),典型的如:数据截获攻击
解决方案:使用HTTPS保护网络通信将有效地防止MitM攻击,并保护会话ID cookie不被盗用。不过用户可能首先使用HTTP访问网站,即使立刻将请求进行重定向到HTTPS,攻击可能已经发生了。使用cookie的Secure标志可以解决此问题。
在许多情况下,都可以在Java EE中直接使用HTTP会话,不需要显式的配置,不过可以在部署描述符中配置它们,并且处于安全的目的也应该配置。在部署描述符中使用<session-config>标签配置会话。
所有在<session-config>和<cookie-config>中的标签都是可选的,但是如果选择了这些标签就要按照如下顺序添加到部署描述符中:
<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<name>JSESSIONID</name>
<domain>example.org</domain>
<path>/shop</path>
<comment><![CDATA[example]]</comment>
<http-only>true</http-only>
<secure>false</secure>
<max-age>1800</max-age>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
<tracking-mode>URL</tracking-mode>
<tracking-mode>SSL</tracking-mode>
<session-config>
#Java##读书笔记#