保护你的会话令牌
通常我们会采取以下的措施来保护会话。
1.采用强算法生成Session ID
正如我们前面用Web Scrab分析的那样,会话ID必须具有随机性和不可预测性。一般来说,会话ID的长度至少为128位。下面我们就拿常见的应用服务器Tomcat来说明如何配置会话ID的长度和生成算法。
首先我们找到{TOMCAT_HOME}\conf\context.xml,然后加入下面一段设置
<Manager sessionIdLength="20" ➊
secureRandomAlgorithm="SHA1PRNG" ➋
secureRandomClass="java.security.SecureRandom" ➌
/>
➊ 定义会话ID 的长度,如果我们这里不声明的话,默认是16字节。可能有读者会纳闷,怎么平时我看到的会话ID都是很长的呀?我们就拿这里的20个字节来讲吧,我们在浏览器发送请求时会发现这样的会话ID:
JSESSIONID=90503B6BE403D4AB6164A311E167CF1F6F3F2BD0
仔细看会发现ID的长度为40,因为这里显示的是十六进制,每两个字符代表一个字节。
➋ 定义随机数算法,默认的是SHA1PRNG,你也可以换成自己的算法。
➌ 定义随机数类,默认的是java.security.SecureRandom,我们也可以继承这个类来实现自己的算法。
有一点要注意,就是我们在实现自己的随机数算法时,一定要保证生成的Session ID不能有重复,这里我们参考一下Tomcat实现的机制。
/**
* Generate and return a new session identifier.
*/
protected StringgenerateSessionId() {
String result = null;
do {
if (result != null) {
duplicates++;
}
result = sessionIdGenerator.generateSessionId();
} while (sessions.containsKey(result));
return result;
}
由此可见,Tomcat是不会产生两个相同的会话ID的。
2.软硬兼施,会话过期
会话过期是应用程序的一项重要的安全控制,它定义了用户在多长时间段内不用重新登录而仍然维持一个登录状态。一般来说,有两种会话过期——软会话过期(Soft Session Timeout)和硬会话过期(Hard Session Timeout)。
软会话过期,它指的是用户在一定的时间内与应用系统没有交互,则会话过期。举一个简单的例子就是,一个用户登录了一个应用系统,他临时离开了计算机40分钟,而应用系统设置的会话过期时间为30分钟,这时候用户回到计算机前再做任何操作,系统都会重定向为登录页面让用户重新输入用户名和密码。
那么,软会话过期有什么用呢?我们知道在CSRF攻击中一个最基本的假设就是合法用户处在一个登录状态中,如果我们设置了一个合理的且较低的会话过期时间,就提高了实施CSRF攻击的难度,从而保护了系统。
通常有3种办法来设定软会话过期,其级别由高到低依次为:Tomcat级别> Web应用级别>Servlet运行时context级别,这时候低级别的设定会覆盖高级别的设定。
a.Tomcat级别的设定。
若你需要设定30分钟的会话过期,你可以在{TOMCAT_HOME}\conf\web.xml中进行设定如下:
<session-config>
<session-timeout>30</session-timeout><!-- set in minutes -->
</session-config>
b.Web应用级别的设定。
若你需要设定15分钟的会话过期,你可以在{TOMCAT_HOME}\webapps\ {APP_NAME}\WEB-INF\web.xml中这样进行设定:
<session-config>
<session-timeout>15</session-timeout><!-- set in minutes -->
</session-config>
c.在程序代码中进行设定。
若你需要在程序中设定5分钟的会话过期,你可以用下面一行代码来实现:
httpSession.setMaxInactiveInterval(5*60); // set in seconds
如果我们按照上面的步骤进行了会话过期设置,那么最后真正起作用的是在程序中进行设定的5分钟。
再看什么是硬会话过期。它指的是用户登录到系统中经过一定的时间后,不管用户做什么,该会话都会过期。大家都知道网络游戏防沉迷系统吧?如果未成年人的累计在线时间已满5小时,则累计在线时间清零,这个与我们这里说的硬会话过期很相似,只不过我们这里不是在线时间清零,而是强制用户退出并重新登录。
那么硬会话过期有什么用呢?它主要是用来防止永久的对一个账号劫持。比如说一个攻击者通过XSS得到了受害者的session,并用它冒充受害者进行登录,如果我们设定了硬会话过期,则经过了一段时间之后,系统会强制用户重新进行认证。
没有专门的API或者配置来设定硬会话过期,但我们可以通过在web filter中写自己的代码来实现这个功能。基本思路如下:对每个用户登录成功后记录下此时的时间,并且把这个时间与他们的Session ID绑定起来,如果用同一个Session ID发送的请求的时间减去这个Session ID刚登录成功的时间大于了我们设定的会话过期时间,则使这个会话无效,并重定向到登录页面。
3.保护你的Cookie
Cookie有两个很重要的属性:secure和HttpOnly,设置好这两个属性对于保护你的Cookie至关重要。
首先说secure属性。声明了它,则说明当前这个Cookie只会在HTTPS的链接中进行传递,这样就可以使得攻击者无法很容易地通过分析网络流量来获得会话ID,从而有效地防治了中间人攻击(Man-in-the-Middle)。
HttpOnly这个属性我们在XSS这一章已经介绍过,它不允许一些脚本(如JavaScript等)直接操作document.cookie这个DOM对象,这个属性对于阻止通过XSS窃取会话ID是必需的。
一个好消息是,Tomcat 7支持了Servlet 3.0,所以我们可以在web.xml设定上面的两个属性。
<session-config>
<cookie-config>
<secure>true</secure>
</cookie-config>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
</session-config>
需要注意的是Tomcat 6以前的版本不支持,Tomcat 6支持的是Servlet 2.5。
4.提供logout功能
上面介绍的是系统自动按照设定的时间使会话过期,一个好的应用程序应该提供一个功能,即用户可以手动地使当前会话过期,这就是我们在几乎所有网站上都看到的logout按钮。那么一般的logout需要完成哪些功能呢?让我们看看ESAPI中是如何实现logout功能的吧。
Class: org.owasp.esapi.reference.DefaultUser
public void logout() {
ESAPI.httpUtilities().killCookie( ESAPI.currentRequest(),
ESAPI.currentResponse(),
HTTPUtilities.REMEMBER_TOKEN_COOKIE_NAME );➊
HttpSession session = ESAPI.currentRequest().getSession(false);
if (session != null) {
removeSession(session);
session.invalidate();➋
}
ESAPI.httpUtilities().killCookie(ESAPI.currentRequest(),
ESAPI.currentResponse(),
"JSESSIONID");➌
loggedIn = false;
logger.info(Logger.SECURITY_SUCCESS, "Logout successful" );
ESAPI.authenticator().setCurrentUser(User.ANONYMOUS);
}
killCookie的实现代码如下:
public void killCookie(HttpServletRequest request, HttpServletResponse response, String name) {
String path = "//";
String domain="";
Cookie cookie = getFirstCookie(request, name);
if ( cookie != null ) {
path = cookie.getPath();
domain = cookie.getDomain();
}
Cookie deleter = new Cookie( name, "deleted" );
deleter.setMaxAge( 0 );➍
if ( domain != null ) deleter.setDomain( domain );
if ( path != null ) deleter.setPath( path );
response.addCookie( deleter );
}
我们简单地分析一下上面的代码:
➊ 的作用是清除remember me这个Cookie,这是针对网站有remember这个功能来说的。
➋ 是使得当前的会话无效,这样即使当前的会话ID泄露出去了,攻击者也无法用这个会话ID进行登录。
➌ 的作用是清除JSESSIONID这个Cookie。
➍ 使deleter(与传递进来的Cookie同名)立即无效。
本文节选自《Web应用安全威胁与防治——基于OWASP Top 10与ESAPI》
王文君 李建蒙编著
电子工业出版社出版
相关推荐
首先,令牌的可预测性测试涉及生成并截获大量会话令牌。这可以通过模拟用户登录或触发服务器生成新令牌的请求来实现。例如,一个成功的登录请求可能会导致服务器返回一个新的会话ID或令牌。将这些令牌收集并分析,...
在网络安全领域,保护用户的会话令牌至关重要,因为这些令牌通常用于验证用户的身份并授权他们在应用程序中的操作。"检查在日志中泄露的令牌"是一项关键的安全审计任务,旨在确保敏感信息不会因不当的日志记录而暴露...
首先,会话令牌是应用程序用来标识用户会话的一种手段,它通常在用户成功登录后生成,并在后续请求中作为身份凭证传递。这些令牌可能存储在HTTP cookies、URL参数、POST数据或其他地方。 1. **通信协议的选择**:...
通过获取一个有效的令牌,不使用它并在一段时间后尝试使用该令牌访问受保护资源,如果服务器仍允许访问,说明会话超时机制存在问题。利用工具如Burp Intruder设置不同时间间隔的连续请求,可以探测出服务器的会话超...
`IdentityserverSQL`表明数据库中存储了这些令牌信息,可能包括刷新令牌和相关用户的会话信息。 4. **SQLSERVER 集成** 本项目使用`SQLSERVER`作为持久化存储,存储用户账户、客户端定义、令牌等信息。这是对默认...
6. 通用数据类型:标准中定义了一系列通用数据类型,这些类型为与密码令牌交互提供了必要的数据结构,包括版本信息、令牌信息、会话信息、对象类型等。 7. 函数概述:PKCS#11标准包括了对一系列函数的定义和描述,...
通过以上步骤,我们就可以在Struts2应用中实现有效的令牌验证,保护用户免受CSRF攻击并防止重复提交。这个压缩包文件"token"很可能包含了完成以上步骤所需的示例代码,包括struts.xml配置文件、Action类、JSP页面等...
`token`拦截器负责在表单请求时生成和验证令牌,`tokenSession`则用于在用户会话中存储令牌,防止页面刷新时令牌丢失。 ```xml <!-- ... --> <!-- ... --> ``` 2. 在Action类中配置令牌 在需要令牌...
通过上述讲解,我们可以看出"第五章:会话及会话技术chapter05"主要涵盖了如何在JavaWeb环境中创建、管理和保护用户会话的关键概念和技术。在实践练习中,学生将有机会编写和调试涉及会话管理的代码,加深对这一重要...
1. **登录模块**:负责用户身份验证,通常涉及OAuth2.0或者腾讯特定的登录流程,获取到必要的访问令牌。 2. **会话建立**:根据QQ号查找并建立临时会话,这可能需要向服务器发送请求,获取会话ID或其他相关标识。 ...
客户端在后续的请求中携带这个令牌,服务器通过验证令牌来确认用户的身份,从而实现无状态的会话管理。 在这个项目中,Spring Security会被配置为使用JWT进行身份验证。首先,我们需要创建一个自定义的`...
标准中描述的会话是应用程序与令牌之间的交互过程,会话分为只读和读/写两种状态,并且不同类型的会话对访问对象有不同的权限限制。 会话在PKCS#11中扮演了非常重要的角色。例如,只有在读/写会话中才能创建、修改...
你可以为用户分配角色,然后为角色定义相应的权限。在访问控制时,Shiro 会检查用户的角色和权限,确保只有被授权的用户才能执行特定的操作。 3. **密码管理(Password Management)**: Shiro 提供了密码加密和...
首先,你需要创建一个ActionForm类,其中包含一个用于存储令牌的属性,如`private String token;` 并生成对应的getter和setter方法。 ```java public class MyForm extends ActionForm { private String token; ...
总的来说,Struts的令牌机制是防止重复提交的有效手段,通过在客户端和服务器之间传递和验证唯一的令牌,确保每个请求的唯一性,从而保护了应用程序的稳定性和数据的一致性。在实际开发中,合理运用这一机制可以提高...
6. **测试和调试**:编写测试用例来验证OAuth2流程,包括用户登录、获取访问令牌、使用令牌访问受保护资源等步骤。 7. **部署与监控**:最后,将应用部署到生产环境,并使用工具如Spring Actuator进行性能和健康...
本文分析了现有的处理方式的不足,讨论了如何通过基于会话的服务器令牌和基于请求的客户令牌,有效防止刷新处理,避免数据的重复提交。 一、表单提交数据的安全问题 在 Java Web 应用系统中,通过表单提交数据是一...
传统的单体应用中的会话管理方法不再适用,因为每个微服务都是独立的,没有共享的会话状态。因此,采用基于令牌的身份认证机制成为了一种解决方案。 令牌管理是这个过程的关键组成部分。JWT(JSON Web Token)是一...