JSF outputText tag: the good, the bad and the ugly

While working on a JSF (Java Server Faces) test case recently I had one of those WHAT?!?! moments - where something you take for granted starts behaving in a completely different way from how you expect. In this case it was even worse, since the behavior I was observing was breaking my application security and undermining the trust I place on libraries and frameworks as a developer.


The good

The http://java.sun.com/jsf/html/outputText tag renders basic text on your JSF page. You can customize the appearance of the text using CSS styles, in which case the generated text is wrapped in an HTML <span> element. What developers know and trust is that by default the <h:outputText> tag encodes the rendered text if it contains sensitive HTML and XML characters, making it safe for an HTML context.

The following example is XSS safe:

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
<h:head />
<body>
<h:outputText value="#{param.xss}" />
</body>
</html>


The bad

What is less known - and undocumented - is that within <script> and <style> blocks, <h:outputText> and other similar tags like <h:outputLabel> disable their HTML encoding, making the following example XSS vulnerable:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
<h:head />
<body>
<script>
  var a = <h:outputText value="#{param.xss}" />;
</script>
</body>
</html>

 
This can be dangerous if developers are not aware of this behavior and trust <h:outputText> encoding beyond its own capabilities.


The ugly

The HP Software Security Research Group found that <h:outputText> tags immediately following <script> or <style> blocks are not encoded either making the following example XSS vulnerable:

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
<h:head />
<body>
<script>
    var a = “test”;
</script>
<h:outputText value="#{param.xss}" />
</body>
</html>

 

This bug not only applies to the <h:outputText> tag but also to raw EL expressions. For example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
<h:head />
<body>
<script>
    var a = “test”;
</script>
#{param.xss}
</body>
</html>

 

Necessary and Sufficient Conditions For the Vulnerability to be Present:

 

  1. Must have an EL expression immediately after a </script> element, without any intervening components or markup, and the EL expression must contain the XSS attacking code.  The presence of any intervening markup between the </script> and the EL expression causes this bug to not manifest.
  2. Must be using a version of Mojarra that is subject to the vulnerability.  Any versions older than 2.2.6-SNAPSHOT and 2.1.28-SNAPSHOT are subject to the vulnerability.

Disclosure


These issues, the lack of documentation around outputText behavior within <script> or <style> blocks and the lack of output encoding when tags follow a </script> or </style> end tag, have been reported to the Oracle JSF team. The fixes are due to be released in the next JSF version:

https://java.net/jira/browse/JAVASERVERFACES-3150
https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1258

We decided to disclose these issues before the release of the patched version as we understand that this disclosure does not give any advantage to attackers already testing for XSS issues. However, by providing the vulnerable patterns as soon as possible we can help developers to better protect their applications.

CVE Id assigned is CVE-2013-5855.

 

Workaround


JSF won’t escape raw EL expressions or the <h:outputText> tag family within <script> or <style> blocks, so manual encoding is required if untrusted data is used in these contexts. We recommend using Javascript context encoders like the one in OWASP ESAPI

Also, make sure you are either using a patched JSF version, or that every </script> element has at least one intervening markup element present between it and the next EL expression, either embedded in the page, or on the right hand side of an attribute in a JSF UI Component Tag.


Conclusion


As developers we trust the libraries and frameworks we use to build our applications, and since we depend on them so strongly we don’t really have a choice. This puts the risk and responsibility on us to monitor the component projects we use and make sure we update to the latest versions when serious quality or security issues are found.

Comments
Kurt Dmello | ‎02-10-2014 06:09 AM

As far as I understand JSF never encodes #{param.xss} regardless of its poisition.  Isn't that true ?

alvaro_munoz | ‎02-10-2014 07:05 AM

Hi Kurt,

 

No, JSF wont encode #{param.xss} within script or style blocks (this is somehow surprising and undocumented but its how it behaves how its supposed to behave regarding the JSF team).

Also, and due to CVE-2013-5855, it wont encode it if #{param.xss} is right after a closing script or style tag.

 

Thanks for your comment.

A

Craig_Doremus | ‎02-21-2014 01:04 PM

Is this vulnerability exhibited by the Apache MyFaces JSF implementation too?

alvaro_munoz | ‎02-21-2014 01:10 PM

Hi Craig,

 

MyFaces does not encode outputText tags within Script or Style blocks (The bad) but it does encode correcty the outputText tags right after a script or style block (The ugly)

 

Thanks for your comment.

A

Alb3rt0c | ‎05-13-2014 11:14 AM

Why is indicated that this vulnerability provides no advantage to the attackers?

alvaro_munoz | ‎05-13-2014 11:22 AM

Hi Alberto,

 

It is stated that this "disclosure" does not provide any advantage to the attackers since they are already testing for XSS issues. In the other side its helpful for developers that may have a false sense of security.

 

Cheers,

A

Leave a Comment

We encourage you to share your comments on this post. Comments are moderated and will be reviewed
and posted as promptly as possible during regular business hours

To ensure your comment is published, be sure to follow the Community Guidelines.

Be sure to enter a unique name. You can't reuse a name that's already in use.
Be sure to enter a unique email address. You can't reuse an email address that's already in use.
Type the characters you see in the picture above.Type the words you hear.
Search
Showing results for 
Search instead for 
Do you mean 
About the Author
Featured


Follow Us
The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation.