Preventing clickjacking attack - java

Currently, I'm working on a vaadin project where I'm working on preventing clickjacking attack on the project. After searching for the solution I've found that adding following snippet in web.xml would work:
<filter>
<filter-name>httpHeaderSecurity</filter-name>
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>antiClickJackingEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>antiClickJackingOption</param-name>
<param-value>SAMEORIGIN</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>httpHeaderSecurity</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
I've added following dependency in pom.xml:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>9.0.2</version>
</dependency>
I'm running the project on payara server.
The project runs but throw the following error:
Caused by: java.lang.ClassNotFoundException:
org.apache.catalina.filters.HttpHeaderSecurityFilter not found by
org.glassfish.main.web.core [69] at
org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532)
at
org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
at
org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at
org.apache.catalina.core.ApplicationFilterConfig.loadFilterClass(ApplicationFilterConfig.java:283)
at
org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:253)
at
org.apache.catalina.core.ApplicationFilterConfig.(ApplicationFilterConfig.java:123)
... 50 more
Which means my solution for preventing clickjacking attack won't work :)
Any help will be appreciated :).

I've solved this in the following way using web.xml:
First created the following filter:
public class ClickjackingPreventionFilter implements Filter
{
private String mode = "DENY";
// Add X-FRAME-OPTIONS response header to tell any other browsers who not to display this //content in a frame.
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse)response;
res.addHeader("X-FRAME-OPTIONS", mode );
chain.doFilter(request, response);
}
#Override
public void destroy() {
}
#Override
public void init(FilterConfig filterConfig) {
String configMode = filterConfig.getInitParameter("mode");
if ( configMode != null ) {
mode = configMode;
}
}
}
Then configured that into web.xml like the following:
<filter>
<filter-name>ClickjackPreventionFilterDeny</filter-name>
<filter-class>com.groupbuilder.preventclickjacking.ClickjackingPreventionFilter</filter-class>
<init-param>
<param-name>mode</param-name><param-value>DENY</param-value></init-param>
</filter>
<filter-mapping>
<filter-name>ClickjackPreventionFilterDeny</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Related

Java filter doesn't work, when I tried to make request

I have this Cors filter:
public class SimpleCorsFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
#Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
System.out.println("here");
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
chain.doFilter(req, res);
System.out.println("here2");
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
}
And it seems it doesnt work. HEre is my web.xml:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:app-context.xml</param-value>
</context-param>
<filter>
<filter-name>SimpleCORSFilter</filter-name>
<filter-class>org.heller.filter.SimpleCorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SimpleCORSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
Can someone please give me a poit how to make this filter work? When I tried to request, there is no message ,,here" in console. I saw lot of tutorials, and code seems to be fine. It should be some mistake, which I dont see. Thank you for help.
My web.xml look like:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:app-context.xml</param-value>
</context-param>
<filter>
<filter-name>SimpleCORSFilter</filter-name>
<filter-class>org.heller.filter.SimpleCorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SimpleCORSFilter</filter-name>
<servlet-name>app</servlet-name>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
</web-app>
And now it runs! Thank you for help!
This is my filter :-
package com.test.test.apis.filter;
public class AuthenticationFilter implements Filter{
private FilterConfig filterConfig;;
private List<String> excludedApiUrls;
protected ServletContext servContext;
private static final String AUTHENTICATION_HEADER_KEY = "Authorization";
private static final String AUTHENTICATION_HEADER_VALUE_PREFIX = "Bearer "; // with trailing space to separate token
#Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
String excludePattern = filterConfig.getInitParameter("excludedUrls");
excludedApiUrls = Arrays.asList(excludePattern.split(","));
}
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {
if (filterConfig == null) return;
HttpServletRequest request = (HttpServletRequest) servletRequest;
if(!"OPTIONS".equalsIgnoreCase(request.getMethod())) {
// filter logic
}else {
filterChain.doFilter(request, servletResponse);
}
}
#Override
public void destroy() {
filterConfig = null;
}
}
CORS Configurration:-
package com.test.test.apis.filter;
public class CORSFilter implements ContainerResponseFilter {
#Override
public ContainerResponse filter(ContainerRequest request,ContainerResponse response) {
response.getHttpHeaders().add("Access-Control-Allow-Origin", "*");
response.getHttpHeaders().add("Access-Control-Allow-Headers","origin, content-type, accept, authorization");
response.getHttpHeaders().add("Access-Control-Allow-Credentials", "true");
response.getHttpHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
return response;
}
}
web.xml;-
<filter>
<filter-name>ApiFilter</filter-name>
<filter-class>com.test.test.apis.filter.AuthenticationFilter</filter-class>
<init-param>
<param-name>excludedUrls</param-name>
<param-value>/tb/login/doLogin</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>ApiFilter</filter-name>
<servlet-name>api-serlvet</servlet-name>
</filter-mapping>
<servlet>
<servlet-name>api-serlvet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.test.test.apis.controllers</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.test.test.apis.filter.CORSFilter</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>api-serlvet</servlet-name>
<url-pattern>/test/*</url-pattern>
</servlet-mapping>

filter that forwards to index page

I want to make a filter that would forward to /WEB-INF/index.html request to application that looks like this
http://localhost:8080/basic-application-web
Here is my filter
public class RootFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
if (req.getRequestURI().equals("/basic%2Dapplication%2Dweb/")) {
req.getRequestDispatcher("/WEB-INF/index.html").forward(req, resp);
}
chain.doFilter(request, response);
}
#Override
public void destroy() {}
}
My web.xml looks like this
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://java.sun.com/xml/ns/javaee'
xmlns:web='http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd'
xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaeeweb-app_2_5.xsd'
id='basic_web' version='2.5'>
<display-name>Basic web application</display-name>
<servlet>
<servlet-name>serviceServlet</servlet-name>
<servlet-class>com.pack.ServiceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>serviceServlet</servlet-name>
<url-pattern>/messaging</url-pattern>
</servlet-mapping>
<filter>
<filter-name>rootFilter</filter-name>
<filter-class>com.pack.RootFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>rootFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
However from time to time I get some weird behaviour where tomcat (I use it to deploy the war) is unable to find basic-application-web when I try to access directly using URL.
Though through tomcat manager it works fine. What is the problem? Maybe due to missing root servlet?
I moved index.html outside WEB-INF so basically the layout started to look like this
webapp
WEB-INF\web.xml
index.html
And adjusted filter to forward to /index.html instead of WEB-INF/index.html
req.getRequestDispatcher("/WEB-INF/index.html").forward(req, resp);
It has helped.

JQuery invoking Spring Rest service: Cross-Origin issue vs ParseError

I am trying to invoke a REST service with jquery, but either I get a Cross Origin Problem (when I do not specify the datatype in jquery invocation) or a parseerror (when I do).
JQuery use:
function requestData() {
$.ajax({
url: 'http://xxx.xx.xx.xxx:8080/Project/api/',
type: 'GET',
dataType:"jsonp",
success: function(json) {
console.log("OK");
console.log(json);
},
error: function(xhr, status, error) {
console.log("NO");
console.log("STATUS:" + status);
}
});
}
Server side, I am using Spring REST this way:
#RequestMapping(value = "/", method = RequestMethod.GET)
public #ResponseBody List<Entity> getEntities() {
List<Entity> found = controller.findEntities();
return found;
}
The serialized data are correct, as invoking the REST API in the browser produces correct JSON.
I also added the following CORS filter, which does NOT seem to be executed, as "AA" is not printed:
#Component
public class SimpleCORSFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
System.out.println("AA");
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods",
"POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() { }
}
My web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>simpleCORSFilter</filter-name>
<filter-class>org.lh.xxx.web.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>simpleCORSFilter</filter-name>
<servlet-name>/*</servlet-name>
</filter-mapping>
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
What's wrong with it?
The issue was strictly related to the filter not being executed: Spring Filter not getting invoked
When executing the filter, correct json is returned to the invoking client.

SpringMVC - Controller for all files with same file extension

I have a SpringMVC application, and I need to create a controller capable of handling all the request for files with a given extension.
So far I have this:
web.xml
<filter-mapping>
<filter-name>redirectFilter</filter-name>
<url-pattern>*.jhtml</url-pattern>
</filter-mapping>
spring-mvc.xml
<bean id="anotherViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver" >
<property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>
<property name="prefix" value="/"/>
<property name="suffix" value=".jhtml"/>
</bean>
Dispatcher Servlet
<servlet>
<servlet-name>abc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>abc</servlet-name>
<url-pattern>/abc/*</url-pattern>
</servlet-mapping>
How should I write the controller?
You can write a #Controller method like this
#RequestMapping(value = "**/*.jhtml")
public String handleExtensionRequest() {
return "viewName";
}
This will map to paths like
www.yourhost.com/abc/somePath.jhtml
www.yourhost.com/abc/asdasdasd/qweqwe1231/12312312/somePath.jhtml
going down any number of sub paths.
The problem with this is /abc/somePath and /abc/somePath.* are considered equivalent. If you have a #Controller handler method mapped to /somePath, it will probably get priority.
With Java config, you can declare a #Configuration class to extends WebMvcConfigurationSupport and add
#Override
#Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping handlerMapping = super.requestMappingHandlerMapping();
handlerMapping.setUseSuffixPatternMatch(false);
return handlerMapping;
}
This setting decides
Whether to use suffix pattern match (".*") when matching patterns to
requests.
The RequestMappingHandlerMapping has other methods/settings you can play around with to set the right path.
I opted for the easiest way: since what I only need is to redirect those *.jhtml requests to somewhere else, I added a filter for them.
web.xml
<filter>
<description>Filter for *.jhtml requests</description>
<display-name>jhtmlRedirectFilter</display-name>
<filter-name>jhtmlRedirectFilter</filter-name>
<filter-class>com.mycompany.JHTMLRedirectFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>jhtmlRedirectFilter</filter-name>
<url-pattern>*.jhtml</url-pattern>
</filter-mapping>
JHTMLRedirectFilter class
public class JHTMLRedirectFilter implements Filter {
private static final Logger logger = Logger.getLogger(JHTMLRedirectFilter.class);
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
// Some logic here
}
#Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}

Filter not working

I basically have a filter and in it's doFilter method, i'm just printing a message to console and i have applied that filter to every page of my sample web app.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>
com.mypkg.filters.LoginFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>utility.jsp</welcome-file>
and my filter code
LoginFilter.java
package com.mypkg.filters;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
//other imports
public class LoginFilter implements Filter {
#Override
public void init(FilterConfig config) throws ServletException {
System.out.println("Filter init ran!");
}
#Override
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
System.out.println("Filter running!");
}
#Override
public void destroy(FilterConfig config) throws ServletException {
//System.out.println("Filter destoryed!");
}
Now when i first ran this filter, i got "Filter running" message but after that i included hibernate and other libraries, it stopped working, i removed them and same result. Filter doesn't run. Checked url pattern and everything.. Clueless!!
Any pointers?
First of all, in you doFilter method you should call the next filter in the chain:
chain.doFilter(request, response);
Without this your request will not be processed further after your filter.
This can be a reason of your problem.
EDIT:
Also your destroy() method is wrong. Here how you should rewrite it:
#Override
public void destroy() {
System.out.println("Filter destoryed!");
}
Maybe you have another Filter executed before yours, that does not call chain.doFilter(), thus preventing next filters (including yours) to be executed.

Categories

Resources