保护你的会话令牌
通常我们会采取以下的措施来保护会话。
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》
王文君 李建蒙编著
电子工业出版社出版
相关推荐
简单的用户会话保护。 快速开始 这是一个使用Flask-Paranoid保护用户会话的简单应用程序: from flask import Flask from flask_paranoid import Paranoid app = Flask ( __name__ ) app . config [ 'SECRET_KEY' ...
冲浪 Node.js 保护中间件。 需要首先初始化会话中间件或。 如果将设置为非false值,则必须在此模块之前使用 。 否则,必须在此模块之前使用会话中间件。 例如:如果您对如何实现此模块有疑问,请阅读 。安装这是通过...
它将ASP.NET会话cookie的生存期与OIDC访问令牌之一对齐。 注意:此代码已升级为可与ASP.NET Core 2.0一起使用;请参见参考资料。 如果您使用的是基于ASP.NET Core 1.x的原始版本,则可以检查asp-net-core-1分支 它...
通过调用/ login函数并传递Civic生成的一次性登录令牌来生成会话令牌。 该登录令牌包含有关用户登录的详细信息,然后您可以对其进行验证,存储或发送到前端 有关如何将前端与公民整合信息,请参阅 ,另外, 一个...
此CSRF保护库不使用会话,文件,内存存储或数据库。 基本例子 在下面的示例中,您将找到3种最重要的方法: TokenManager::create(); TokenManager::createHtmlField(); TokenManager::validate(); 完整的名称...
它旨在用于保护没有会话的RESTful端点。 支持者 如果你想安全的基于令牌的认证快速添加到Node.js的应用程序,随时检查出Auth0的Node.js的SDK,并在免费计划 安装 npm install passport-jwt 用法 配置策略 JWT身份...
透明的登录和注销检索OAuth2访问令牌,ID令牌和刷新令牌 细粒度控制哪些URL路径受保护 会话管理 会话生存期和空闲超时的配置 自动刷新过期的令牌 与任何标准OIDC提供商兼容 支持同一应用程序的多个OIDC提供程序 与...
Spring Session(具有Spring Security)提供了一种简单的策略来创建和验证基于标头的令牌(会话ID),它可用于保护RESTful API,我已经在我的和进行了演示。 除了这些,Spring Security OAuth(Spring Security的子...
基本上有两种方法来保护REST API:1.使用基于会话和cookie的身份验证。 2.使用oauth2,即在每次调用中都包含一个json令牌以进行身份验证以及授权宁静的服务端点。 在此应用程序中,我们为此使用基于JSON令牌的...
django-session-csrf, 无需 Cookies 就可以对 Django 进行CSRF保护 这是什么?django-session-csrf 是不... 相反,它使用 Django 后端会话在服务器上维护CSRF令牌。 csrf令牌仍然必须包含在所有POST请求( 在表单中使用
将受本地会话保护的http代理/proxy到远程graphQL服务器/端点自动将带有oauth承载令牌的授权标头添加到出站请求 通过环境变量完全可配置 可插拔会话管理 基于Cookie的会话 基于Redis的会话 安全-浏览器...
概要使用 NodeJS、ExpressJS、AngularJS 和 MongoDB 进行身份验证。 服务器在 JSON Web 令牌(JWT)的帮助下保护 Angular ... 客户端将令牌存储在会话存储中。 app.js 中的 $httpProvider 拦截器代码将 JWT 添加到服
oauth-graphql-操场一个受oauth2保护的特征 服务用户界面/ 使用登录如果令牌已过期或无法刷新,则自动将用户重定向到登录 将本地身份验证代理服务到远程graphQL服务器/端点自动将带有oauth承载令牌的授权标头添加到...
anti-csrf, 全功能反CSRF库 反csrf库 动机没有任何好的会话来支持CSRF保护库。 我们的意思是:CSRF令牌可以限制为以下任何或者全部:特定会话特定的HTTP URI特定的IP地址( 可选)可以存储多个CSRF令牌CSR
AngularJS的简单,安全的身份验证。 该模块提供以下功能: Oauth2身份验证电子邮件... 关于安全性:请,以获取有关保护令牌身份验证系统的更多信息。 gem具有适当的安全措施,并且gem与该模块无缝协作。安装下载此模
保护是一项重要的安全功能,但是在没有后端会话持久性的系统中,验证非常棘手。 无状态CSRF支持解决了这一需求。 请参阅以获取在Hapi NodeJS服务器的Web应用程序中使用此示例的示例。我们如何验证请求? 当恶意脚本...
Themis解决的用例加密应用程序和后端中存储的机密:API密钥,会话令牌,文件。 在存储在数据库中之前,先对敏感数据字段进行加密( “应用程序侧字段级加密” )。 使用Themis和支持可搜索的加密,数据标记和数据...
OidcTokensApis 该示例显示了基于cookie的会话以及基于OpenID Connect的身份验证和自动访问令牌生存期管理。授权基于策略和资源的授权的某些变体数据保护显示简单的保护/取消保护调用以及相应的密钥容器。水疗和BFF ...
Themis 解决的用例加密应用程序和后端中存储的机密:API 密钥、会话令牌、文件。在存储到数据库之前加密敏感数据字段(“应用程序端字段级加密” )。使用 Themis 和Acra支持可搜索加密、数据标记化和数据屏蔽。安全...
默认情况下,它将查找名为XSRF-TOKEN的cookie,如果找到它,则将其值写入X-XSRF-TOKEN标头中,服务器会将其与用户会话中保存的CSRF令牌进行比较。 该项目直接在Rails应用程序中对此方案提供了直接支持,而无需对...