您的位置:首页 > 编程语言 > Java开发

Spring Security如何防止会话固定攻击(session fixation attack)

2013-05-12 20:16 417 查看
Session fixation attack(会话固定攻击)是利用服务器的session不变机制,借他人之手获得认证和授权,然后冒充他人。如果应用程序在用户首次访问它时为每一名用户建立一个匿名会话,这时往往就会出现会话固定漏洞。然后,一旦用户登录,该会话即升级为通过验证的会话。最初,会话令牌并未被赋予任何访问权限,但在用户通过验证后,这个令牌也具有了该用户的访问权限。

防止会话固定攻击,可以在用户登录成功后重新创建一个session id,并将登录前的匿名会话强制失效。Spring Security默认即可防止会话固定攻击。具体实现方式[3.1版本]如下:HttpConfigurationBuilder的createSessionManagementFilters方法用于配置文件中的session-management属性,并根据配置创建SessionManagementFilter。其首先读取session-fixation-protection并存入sessionFixationAttribute变量,随后,通过如下语句判断是否需要进行会话规定漏洞保护

boolean sessionFixationProtectionRequired = !sessionFixationAttribute.equals(OPT_SESSION_FIXATION_NO_PROTECTION);


需要说明的是在上述语句之前,如果发现sessionFixationAttribute变量没有赋值(例如,没有配置session-management属性),程序会采用如下语句确保缺省的session-fixation-protection=migrateSession

if (!StringUtils.hasText(sessionFixationAttribute)) {
sessionFixationAttribute = OPT_SESSION_FIXATION_MIGRATE_SESSION;


下面的判断,如果您配置了session-management并启用了concurrency-control,则向SessionManagementFilter注册ConcurrentSessionControlStrategy类;否则如果上面代码中的sessionFixationProtectionRequired = true或者配置了invalid-session-url,则向SessionManagementFilter注册SessionFixationProtectionStrategy类,由于ConcurrentSessionControlStrategy继承自SessionFixationProtectionStrategy,因此以上条件下,都会导致SessionFixationProtectionStrategy的策略被应用,而SessionFixationProtectionStrategy的策略,将在SessionManagementFilter中被执行,代码如下

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
{
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;

if (request.getAttribute("__spring_security_session_mgmt_filter_applied") != null) {
chain.doFilter(request, response);
return;
}

request.setAttribute("__spring_security_session_mgmt_filter_applied", Boolean.TRUE);

if (!this.securityContextRepository.containsContext(request)) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

if ((authentication != null) && (!this.authenticationTrustResolver.isAnonymous(authentication)))
{
try {
this.sessionAuthenticationStrategy.onAuthentication(authentication, request, response);

......


回头来看SessionFixationProtectionStrategy的onAuthentication方法,如下代码中,字体加粗部分,先设置当前的session失效,再创建一个新的session

public void onAuthentication(Authentication authentication, HttpServletRequest request, HttpServletResponse response)
{
boolean hadSessionAlready = request.getSession(false) != null;

if ((!hadSessionAlready) && (!this.alwaysCreateSession))
{
return;
}

HttpSession session = request.getSession();

if ((hadSessionAlready) && (request.isRequestedSessionIdValid()))
{
String originalSessionId = session.getId();

if (this.logger.isDebugEnabled()) {
this.logger.debug("Invalidating session with Id '" + originalSessionId + "' " + (this.migrateSessionAttributes ? "and" : "without") + " migrating attributes.");
}

Map attributesToMigrate = extractAttributes(session);

session.invalidate();
    session = request.getSession(true);

if (this.logger.isDebugEnabled()) {
this.logger.debug("Started new session: " + session.getId());
}

if (originalSessionId.equals(session.getId())) {
this.logger.warn("Your servlet container did not change the session ID when a new session was created. You will not be adequately protected against session-fixation attacks");
}

transferAttributes(attributesToMigrate, session);

onSessionChange(originalSessionId, session, authentication);
}
}


最后,怎么关闭Spring Security的session-fixation-protection呢,由以上代码分析知,除了将session-fixation-protection设置为null以外,还不能设置诸如concurrency-control或invalid-session-url属性,举例如下

<session-management session-fixation-protection="none" />
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: