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:
- Is
<f:verbatim>
tag safe to XSS when use tainted input from user in web application built on JSF 2.0+ and Facelets? - 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<script>alert(9)</script>testform1
testform2<script>alert(10)</script>testform2
aaa<script>alert(11)</script>bbb
ccc
<span>
<script>alert(12)</script>test
<a>link<script>alert(13)</script></a>
<script>alert(14)</script>
</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>