0
votes

I am looking for information about XSS in web applications that use JavaServer Faces. I found paper Proofing Java EE, JSP, and JSF Applications On page 48 (slide 36) called "Escaping in JSF" there is code snippet:

<f:verbatim value="#{foo}"/>

Also on page 50 (slide 38) there is description "Tags that don't escape enough" for <f:verbatim> and <h:outputlink>.

I can't reproduce XSS inside <f:verbatim> tag when use EL in web app with Facelets, probably because of auto escaping in JSF components:

CSRF, XSS and SQL Injection attack prevention in JSF

"JSF is designed to have builtin XSS prevention. You can safely redisplay all user-controlled input (request headers (including cookies!), request parameters (also the ones which are saved in DB!) and request bodies (uploaded text files, etc)) using any JSF component."

It seems that information in paper is for JSF before 2.0.

Also I found this: f:verbatim tag stops working when inside a dataTable "The <f:verbatim> tag is intented to hold plain text/HTML, not JSF components nor EL expressions."

So I don't understand how this tag could be used for XSS if it doesn't work with dynamic data from request or beans.

So I have 2 questions:

  1. Is <f:verbatim> tag safe to XSS when use tainted input from user in web application built on JSF 2.0+ and Facelets?
  2. In which situation <f:verbatim> tag "don't escape enough" in web applications built on JSF?

Example for JSF 2.0 and Facelets:

<h:form>
    testform1#{testBean.getXSS(9)}testform1
    testform2<h:outputText value="#{testBean.getXSS(10)}" escape="false" />testform2
    <f:verbatim escape="false">
        aaa#{testBean.getXSS(11)}bbb
        ccc
        <span>
            #{testBean.getXSS(12)}test
            <a>link#{testBean.getXSS(13)}</a>
            #{testBean.getXSS(14)}
        </span>
        ddd
        <script>alert(15)</script>
        eee
        <h:outputText value="#{testBean.getXSS(16)}" escape="false" />
        ddd
    </f:verbatim>
</h:form>

Test method in bean:

public String getXSS(Integer index) {
    return ("<script>alert(" + Integer.toString(index) + ")</script>");
}

Output:

            testform1&lt;script&gt;alert(9)&lt;/script&gt;testform1
            testform2<script>alert(10)</script>testform2

                aaa&lt;script&gt;alert(11)&lt;/script&gt;bbb
                ccc
                <span>
                    &lt;script&gt;alert(12)&lt;/script&gt;test
                    <a>link&lt;script&gt;alert(13)&lt;/script&gt;</a>
                    &lt;script&gt;alert(14)&lt;/script&gt;
                </span>
                ddd
                <script>alert(15)</script>
                eee

                ddd
            <input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:1" value="-7832412971090198368:1934231343887166207" autocomplete="off" />
</form>
1

1 Answers

0
votes

The referenced article/slide is from 8 june 2009. That's the era of JSF 1.2 and JSP.

JSF 2.0 was introduced december 2009. JSP was since then deprecated and replaced by Facelets. <f:verbatim> was deprecated because it's entirely useless in Facelets. JSF 2.0 on Facelets is designed to have implicit XSS prevention over all place (except of one Mojarra specific bug which is already fixed in 2.2.6, see 1st "See also" link below for detail).

In other words, ignore that article/slide. It doesn't apply on JSF 2.x at all. In future resources, doublecheck the publish date and whether the versions being treated match yours.

See also: