Jenkins 如何使用 CrumbIssuer 防御 CSRF 攻击

使用 CrumbIssuer 防御 CSRF 攻击

1. CSRF简介

CSRF(Cross-site request forgery)跨站请求伪造,通过伪装成受信任用户的请求来利用受信任的网站。

攻击通过在授权用户访问的页面中包含链接或者脚本的方式工作。例如:用户Bob可能正在浏览聊天论坛(网站B),而同时攻击者Alice也论坛中,并且刚刚发布了一个含有Bob银行链接(网站A)的图片消息。假如这个图片包含的链接是一次取款操作,而Bob恰好打开了银行网站,或者浏览器自动保存了包含授权信息的cookie。那么当Bob的浏览器尝试加载图片时将提交这个取款链接和他的cookie,于是在未经Bob允许下便授权了这次操作。

这利用了web中用户身份验证的一个漏洞:简单的身份验证仅仅能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。

Jenkins 如何使用 CrumbIssuer 防御 CSRF 攻击_第1张图片

2. CSRF的危害与防范

CSRF的防御思路在于,对web站点,将持久化的授权方法(例如cookie或者HTTP授权)切换为瞬时的授权方法(比如在每个form中提供隐藏field)。

具体防御手段

(1) 提交验证码

在表单中添加一个随机的数字或字母验证码。通过强制用户和应用进行交互。来有效地遏制CSRF攻击

(2) Referer Check

检查HTTP请求头中的referer字段,查看请求来源是否正常(referer可被更改,不可靠)

(3) token验证

在 HTTP 请求中以參数的形式添加一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,假设请求中没有 token 或者 token 内容不对,则觉得可能是 CSRF 攻击而拒绝该请求。

token相较于cookie能够防御CSRF的原因在于,cookie存储于用户浏览器中且当当前会话结束后仍可能继续存在且有效,在访问网站时会被自动提交。而token是以会话(session)为单位,由服务器在用户成功登陆后分配,在请求时被加在参数中或者form表单中一起提交,无法被攻击者通过跨站请求的方式获取。

举个简单的例子:

假如银行页面没有设置csrftoken,攻击者可以通过下面这行代码诱导用户点击并完成取款操作(身份验证由cookie完成)


但加上csrftoken以后,取款操作的请求变成

http://www.mybank.com/Transfer.php?toBankId=11&money=1000&csrftoken='xxx'

攻击者无法知晓csrftoken的值,也就无法完成操作了

3. CrumbIssuer

CrumbIssuer是一个为了抵御CSRF攻击而生成名为crumb值的算法。crumb通常是对能够唯一标识发送请求的代理(用户端)的信息 的hash值,并且其会被加密以防第三方伪造。

这个crumb值就相当于上面所讲的csrftoken值,由服务器端在用户登录时生成并发送给用户,之后用户每次登录时都需要对其进行验证。为了保证csrftoken不会被猜测或者伪造,生成方式是获取用户信息进行hash并加密。

在 Jenkins 中可以通过 系统管理->全局安全设置->CSRF Protection 启用或停用 CrumbIssuer ,在默认安全设置中是开启的。

4. 源码解析

hudson.security.csrf.CrumbIssuer

all() : 返回CrumbIssuer的所有描述符

getApi() : 返回所有公共方法

getDescriptor() : 获取crumb issuer的全局配置

initStaplerCrumbIssuer() : 设置Stapler

getCrumb([javax.servlet.ServletRequest request]) : 带参数就是基于请求中的特定用户信息生成crumb值,不带参数就是基于最近一次请求中的用户信息生成crumb值

getCrumbRequestField() : 获取crumb存储在哪个请求参数名中

issueCrumb(javax.servlet.ServletRequest request, String salt) : 创建一个crumb值,与getCrumb不同的是其还包含了一个用于生成hash的盐值(salt),安全性更高

validateCrumb() :有三种参数

​ 1. javax.servlet.ServletRequest request - 指定请求, 盐值和请求参数都基于最近一次的配置

​ 2. javax.servlet.ServletRequest request,MultipartFormDataParser parser - 指定表单数据和请求。盐值基于最近一次配置

​ 3. javax.servlet.ServletRequest request,String salt,String crumb - 指定请求、盐值和crumb值

你可能感兴趣的:(Jenkins 如何使用 CrumbIssuer 防御 CSRF 攻击)