Simple XSS Prevention in Java projects

Tugrul Aslan
4 min readFeb 17, 2022

Introduction

Cross Site Scripting a.k.a XSS is a type of an attack in which the malicious actors look for means to insert scripting code into the application. Then the inserted code will be executed on the victims browsers which will give actors leverage to perform unwanted executions. The malicious code may allow for example stealing cookies or session information. You can read more about this type of attack in details at Owasp’s Web Site.

Well known type: Persisted/Stored XSS

There is a few of other XSS types, but in this article I’d like to focus on Persisted type.

The attack is depicted from all perspectives

As the name suggests the malicious code is persisted in the system generally via user input. The eventual outcome is that victims are being infected every time they land on the pages that serve the malicious code. Here is the whole flow how it all works out :

  1. The malicious actor inserts some malicious code via web forms,
  2. The web application does not sanitize or encode the given content, and persists the input, eventually upon the successful persistence, the code is written into the database,
  3. When the innocent clients starts visiting the page, then they are infected with the code being executed on their browser.

Of course the flow of the attack is solely up to the actor’s intention, they can enforce any code execution.

Prevention

Once again Owasp’s web site offers great information and ways to prevent. The library focuses on removal of content which is called as Sanitation. The sanitation works. Furthermore some of the content is encoded to prevent possible attacks from every possible vectors via the provided input.

When I entered into the waters of the XSS security libraries, I was surprised that they start clearing up the given HTML inputs, as well as encoding some of content that I provided. However, that’s what the sanitation is all about. Basically, the tools we use shall remove the malicious content, so that we will be in safe hands.

There are many of libraries out there, whatever you choose, they mostly work on a way of White listing methodology. White listing only allows the allowed elements that are on the white list. Basically this is what White listing means right?

Preferred Security Library: OWASP Java HTML Sanitizer

I did stumble upon this library OWASP Java HTML Sanitizer which has Google Security engineers for the contribution and maintenance. According to the web site the library has the following benefits:

  • Very easy to use. It allows for simple programmatic POSITIVE policy configuration (see below). No XML config,
  • Actively maintained by Mike Samuel from Google’s AppSec team,
  • Passing 95+% of AntiSamy’s unit tests plus many more,
  • This is code from the Caja project that was donated by Google. It is rather high performance and low memory utilization,
  • Java 1.5+,
  • Provides 4X the speed of AntiSamy sanitization in DOM mode and 2X the speed of AntiSamy in SAX mode.

Furthermore, among many good libraries I have also seen this simple library called Jsoup which offers a configurable XSS security library for public to utilize HTML Sanitation

Sanitation in Action using OWASP library

I have prepared a tiny Spring Boot project with a dummy REST API. You can reach out the source code here in my GitHub repository. However, I’ll expose the core of the application which is the configuration of the Owasp library and some sample test cases.

XssSanitizerService.java: The service utilizes and configures the library using a Java class via Factories. The provided configuration only allows basic inputs of HTML and limited hyper text links. This configuration is best suitable for simple WYSIWYG editor inputs from the users,

package com.tugrulaslan.service;

import org.owasp.html.HtmlPolicyBuilder;
import org.owasp.html.PolicyFactory;
import org.springframework.stereotype.Service;

@Service
public class XssSanitizerService {
public String sanitize(String input) {
PolicyFactory policyFactory = new HtmlPolicyBuilder()
.allowStandardUrlProtocols()
.allowStyling()
.allowCommonBlockElements()
.allowCommonInlineFormattingElements()
.allowElements("a")
.allowAttributes("href").onElements("a")
.toFactory();
return policyFactory.sanitize(input);
}
}

XssSanitizerServiceTest.java: this is the unit test that has simple test cases to cover the basics

package com.tugrulaslan.service;

import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class XssSanitizerServiceTest {

private final XssSanitizerService sanitizerService = new XssSanitizerService();

@Test
public void shouldRemoveOnClickAttributes() {
//given
String input = "<p><a href='http://h4ck3rz-53cr3t-ar3a.com' onclick='stealCookies()' onfocus='stealCookies()'>Click me</a></p>";

//when
String sanitize = sanitizerService.sanitize(input);

//then
assertThat(sanitize).isEqualTo("<p><a href=\"http://h4ck3rz-53cr3t-ar3a.com\">Click me</a></p>");
}

@Test
public void shouldRemoveScriptElements() {
//given
String input = "<div> hello <a href=\"tugrulaslan.com\" onclick=giveMeYourData()>click me</a><script>alert('')</script></div>";

//when
String sanitize = sanitizerService.sanitize(input);

//then
assertThat(sanitize).isEqualTo("<div> hello <a href=\"tugrulaslan.com\">click me</a></div>");
}
}

--

--