在Java Web应用程序中阻止CSRF

跨站点请求伪造攻击(CSRF)在Web应用程序中非常常见,如果允许,可能会造成重大危害。 如果您从未听说过CSRF,建议您查看有关它的OWASP页面 。
幸运的是,阻止CSRF攻击非常简单,我将向您展示它们的工作方式,以及如何在基于Java的Web应用程序中以尽可能不干扰的方式防御它们。
想象一下,您即将在银行的安全网页上进行汇款,当您单击转帐选项时,将加载一个表格页面,您可以选择借方和贷方帐户,并输入要转移的金额。 当您对选择感到满意时,请按“提交”,然后将表单信息发送到银行的Web服务器,该服务器依次执行交易。
现在,将以下内容添加到图片中,一个恶意网站(您认为当然没有害处)在浏览器的另一个窗口/选项卡上打开,而您无辜地在银行站点中移动了数百万美元。 这个邪恶的网站了解银行的网络表单结构,当您浏览该网站时,它会尝试发布从您的帐户中提取资金并将其存入邪恶的霸主账户的交易,之所以能够这样做,是因为您与银行之间存在公开且有效的会话银行网站使用同一浏览器! 这是CSRF攻击的基础。
一种简单有效的预防方法是在加载初始传输表单时生成一个随机(即,不可预测的)字符串并将其发送给浏览器。 然后,浏览器将这些数据与传输选项一起发送,并且服务器会在批准交易进行处理之前对其进行验证。 这样,恶意网站即使可以访问浏览器中的有效会话也无法发布交易。
为了在Java中实现此机制,我选择使用两个过滤器,一个过滤器为每个请求创建盐,另一个过滤器进行验证。 由于用户请求以及随后应验证的POST或GET不一定按顺序执行,因此我决定使用基于时间的缓存来存储有效盐字符串列表。
用于为请求生成新的盐并将其存储在缓存中的第一个过滤器可以编码如下:
package com.ricardozuasti.csrf;import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.RandomStringUtils;public class LoadSalt implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// Assume its HTTPHttpServletRequest httpReq = (HttpServletRequest) request;// Check the user session for the salt cache, if none is present we create oneCache<String, Boolean> csrfPreventionSaltCache = (Cache<String, Boolean>)httpReq.getSession().getAttribute("csrfPreventionSaltCache");if (csrfPreventionSaltCache == null){csrfPreventionSaltCache = CacheBuilder.newBuilder().maximumSize(5000).expireAfterWrite(20, TimeUnit.MINUTES).build();httpReq.getSession().setAttribute("csrfPreventionSaltCache", csrfPreventionSaltCache);}// Generate the salt and store it in the users cacheString salt = RandomStringUtils.random(20, 0, 0, true, true, null, new SecureRandom());csrfPreventionSaltCache.put(salt, Boolean.TRUE);// Add the salt to the current request so it can be used// by the page rendered in this requesthttpReq.setAttribute("csrfPreventionSalt", salt);chain.doFilter(request, response);}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void destroy() {}
}
我使用Guava CacheBuilder创建盐缓存,因为它既有大小限制,又有每个条目的过期超时。 为了生成实际的盐,我使用了由Java 6 SecureRandom支持的Apache Commons RandomStringUtils ,以确保生成强大的种子。
在以AJAX链接,发布或调用安全交易的页面结尾的所有请求中均应使用此过滤器,因此在大多数情况下,最好将其映射到每个请求(也许除了静态内容(例如图像) ,CSS等)。 您的web.xml中的映射应类似于:
...<filter><filter-name>loadSalt</filter-name><filter-class>com.ricardozuasti.csrf.LoadSalt</filter-class></filter>...<filter-mapping><filter-name>loadSalt</filter-name><url-pattern>*</url-pattern></filter-mapping>...

就像我说的,要在执行安全交易之前验证盐,我们可以编写另一个过滤器:

package com.ricardozuasti.csrf;import com.google.common.cache.Cache;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;public class ValidateSalt implements Filter  {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// Assume its HTTPHttpServletRequest httpReq = (HttpServletRequest) request;// Get the salt sent with the requestString salt = (String) httpReq.getParameter("csrfPreventionSalt");// Validate that the salt is in the cacheCache<String, Boolean> csrfPreventionSaltCache = (Cache<String, Boolean>)httpReq.getSession().getAttribute("csrfPreventionSaltCache");if (csrfPreventionSaltCache != null &&salt != null &&csrfPreventionSaltCache.getIfPresent(salt) != null){// If the salt is in the cache, we move onchain.doFilter(request, response);} else {// Otherwise we throw an exception aborting the request flowthrow new ServletException("Potential CSRF detected!! Inform a scary sysadmin ASAP.");}}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void destroy() {}
}
您应该为每个需要确保安全的请求(例如,检索或修改敏感信息,转移资金等)配置此过滤器,例如:
...<filter><filter-name>validateSalt</filter-name><filter-class>com.ricardozuasti.csrf.ValidateSalt</filter-class></filter>...<filter-mapping><filter-name>validateSalt</filter-name><url-pattern>/transferMoneyServlet</url-pattern></filter-mapping>...
配置两个servlet后,所有受保护的请求都将失败:)。 要解决此问题,您必须在每个以安全URL结尾的链接和表单帖子中添加csrfPreventionSalt参数,该参数包含具有相同名称的request参数的值。 例如,在JSP页面内以HTML形式:
...
<form action="/transferMoneyServlet" method="get"><input type="hidden" name="csrfPreventionSalt" value="<c:out value='${csrfPreventionSalt}'/>"/>...
</form>
...

当然,您可以编写一个自定义标签,一个不错的Javascript代码,或在每个所需的链接/表单中添加新参数的方法。

参考: Ricardo Zuasti博客博客上的JCG合作伙伴 Ricardo Zuasti 阻止了Java Web应用程序中的CSRF 。


翻译自: https://www.javacodegeeks.com/2012/06/preventing-csrf-in-java-web-apps.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372388.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows命令行无法启动redis_windows系统安装redis

1、下载最新redis https://github.com/MicrosoftArchive/redis/releases我选择下载msi版本的2.双击下载包安装3.设置redis环境变量&#xff0c;把redis路径配置到系统变量path值中4启动redis&#xff0c;cmd进入安装好redis文件夹 输入&#xff1a;如果redis启动出错Creating S…

SQL Server 筛选时间区间

一、SQL直接判断 select * from login where pass>2013/03/25 and pass < 2017/04/24 二、DATEDIFF() 函数返回两个日期之间的时间 --语法 DATEDIFF(datepart,startdate,enddate) --开始时间 startdate --结束时间 enddate --datepart datepart缩写年yy, yyyy季度qq, …

OpenShift Express Web管理控制台:入门

本周&#xff0c; 最新版本的OpenShift为已经很棒的PaaS Cloud提供商带来了两个非常好的功能。 首先&#xff0c;JBoss AS已从7.0升级到7.1&#xff0c;并且所有新的Express Web Management Console已作为预览发布。 在本文中&#xff0c;我们将研究如何使用此新控制台&#xf…

Linux-IP地址后边加个/8(16,24,32)是什么意思?

是掩码的位数 A类IP地址的默认子网掩码为255.0.0.0&#xff08;由于255相当于二进制的8位1&#xff0c;所以也缩写成“/8”&#xff0c;表示网络号占了8位&#xff09;; B类的为255.255.0.0&#xff08;/16&#xff09;; C类的为255.255.255.0(/24) /30就是255…

女士细线毛衣起多少针_从起针到缝合,教你织毛衣的各种要点(详细教程)

新手学织毛衣看过来&#xff0c;7大编织要点帮你解决织好一件毛衣的基础问题&#xff0c;满满的干货&#xff0c;每点都值得学习!一、起针二、棒针符号三、如何织小样四、依据小样推算针数收挂肩的推算五、斜肩针数的推算开前、后领的位置与针数六、袖山的推算七、如何上袖子一…

关于OPENSSL的使用

#import <Foundation/Foundation.h> interface RSAEncryptor : NSObject /** * 加密方法 * * param str 需要加密的字符串 * param path .der格式的公钥文件路径 */ (NSString *)encryptString:(NSString *)str publicKeyWithContentsOfFile:(NSString *)path; /*…

Jelastic Java云端平台

谁在Jelastic背后&#xff1f; 那是我的第一个问题&#xff0c;因此我浏览了Jelastic网站。 回答此问题的最佳方法是查看“ Jelastic团队”部分。 创始人&#xff0c;顾问&#xff0c;特殊合作伙伴构成了一支真正的专业团队。 作为特殊的合作伙伴&#xff0c;您会发现MySQL&am…

请先设置tkk_搅拌站水泥罐仓顶除尘器设置及调整

搅拌站水泥罐仓顶除尘器采用脉冲喷吹清灰系统&#xff0c;除尘器本体结构&#xff0c;采用标准模板焊接&#xff0c;整体结构&#xff0c;强度牢靠&#xff0c;组装维修方便&#xff0c;脉冲清灰采用时序控制器MCY系列 控制阀门KEK系列&#xff0c;喷吹清灰频率及喷吹间隔可手…

Eclipse Meaven Spring SpringMVC Mybaits整合

本示例是在&#xff1a;Ubuntu15上实现的&#xff1b;Windows上安装Maven将不太相同。 Maven Install Run command sudo apt-get install maven, to install the latest Apache Maven.Run command mvn -version to verify your installation.Where is Maven installed? The co…

抽象类和抽象函数

1.抽象函数的语法特征 什么是抽象函数&#xff1f; 只有函数的定义,没有函数体的函数被称为抽象函数&#xff1b; Abstract void fun(); 如果一个类拥有一个或一个以上的抽象函数&#xff0c;那么这个类必须被定义为抽象类 2.抽象类的语法特征 使用abstract定义的类被称之…

并发–执行程序和Spring集成

基于线程池/执行器的实现 比原始线程版本更好的方法是基于线程池的线程池&#xff0c;其中基于运行任务的系统定义了适当的线程池大小– CPU数量/&#xff08;任务的1-Blocking Coefficient&#xff09;。 Venkat Subramaniams书中有更多详细信息&#xff1a; 首先&#xff0c…

后面的参数_英特尔I系列CPU大家都知道,后面的参数你有没有了解过

嗨&#xff01;大家好&#xff0c;我是伟仔&#xff0c;今天主要是和大家聊下CPU。大多数人买笔记本或台式电脑对CPU的要求就知道I5或者I7之类的。像是I7一定比I5要好&#xff0c;I3很LOU这样的&#xff0c;当然这样子的观点是不正确的&#xff0c;今天我会告诉大家&#xff0c…

設置Linux保留物理內存並使用 (1)

在Linux系統中可以通過memblock來設置系統保留物理內存&#xff0c;防止這些內存被內存管理系統分配出去。 作者&#xff1a; 彭東林 郵箱&#xff1a; pengdonglin137163.com 平臺 硬件平臺&#xff1a; TQ2440 Linux版本&#xff1a;Linux 3.14.45 說明 1. 在tq2440上&#x…

移动端

http://www.w3cplus.com/mobile/lib-flexible-for-html5-layout.html 移动端手淘使用方案 移动端px自动转换rem插件 CSSREM Flexible 转载于:https://www.cnblogs.com/yuruiweb/p/6723580.html

OutOfMemoryError:Java堆空间–分析和解决方法

java.lang.OutOfMemoryError&#xff1a;Java堆问题是在支持或开发复杂的Java EE应用程序时可能会遇到的最复杂的问题之一。 这篇简短的文章将为您提供此JVM HotSpot OutOfMemoryError错误消息的描述&#xff0c;以及在解决该问题之前应如何解决此问题。 有关如何确定要处理的O…

函数伪代码_Excel常用函数

欢迎大家在此收看任我行office教程系列&#xff0c;这一期我来为大家讲什么内容呢&#xff0c;那就是几个office的几个常用函数了&#xff0c;如果您不会这些函数和函数嵌套那么您的Excel电子表格也就别玩了哈&#xff0c;那么他们分别是什么函数呢。咱们现在隆重有请这几位函数…

阻止Ajax多次提交

1、Ajax的abort() xhr $.ajax({})if (xhr){xhr.abort(); } 2、通过在Ajax的beforeSend()方法以及complete()方法添加删除类&#xff0c;对类进行判断&#xff0c;对于两者来回切换的时候&#xff0c;对类的设置不好进行操作上的时候&#xff0c;可以通过使用一个input框&#…

POJ3675 Telescope 圆和多边形的交

POJ3675 用三角剖分可以轻松搞定&#xff0c;数据也小 随便AC。 #include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<algorithm> #include<queue> #include<vector> usi…

windows搭建python开发环境方法_04 Windows下搭建 Python 开发环境 - Python 入门教程

前面两个小节中我们已经学习了在 MacOS 和 Ubuntu 中安装 Python 的开发环境。当然&#xff0c;作为用户基数最多的 Windows 操作系统&#xff0c;我们当然不会忘记&#xff0c;这节课我们就来学习下如何在 Windows 下搭建 Python 的开发环境。1. 下载 Python1.1 Python 2 与 P…

消除view旋转后边缘有锯齿的情况

view的layer中有个属性叫 allowsEdgeAntialiasing&#xff1b; 在形变后有边缘有锯齿的话 可以 view.layer.allowsEdgeAntialiasing YES; 消除锯齿 如果直接在*-Info.plist配置 Renders with edge antialiasing YES 会导致UIAlertView显示有问题。转载于:https://www.cnblogs…