Перехватчик Token/TokenSession, приводящий к нулевому указателю на HttpSession
Я работаю над веб-приложением struts2 и обрабатываю уязвимость CSRF с помощью токена-перехватчика.
то, что я делаю, относится как к успеху, так и к ошибке. Я буду перенаправлять пользователя на ту же страницу, но с сообщением об ошибке или сообщении об успехе.
<action name="saveApplicationForm" class="action.ApplicationFormAction"
method="saveApplicationForm">
<interceptor-ref name="token" />
<result name="invalid.token" type="tiles">applicationForm.tiles</result>
<result name="input" type="tiles">applicationForm.tiles</result>
</action>
без перехватчика token / tokenSession все работает нормально, но когда я использую перехватчик, я получаю исключение NullPointerException.
трассировки стека
java.lang.NullPointerException: null
at action.ApplicationFormAction.saveApplicationForm(ApplicationFormAction.java:218) ~[ApplicationFormAction.class:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_67]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_67]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_67]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_67]
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:450) [xwork-core-2.3.16.3.jar:2.3.16.3]
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:289) [xwork-core-2.3.16.3.jar:2.3.16.3]
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:252) [xwork-core-2.3.16.3.jar:2.3.16.3]
at org.apache.struts2.interceptor.TokenInterceptor.handleValidToken(TokenInterceptor.java:193) [struts2-core-2.3.16.3.jar:2.3.16.3]
at org.apache.struts2.interceptor.TokenInterceptor.handleToken(TokenInterceptor.java:154) [struts2-core-2.3.16.3.jar:2.3.16.3]
at org.apache.struts2.interceptor.TokenInterceptor.doIntercept(TokenInterceptor.java:142) [struts2-core-2.3.16.3.jar:2.3.16.3]
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98) [xwork-core-2.3.16.3.jar:2.3.16.3]
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246) [xwork-core-2.3.16.3.jar:2.3.16.3]
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54) [struts2-core-2.3.16.3.jar:2.3.16.3]
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:562) [struts2-core-2.3.16.3.jar:2.3.16.3]
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77) [struts2-core-2.3.16.3.jar:2.3.16.3]
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99) [struts2-core-2.3.16.3.jar:2.3.16.3]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.63]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.63]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) [catalina.jar:7.0.63]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) [catalina.jar:7.0.63]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505) [catalina.jar:7.0.63]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) [catalina.jar:7.0.63]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) [catalina.jar:7.0.63]
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957) [catalina.jar:7.0.63]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) [catalina.jar:7.0.63]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423) [catalina.jar:7.0.63]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079) [tomcat-coyote.jar:7.0.63]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620) [tomcat-coyote.jar:7.0.63]
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318) [tomcat-coyote.jar:7.0.63]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_67]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_67]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-coyote.jar:7.0.63]
at java.lang.Thread.run(Thread.java:745) [na:1.7.0_67]
Класс действий
public class ApplicationFormAction extends ActionSupport implements ModelDriven<ApplicationFormBean>, SessionAware
{
private Map<String, Object> session;
// getter and setter
public String saveApplicationForm()
{
// getting nullpointer here
ApplicationFormBean sessApplicationFormBean = (ApplicationFormBean) this.session.get(SESSION_KEY_APPLICANT);
}
}
что не так с кодом?
не перенаправление на ту же страницу вызовет проблемы (представленный токен будет отличаться от вновь созданного токена)?
- если да, то как мне справиться с этой ситуацией, не перенаправляя на другую страницу?
1 ответ
<action name="saveApplicationForm" class="action.ApplicationFormAction"
method="saveApplicationForm">
<interceptor-ref name="token" />
<result name="invalid.token" type="tiles">applicationForm.tiles</result>
<result name="input" type="tiles">applicationForm.tiles</result>
</action>
Вы используете только Token Interceptor. Вместо этого вам нужно запустить весь стек, содержащий Token Interceptor. В противном случае обязательные перехватчики, такие как Parameter Interceptor и ModelDriven Interceptor (поскольку вы используете ModelDriven), не будут работать, параметры не будут установлены, и вы получите исключение NullPointerException. Измените это на:
<action name="saveApplicationForm" class="action.ApplicationFormAction"
method="saveApplicationForm">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="token" />
<result name="invalid.token" type="tiles">applicationForm.tiles</result>
<result name="input" type="tiles">applicationForm.tiles</result>
</action>
Также обратите внимание на терминологию, вы ничего не перенаправляете, вы просто отправляете. Перенаправление подразумевает совершенно другой набор проблем, таких как потеря параметров, и это происходит только с redirect
а также redirectAction
Результаты.