Embracing the Messiness in Search of Epic Solutions

JEE Security: Preventing Clickjacking Attacks

Posted

in

PROBLEM

Clickjacking is an attack that tricks the users to perform unintended actions… see OWASP’s Testing for Clickjacking (OTG-CLIENT-009)

SOLUTION

To prevent clickjacking attacks, the app must set X-FRAME-OPTIONS header with an appropriate value:-

  • DENY: this denies any domain using the page as an iFrame source. This is the best option.
  • SAMEORIGIN: this allows pages within the same domain to use other application pages as iFrame sources.
  • ALLOW-FROM [whitelisted domains]: this declares a list of domains that are allowed to include the pages as iFrame sources.

If set correctly, the HTTPS response should show X-FRAME-OPTIONS header:-

➜  ~ curl -i -k https://localhost:8443/
HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
X-Application-Context: application:local:8443
Set-Cookie: JSESSIONID=04ADDAF886A20AA561021E869E980BCC; Path=/; Secure; HttpOnly
Content-Type: text/html;charset=UTF-8
Content-Language: en-US
Content-Length: 631
Date: Thu, 31 Aug 2017 14:56:57 GMT

There are several ways to set this header.

Solution 1: Using a servlet filter

You may create a servlet filter that sets X-FRAME-OPTIONS in the response header.

Here’s an example using web.xml-less Spring Boot:-

@SpringBootApplication
class Application extends SpringBootServletInitializer {
    static void main(String[] args) {
        SpringApplication.run(Application, args)
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(Application)
    }

    @Bean
    FilterRegistrationBean clickjackingPreventionFilter() {
        return new FilterRegistrationBean(
                urlPatterns: ['/**'],
                filter: new Filter() {
                    @Override
                    void init(final FilterConfig filterConfig) throws ServletException {
                    }

                    @Override
                    void doFilter(final ServletRequest servletRequest,
                                  final ServletResponse servletResponse,
                                  final FilterChain filterChain) throws IOException, ServletException {
                        final HttpServletResponse response = (HttpServletResponse) servletResponse
                        response.addHeader('X-FRAME-OPTIONS', 'DENY')
                        filterChain.doFilter(servletRequest, servletResponse)
                    }

                    @Override
                    void destroy() {
                    }
                }
        )
    }
}

Solution 2: Using Spring Security

Spring Security provides a very easy way to set the X-FRAME-OPTIONS header:-

@Configuration
@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.
                headers().frameOptions().deny().
                and().
                authorizeRequests().
                antMatchers('/**').permitAll()
    }
}

Comments

Leave a Reply