OWASP Java Encoder Project

= Main =  {| style="padding: 0;margin:0;margin-top:10px;text-align:left;" |-
 * valign="top" style="border-right: 1px dotted gray;padding-right:25px;" |

OWASP Java Encoder Project
The OWASP Java Encoder is a Java 1.5+ simple-to-use drop-in high-performance encoder class with no dependencies and little baggage. This project will help Java web developers defend against Cross Site Scripting!

Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts (primarily JavaScript) are injected into otherwise trusted web sites. You can read more about Cross Site Scripting here: Cross-site_Scripting_%28XSS%29. One of the primary defenses to stop Cross Site Scripting is a technique called Contextual Output Encoding. You can read more about Cross Site Scripting prevention here: XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet.

As of February 2017 there are no issues submitted against this project! https://github.com/OWASP/owasp-java-encoder/issues. We actively track project issues and seek to remediate any issues that arise. The project owners feel this project is stable and ready for production use and are seeking project status promotion.

Introduction
Contextual Output Encoding is a computer programming technique necessary to stop Cross Site Scripting. This project is a Java 1.5+ simple-to-use drop-in high-performance encoder class with no dependencies and little baggage. It provides numerous encoding functions to help defend against XSS in a variety of different HTML, JavaScript, XML and CSS contexts.

Quick Overview
The OWASP Java Encoder library is intended for quick contextual encoding with very little overhead, either in performance or usage. To get started, simply add the encoder-1.2.1.jar, import org.owasp.encoder.Encode and start encoding.

Please look at the javadoc for Encode to see the variety of contexts for which you can encode. Tag libraries and JSP EL functions can be found in the encoder-jsp-1.2.1.jar.

Happy Encoding!

Licensing
The OWASP Java Encoder is free to use under the New BSD License.


 * valign="top" style="padding-left:25px;width:200px;border-right: 1px dotted gray;padding-right:25px;" |

What is this?
The OWASP Java Encoder provides:


 * Output Encoding functions to help stop XSS
 * Java 1.5+ standalone library

Important Links
Java Encoder at GitHub Issue Tracker

Mailing List
Java Encoder Mailing List

Project Leaders
Author: Jeff Ichnowski [mailto:jeff.ichnowski@gmail.com @] Jim Manico [mailto:jim.manico@owasp.org @] Jeremy Long [mailto:jeremy.long@owasp.org @]

Related Projects

 * XSS (Cross Site Scripting) Prevention Cheat Sheet
 * OWASP Java HTML Sanitizer Project
 * OWASP JSON Sanitizer
 * OWASP Dependency Check
 * Sourceclear Headlines
 * Google KeyCzar
 * Apache SHIRO


 * valign="top" style="padding-left:25px;width:200px;" |

Quick Download

 * encoder-1.2.1.jar
 * encoder-jsp-1.2.1.jar

News and Events

 * [19 February 2017] 1.2.1 Released!
 * [11 June 2016] No reported issues and library use is strong!
 * [1 May 2015] Moved to GitHub
 * [12 Apr 2015] 1.2 Released!
 * [10 Apr 2015] GitHub move
 * [1 Feb 2015] Removed ThreadLocal
 * [20 Mar 2014] Doc additions
 * [5 Feb 2014] New Wiki
 * [4 Feb 2014] 1.1.1 Released

In Print
We will be releasing a user guide soon!

Classifications

 * }

= Use the Java Encoder Project =

The general API pattern is to utilize the Java Encoder Project in your user interface code and wrap all variables added dynamically to HTML with a proper encoding function. The encoding pattern is "Encode.forContextName(untrustedData)", where "ContextName" is the name of the target context and "untrustedData" is untrusted output.

Basic HTML Context
<%= Encode.forHtml(UNTRUSTED) %>

HTML Content Context
<%= Encode.forHtmlContent(UNTRUSTED) %>

HTML Attribute context
" />

Generally Encode.forHtml(UNTRUSTED) is also safe but slightly less efficient for the above two contexts (for textarea content and input value text) since it encodes more characters than necessary but might be easier for developers to use.

CSS contexts
"> ">

Javascript Block context
 var msg = "<%= Encode.forJavaScriptBlock(UNTRUSTED) %>"; alert(msg);

Javascript Variable context
');"> click me

JavaScript Content Notes: Encode.forJavaScript(UNTRUSTED) is safe for the above two contexts, but encodes more characters and is less efficient.

Encode URL parameter values
&order=1#top">

Encode REST URL parameters
">

Handling an Full Untrusted URL
When handling a full url with the OWASP Java encoder, first verify the URL is a legal URL.

String url = validateURL(untrustedInput);

Then encode the URL as an HTML attribute when outputting to the page. Note the linkable text needs to be encoded in a different context.

"> <%= Encode.forHtmlContent(untrustedLinkName) %> 

To use in a JSP with EL
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" " http://www.w3.org/TR/html4/loose.dtd "> <%@taglib prefix="e" uri=" https://www.owasp.org/index.php/OWASP_Java_Encoder_Project " %>  &lt;h1&gt;${e:forHtml(param.data)}&lt;/h1&gt;

Other contexts can be found in the org.owasp.Encode class methods, including XML contexts and more..

= How To Handle Numbers =

Numbers don’t need encoding since they cannot cause XSS. There are no numbers that will break out of a javascript context. If (and only if) ‘javaNumber’ is a numeric type (primitive or box wrapper), just use:

var javaScriptNumber = <%= javaNumber %>;

This is true even for the special cases of java.lang.Double.POSITIVE_INFINITY, NEGATIVE_INFINITY, NaN, and java.lang.Float equivalents.

On the other hand, if ‘javaNumber’ is some user provided data that is NOT a numeric type, then you should either (1) convert it to a number on the java side, or (2) encode it to a string and handle it on the javascript side. E.g.

<% // option (1) String javaNumber = (untrusted data); Double actualNumber = Double.parseDouble(javaNumber); // don’t forget to catch NumberFormatException %> var jsNumber = <%= actualNumber %>;

-- OR --

<% // option (2) String javaNumber = (untrusted data); %> var jsNumber = parseInt("<%=Encode.forJavaScript(javaNumber)%>");

= Deploy the Java Encoder Project =

The OWASP Java Encoder version 1.2.1 is now available in central!

OWASP Encoder at Maven Central.

Core
Direct Download: encoder-1.2.1.jar

Maven
org.owasp.encoder encoder 1.2.1

JSP Tag Library
Direct Download: encoder-jsp-1.2.1.jar

Maven
org.owasp.encoder</groupId> encoder-jsp</artifactId> 1.2.1

= Grave Accent Issue =

The following describes the Grave Accent XSS issue with unpatched versions of Internet Explorer. Thank you to Rafay Baloch for bringing this to our attention and to Jeff Ichnowski for the workaround.

Introduction
The grave accent (`), ASCII 96, hex 60 (wikipedia) is subject to a critical flaw in unpatched Internet Explorer. There is no possible encoding of the character that can avoid the issue. For a more in depth presentation on the issue discussed herein, please see Mario Heidrech's presentation.

Background
In Internet Explorer, the grave accent is usable as an HTML attribute quotation character, equivalent to single and double quotes. Specifically, IE treats the following as equivalent:

<input value="this is the value"> <input value=`this is the value`>

It is an IE extension, is not in HTML specifications (HTML4, HTML5), and is probably not well supported in other browsers.

The Issue
The following HTML snippet, demonstrates the cross-site scripting vulnerability related to grave accents on unpatched Internet Explorer:

&#x3C;div id=a&#x3E;&#x3C;input value=&#x22;&#x60;&#x60;onmouseover=alert(1)&#x22;&#x3E;&#x3C;/div&#x3E; &#x3C;div id=b&#x3E;&#x3C;/div&#x3E; &#x3C;script&#x3E;b.innerHTML=a.innerHTML&#x3C;/script&#x3E;

When this snippet is run in Internet Explorer the following steps happen:


 * 1) Two div elements are created with id's "a" and "b"
 * 2) The script executes "a.innerHTML" which returns:

<input value=``onmouseover=alert(1)>


 * 1) The script sets "b.innerHTML" to the value from (2) and is converted to the DOM equivalent of

<input value="" onmouseover="alert(1)">

The XSS issue arises from IE returning a value from innerHTML that it does not parse back into the original DOM. Patched version of IE fix this issue by returning the XSS value as a double-quoted attribute. The issue is complicated by the fact that no possible encoding of the grave accent can avoid this issue.

When...

<input value="&#96;&#96;onmouseover=alert(1)">

...is the input, "a.innerHTML" returns the same XSS vector as it does without the encoding.

Recommend Solution
Our recommended workaround is to update any JavaScript based innerHTML read to replace the accent grave with a numeric entity encoded form: "&#96;". As an example, the following change to the XSS vulnerable code above fixes the issue:

a.innerHTML=b.innerHTML.replace(/`/g, "&#96;");

This can be done in any library code that reads the innerHTML. To follow how this addresses the issue, the innerHTML from step 2 of the issue is converted to:

<input value=&#x26;#96;&#x26;#96;onmouseover=alert(1)>

Since the browser will no longer see the grave accents as an empty attribute, it will convert the input back to a copy of its original DOM.

Other Possible Solutions
As there is no encoding option available, the following options are available to web application authors:


 * 1) Do not use innerHTML copies
 * 2) Filter out the accent grave from any user input
 * 3) Clean up grave accents when using an innerHTML copy

OWASP Java Encoder Library Related Changes
The OWASP Java Encoder Library at its core is intended to be a XSS safe _encoding_ library. The grave accent is a legitimate and frequently used character, that cannot be encoded to avoid this bug in unpatched versions of IE. With enough user feedback, we may update the library to include one of the following options: (1) alternate, drop-in build that filters grave accents, with unchanged API, (2) new filtering methods.

= Roadmap =

2017-2018 Roadmap

 * Add decoders and canonicalization
 * Write a users guide including more complex examples
 * Build a mature test site
 * Optimize encoding to use new Java 8+ performance String utilities