php session fixation,聊聊session fixation attacks
序
本文主要讲一下session fixation attacks以及spring security对它的防范。
session fixation attacks
会话固定攻击,是利用那些登录前和登录之后sessionId没有变化的漏洞来获取登录态,进而获取用户的相关信息等。
servlet3.1规范
servlet3.1规范中,HttpServletRequest.java明确规定了一个changeSessionId的方法
tomcat-embed-core-8.5.23-sources.jar!/javax/servlet/http/HttpServletRequest.java
/**
* Changes the session ID of the session associated with this request. This
* method does not create a new session object it only changes the ID of the
* current session.
*
* @return the new session ID allocated to the session
* @see HttpSessionIdListener
* @since Servlet 3.1
*/
public String changeSessionId();
SessionAuthenticationStrategy
spring-security-web-4.2.3.RELEASE-sources.jar!/org/springframework/security/web/authentication/session/SessionAuthenticationStrategy.java
/**
* Allows pluggable support for HttpSession-related behaviour when an authentication
* occurs.
*
* Typical use would be to make sure a session exists or to change the session Id to guard
* against session-fixation attacks.
*
* @author Luke Taylor
* @since
*/
public interface SessionAuthenticationStrategy {
/**
* Performs Http session-related functionality when a new authentication occurs.
*
* @throws SessionAuthenticationException if it is decided that the authentication is
* not allowed for the session. This will typically be because the user has too many
* sessions open at once.
*/
void onAuthentication(Authentication authentication, HttpServletRequest request,
HttpServletResponse response) throws SessionAuthenticationException;
}
spring security 提供了SessionAuthenticationStrategy接口,用来在登陆成功之后的处理session相关逻辑,它有个抽象类AbstractSessionFixationProtectionStrategy
AbstractSessionFixationProtectionStrategy
spring-security-web-4.2.3.RELEASE-sources.jar!/org/springframework/security/web/authentication/session/AbstractSessionFixationProtectionStrategy.java
/**
* Called when a user is newly authenticated.
*
* If a session already exists, and matches the session Id from the client, a new
* session will be created, and the session attributes copied to it (if
* {@code migrateSessionAttributes} is set). If the client's requested session Id is
* invalid, nothing will be done, since there is no need to change the session Id if
* it doesn't match the current session.
*
* If there is no session, no action is taken unless the {@code alwaysCreateSession}
* property is set, in which case a session will be created if one doesn't already
* exist.
*/
public void onAuthentication(Authentication authentication,
HttpServletRequest request, HttpServletResponse response) {
boolean hadSessionAlready = request.getSession(false) != null;
if (!hadSessionAlready && !alwaysCreateSession) {
// Session fixation isn't a problem if there's no session
return;
}
// Create new session if necessary
HttpSession session = request.getSession();
if (hadSessionAlready && request.isRequestedSessionIdValid()) {
String originalSessionId;
String newSessionId;
Object mutex = WebUtils.getSessionMutex(session);
synchronized (mutex) {
// We need to migrate to a new session
originalSessionId = session.getId();
session = applySessionFixation(request);
newSessionId = session.getId();
}
if (originalSessionId.equals(newSessionId)) {
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");
}
onSessionChange(originalSessionId, session, authentication);
}
}
如果是servlet3.1的话,则spring security默认的SessionAuthenticationStrategy就是ChangeSessionIdAuthenticationStrategy
SessionManagementConfigurer
spring-security-config-4.2.3.RELEASE-sources.jar!/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurer.java
/**
* Creates the default {@link SessionAuthenticationStrategy} for session fixation
* @return the default {@link SessionAuthenticationStrategy} for session fixation
*/
private static SessionAuthenticationStrategy createDefaultSessionFixationProtectionStrategy() {
try {
return new ChangeSessionIdAuthenticationStrategy();
}
catch (IllegalStateException e) {
return new SessionFixationProtectionStrategy();
}
}
ChangeSessionIdAuthenticationStrategy
spring-security-web-4.2.3.RELEASE-sources.jar!/org/springframework/security/web/authentication/session/ChangeSessionIdAuthenticationStrategy.java
/**
* Uses {@code HttpServletRequest.changeSessionId()} to protect against session fixation
* attacks. This is the default implementation for Servlet 3.1+.
*
* @author Rob Winch
* @since 3.2
*/
public final class ChangeSessionIdAuthenticationStrategy
extends AbstractSessionFixationProtectionStrategy {
private final Method changeSessionIdMethod;
public ChangeSessionIdAuthenticationStrategy() {
Method changeSessionIdMethod = ReflectionUtils
.findMethod(HttpServletRequest.class, "changeSessionId");
if (changeSessionIdMethod == null) {
throw new IllegalStateException(
"HttpServletRequest.changeSessionId is undefined. Are you using a Servlet 3.1+ environment?");
}
this.changeSessionIdMethod = changeSessionIdMethod;
}
/*
* (non-Javadoc)
*
* @see org.springframework.security.web.authentication.session.
* AbstractSessionFixationProtectionStrategy
* #applySessionFixation(javax.servlet.http.HttpServletRequest)
*/
@Override
HttpSession applySessionFixation(HttpServletRequest request) {
ReflectionUtils.invokeMethod(this.changeSessionIdMethod, request);
return request.getSession();
}
}
通过反射调用changeSessionId方法,具体是调用Request#changeSessionId
Request#changeSessionId
tomcat-embed-core-8.5.23-sources.jar!/org/apache/catalina/connector/Request.java
/**
* Changes the session ID of the session associated with this request.
*
* @return the old session ID before it was changed
* @see javax.servlet.http.HttpSessionIdListener
* @since Servlet 3.1
*/
@Override
public String changeSessionId() {
Session session = this.getSessionInternal(false);
if (session == null) {
throw new IllegalStateException(
sm.getString("coyoteRequest.changeSessionId"));
}
Manager manager = this.getContext().getManager();
manager.changeSessionId(session);
String newSessionId = session.getId();
this.changeSessionId(newSessionId);
return newSessionId;
}
这里调用了manager.changeSessionId(session)
ManagerBase#changeSessionId(session)
tomcat-embed-core-8.5.23-sources.jar!/org/apache/catalina/session/ManagerBase.java
@Override
public void changeSessionId(Session session) {
String newId = generateSessionId();
changeSessionId(session, newId, true, true);
}
protected void changeSessionId(Session session, String newId,
boolean notifySessionListeners, boolean notifyContainerListeners) {
String oldId = session.getIdInternal();
session.setId(newId, false);
session.tellChangedSessionId(newId, oldId,
notifySessionListeners, notifyContainerListeners);
}
/**
* Generate and return a new session identifier.
* @return a new session id
*/
protected String generateSessionId() {
String result = null;
do {
if (result != null) {
// Not thread-safe but if one of multiple increments is lost
// that is not a big deal since the fact that there was any
// duplicate is a much bigger issue.
duplicates++;
}
result = sessionIdGenerator.generateSessionId();
} while (sessions.containsKey(result));
return result;
}
StandardSessionIdGenerator#generateSessionId
tomcat-embed-core-8.5.23-sources.jar!/org/apache/catalina/util/StandardSessionIdGenerator.java
public class StandardSessionIdGenerator extends SessionIdGeneratorBase {
@Override
public String generateSessionId(String route) {
byte random[] = new byte[16];
int sessionIdLength = getSessionIdLength();
// Render the result as a String of hexadecimal digits
// Start with enough space for sessionIdLength and medium route size
StringBuilder buffer = new StringBuilder(2 * sessionIdLength + 20);
int resultLenBytes = 0;
while (resultLenBytes < sessionIdLength) {
getRandomBytes(random);
for (int j = 0;
j < random.length && resultLenBytes < sessionIdLength;
j++) {
byte b1 = (byte) ((random[j] & 0xf0) >> 4);
byte b2 = (byte) (random[j] & 0x0f);
if (b1 < 10)
buffer.append((char) ('0' + b1));
else
buffer.append((char) ('A' + (b1 - 10)));
if (b2 < 10)
buffer.append((char) ('0' + b2));
else
buffer.append((char) ('A' + (b2 - 10)));
resultLenBytes++;
}
}
if (route != null && route.length() > 0) {
buffer.append('.').append(route);
} else {
String jvmRoute = getJvmRoute();
if (jvmRoute != null && jvmRoute.length() > 0) {
buffer.append('.').append(jvmRoute);
}
}
return buffer.toString();
}
}
这段是tomcat生成sessionId的逻辑
小结
spring security通过SessionAuthenticationStrategy,在登录成功之后进行相关session处理,如果servlet3.1+,则使用ChangeSessionIdAuthenticationStrategy来更换sessionId,以防范session fixation attacks。
doc
php session fixation,聊聊session fixation attacks相关推荐
- Tomcat的SessionID引起的Session Fixation和Session Hijacking问题
上一篇说到<Spring MVC防御CSRF.XSS和SQL注入攻击>,今天说说SessionID带来的漏洞攻击问题.首先,什么是Session Fixation攻击和Session Hi ...
- Spring Session - Cookie VS Session VS Token 以及 Session不一致问题的N种解决方案
文章目录 Cookie VS Session VS Token History Cookie Session Token Session不一致问题 Session不一致解决方案 nginx sessi ...
- session传递参数_分布式 Session 之 Spring Session 架构与设计
作者 | 李增光 杏仁后端工程师.「只有变秃,才能变强!」 前言 开始进行 Web 开发时,我们可能会遇到这样的情况,当服务器重启之后,之前的登录状态会失效需要重新登录.又或者你的应用程序部署了不止 ...
- Session分布式共享 = Session + Redis + Nginx
一.Session 1.Session 介绍 我相信,搞Web开发的对Session一定再熟悉不过了,所以我就简单的介绍一下. Session:在计算机中,尤其是在网络应用中,称为"会话控制 ...
- php session 域,PHP session 跨子域问题总结
今天,做项目时候遇到个问题.之前做东西的时候session一般就直接存在数据库中这样就能解决跨域 不仅仅是跨子域,但是今天遇到这个问题是,自己要在别人现有的东西上面做修改.由于仅仅是子域 当时就行肯定 ...
- session、flask session知识的相关收集
1.打开两个浏览器窗口访问应用程序会使用同一个session还是不同的session session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的ses ...
- 利用spring session解决共享Session问题
https://blog.csdn.net/patrickyoung6625/article/details/45694157 1.共享Session问题 HttpSession是通过Servlet容 ...
- 深度实现session【包括session入库、session机制和session和cookie的使用方法,完善会话机制(在分布式机器中也能使用)】、无限分类的实现...
1.session的注意点: @session_start();//这个配置需要注意,session开启中会有影响,所以使用错误抑制符进行限制[并且使用php.ini对session进行自动开启] s ...
- 单点登录实现(spring session+redis完成session共享)
一.前言 项目中用到的SSO,使用开源框架cas做的.简单的了解了一下cas,并学习了一下 单点登录的原理,有兴趣的同学也可以学习一下,写个demo玩一玩. 二.工程结构 我模拟了 sso的客户端和s ...
- 将登录等信息保存到session中和退出session
做项目时,可能会将某些信息保存在session中,如登录等信息,这样方便在某些页面使用这些保存的信息. 要想保存这些信息,需要创建一个类,该类里面定义需要保存的变量等信息,当登录后就通过new一个该类 ...
最新文章
- 数字电路中时钟抖动 Jitter 和 偏移 Skew
- 《MANAGING THE DEVELOPMENT OF LARGE SOFTWARE SYSTEMS》总结
- 你的微博也被盗赞?试试HSTS强制HTTPS加密
- 李宏毅的可解释模型——三个任务
- 循环链表:拉丁方阵问题
- 我与Python | 从Hacker到探索Deep Learning
- pandas 数据集的端到端处理
- 说说大型高并发高负载网站的系统架构
- ErrorPageRegistrar根据不同的错误类型显示网页
- 免费不加密:C++基础教程完整版视频(黑马程序员)
- php 2037时间问题
- Spring Cloud 微服务速成
- Simulink Resolver 旋转变压器解码仿真
- Ubuntu20.04设置静态IP
- CSDN 重新开放付费资源的上传了,但要求如下
- mysql有to char函数吗_mysql 类似to_char() to_date()函数
- Javascript显示隐藏DIV
- 十二、Vue项目 - 详情页动态路由、banner布局和公用图片画廊组件拆分
- 这款Shadertoy转换器,太牛逼了!
- 竞赛图强连通分量大小幂和计数 - 组合计数 - 多项式
热门文章
- 如何使用纯CSS将页面转换为繁体字
- 云计算时代:PC会消亡吗?
- dcdc低压升压直流稳压高压负电压输出12v24v转-50V100V110V150V200V250V300V350V400V500V
- 最简单容易的四格漫画制作软件 Comic Strip Factory for Mac
- 测试应该知道的知识-python检查死链
- Using ‘UTF-8‘ encoding to copy filtered resources. skip non existing resourceDirectory
- 谷歌Mediapipe运行环境配置
- 利用SHA-1算法和RSA秘钥进行签名验签(带注释)
- mac 端口被占用 解决方案
- 迅捷路由器设置找不到服务器,迅捷(FAST)路由器第一次怎么设置? | 192路由网