有没有办法禁用控制器的某些操作的CSRF验证,以保持其他操作的启用?
在我的例子中,我有几个可配置的Action类,用于注入控制器.我无法将csrf验证令牌传递给AJAX请求,因为我正在使用的东西是外部(由我不做)前端的WYSIWYG插件.是的,我仍然可以使用这些操作禁用整个控制器的csrf验证,但它可能不安全.
我正在使用spring security和java config
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/*").hasRole("ADMIN")
.and()
.addFilterAfter(new CsrfTokenResponseHeaderBindingFilter(), CsrfFilter.class)
.exceptionHandling()
.authenticationEntryPoint(restAuthenticationEntryPoint)
.and()
.formLogin()
.successHandler(authenticationSuccessHandler)
.failureHandler(new SimpleUrlAuthenticationFailureHandler());
Run Code Online (Sandbox Code Playgroud)
我正在使用PostMan来测试我的REST服务.我成功获得'csrf token',我可以使用X-CSRF-TOKEN请求标头登录.但登录后我点击发布请求(我在请求标题中包含相同的令牌,我用于登录发布请求)我收到以下错误消息:
HTTP状态403 - 无法验证提供的CSRF令牌,因为找不到您的会话.
任何人都可以指导我做错了什么.
我正在使用Rails进行单页应用程序.登录和注销时,使用ajax调用Devise控制器.我得到的问题是,当我1)登录2)退出然后再次登录不起作用.
我认为它与CSRF令牌有关,当我退出时它会被重置(虽然它不应该是afaik),并且因为它是单页,旧的CSRF令牌正在xhr请求中发送,从而重置会话.
更具体地说,这是工作流程:
WARNING: Can't verify CSRF token authenticity在服务器日志中打印)任何线索非常感谢!如果我可以添加更多详细信息,请与我们联系.
使用REST API作为后端,由JWT授权反应前端,但如何处理会话?例如,登录后我从REST获取JWT令牌,如果我将其保存到localStorage,我很容易受到XSS的攻击,如果我将其保存到Cookies,只有在没有设置HttpOnly时才会出现同样的问题,但是反应无法读取HttpOnly Cookies(我需要)读取cookie以从中获取JWT,并将此JWT用于休息请求),我也没有提到CSRF问题,如果使用REST作为后端,则不能使用CSRF令牌.
因此,使用REST的React似乎是糟糕的解决方案,我需要重新思考我的架构,如何成为?是否有可能为您的用户提供安全的响应应用程序,哪些业务逻辑在REST API端处理,而不必担心丢失数据?
更新:
据我所知,有可能这样做:
我有缺乏理论知识在这里,但看起来逻辑和相当安全的,但我仍然需要回答我的问题,并批准该"工作流"的.
我正在通过Laravel 5上的AJAX上传文件.除了一件事,我几乎所有工作都在工作.
当我尝试上传一个太大的文件时(比我更大upload_max_filesize,post_max_size我得到了一个TokenMismatchException).
但是,这是预料之中的,因为我知道如果超出这些限制,我的输入将为空.空输入,意味着没有_token收到,因此负责验证CSRF令牌的中间件为什么会大惊小怪.
然而,我的问题不是抛出这个异常,而是渲染它的方式.当Laravel捕获到这个异常时,它正在为通用的Whoops页面吐出HTML(由于我处于调试模式,因此加载了堆栈跟踪).
处理此异常的最佳方法是什么,以便通过AJAX返回JSON(或者在请求JSON时),同时保持默认行为?
编辑:无论抛出什么异常,这似乎都会发生.我刚尝试通过AJAX(数据类型:JSON)向一个"页面"发出请求,该页面在尝试获取404时不存在,同样的事情发生 - 返回HTML,没有JSON友好.
Rails默认情况下会自动为所有表单添加CSRF保护,方法是添加authentication_token到站点生成的所有表单.
我真的希望我的网站在网站的首页上有一个简单的注册表单,当然这将是一个静态的HTML页面.理想情况下,这将完全避免攻击Rails堆栈,从而允许我向首页提供更多请求.
这样做的缺点是它使CSRF保护更加困难.
但我想知道是否真的有必要在注册表单上设置CSRF,考虑到CSRF攻击通常依赖于受害者登录,以便可以利用信任.注册表单会记录用户是否正确验证,但我认为这对攻击者没有任何用处.
是否有关于此的建立视图或使用Rails/jQuery的解决方法?
我有反CRSF MVC机制的问题.cookie和返回的表单输入不匹配.我每次都会收到一个错误,只在一个特定的页面中.在应用程序的其余部分,它运行良好.
服务器正在返回HTTP 500 Internal Server Error,我可以在日志中看到此异常:
[System.Web.Mvc.HttpAntiForgeryException]:{"未提供所需的防伪标记或无效."}
这是服务器生成的隐藏输入:
<input name="__RequestVerificationToken" type="hidden" value="QK8P7rjyZE6Vm5seY7Fr704YCOoFGdTIMzl1W7R0ZFpXSMjGKLG2T05DfFSYTxvtQCEx7DDT69DGsDB2+ZXFHY8oAjiKz0gw8BhDFywgmfIpoXnGpj7fONNzIIfvbrDrE9WJsMu6Io/0bDLM5WfKs0zktiNjyOWpfYrmnfINYmjW8NLOZFoz74xTcgTptAld">
Run Code Online (Sandbox Code Playgroud)
这是Cookie返回:
Set-Cookie:__RequestVerificationToken_L2VGbG93=skmTAVI8HCbfxDS+xhioIMIISL3UOBI7qJM1JbHjTtAqKl4W70pDUcTKMm0p3R3mrHDziE8vXw0C0OO4HArzWO1/e6py+v/cFdbe9maFgjl4jMiZ9Wc4YIhC6+IUXkk6yqJDJ8dCIr8qtGaYcD9IX+m7/SlVhu521KQSWJYRcaY=; path=/; HttpOnly
Run Code Online (Sandbox Code Playgroud)
当我检查服务器发送的内容时,cookie完全相同,但我认为有效负载具有不同的编码:
__RequestVerificationToken:QK8P7rjyZE6Vm5seY7Fr704YCOoFGdTIMzl1W7R0ZFpXSMjGKLG2T05DfFSYTxvtQCEx7DDT69DGsDB2%2BZXFHY8oAjiKz0gw8BhDFywgmfIpoXnGpj7fONNzIIfvbrDrE9WJsMu6Io%2F0bDLM5WfKs0zktiNjyOWpfYrmnfINYmjW8NLOZFoz74xTcgTptAld
Run Code Online (Sandbox Code Playgroud)
区别在于两个出现编码的字符:
/ -> %2F
+ -> %2B
Run Code Online (Sandbox Code Playgroud)
这些是我在隐藏输入字段和后有效负载之间可以找到的唯一差异.
什么可能是导致ValidateAntiForgeryToken验证令牌失败的问题?
问候.
所以我正在四处阅读并且对于拥有CSRF令牌感到困惑,我应该为每个请求生成一个新令牌,还是每小时或者其他什么?
$data['token'] = md5(uniqid(rand(), true));
$_SESSION['token'] = $data['token'];
Run Code Online (Sandbox Code Playgroud)
但是,假设每小时生成一个令牌更好,那么我需要两个会话:令牌,到期,
我将如何处理表格?只需将echo $ _SESSION ['token']放在隐藏的值表单上,然后在提交时进行比较?
首先,我假设一个后端控制输入以防止XSS漏洞.
在这个答案中 @Les Hazlewood解释了如何在客户端保护JWT.
假设所有通信都有100%TLS - 在登录期间和登录后的所有时间 - 通过基本身份验证使用用户名/密码进行身份验证并在交换中接收JWT是一个有效的用例.这几乎就是OAuth 2的一个流程('密码授权')的工作方式.[...]
您只需设置Authorization标头:
Run Code Online (Sandbox Code Playgroud)Authorization: Bearer <JWT value here>但是,话虽如此,如果您的REST客户端是"不受信任的"(例如支持JavaScript的浏览器),我甚至不会这样做:HTTP响应中可通过JavaScript访问的任何值 - 基本上任何标头值或响应正文值 - 可以通过MITM XSS攻击嗅探和截获.
最好将JWT值存储在仅安全的纯http cookie中(cookie config:setSecure(true),setHttpOnly(true)).这可以保证浏览器:
- 只通过TLS连接传输cookie,
- 永远不要将cookie值用于JavaScript代码.
这种方法几乎是您为最佳实践安全所需要做的一切.最后一件事是确保您对每个HTTP请求都有CSRF保护,以确保启动对您站点的请求的外部域无法正常运行.
最简单的方法是使用随机值(例如UUID)设置仅安全(但不是仅限http)cookie.
我不明白为什么我们需要具有随机值的cookie来确保启动对您站点的请求的外部域无法运行.使用同源策略时,这不是免费的吗?
来自OWASP:
检查Origin Header
Origin HTTP Header标准是作为防御CSRF和其他跨域攻击的方法而引入的.与引用者不同,源将出现在源自HTTPS URL的HTTP请求中.
如果存在原始标头,则应检查其是否一致.
我知道OWASP本身的一般建议是同步器令牌模式,但我看不出剩下的漏洞是什么:
更新1: 同源策略仅适用于XMLHTTPRequest,因此恶意站点可以轻松地生成表单POST请求,这将破坏我的安全性.需要显式的原始标头检查.等式将是:
我正在使用带有Java配置的Spring-Security 3.2.0.RC2.我设置了一个简单的HttpSecurity配置,要求/ v1/**上的基本身份验证.GET请求工作但POST请求失败:
HTTP Status 403 - Invalid CSRF Token 'null' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
Run Code Online (Sandbox Code Playgroud)
我的安全配置如下所示:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
private MyUserDetailsService userDetailsService;
@Autowired
//public void configureGlobal(AuthenticationManagerBuilder auth)
public void configure(AuthenticationManagerBuilder auth)
throws Exception {
StandardPasswordEncoder encoder = new StandardPasswordEncoder();
auth.userDetailsService(userDetailsService).passwordEncoder(encoder);
}
@Configuration
@Order(1)
public static class RestSecurityConfig
extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/v1/**").authorizeRequests()
.antMatchers("/v1/**").authenticated()
.and().httpBasic();
}
}
}
Run Code Online (Sandbox Code Playgroud)
对此的任何帮助都非常感谢.
post csrf spring-security basic-authentication spring-java-config