Search code examples
jsfprimefacesxssconfirm-dialog

XSS vulrenability in <p:confirmDialog message>


Summary: The <p:confirmDialog message> attribute does not escape HTML, hereby opening a potential XSS attack hole. How can I solve it?

Original question below (original title was: XSS Attacks : How to prevent Script injection in Response of application):


I am working JSF Application currently i am facing issue with xss attacks i have done several research on it. but not able to find the solution. i am using OWASP tool for testing. i am able to prevent xss attacks in request but not for response. For request i used filter which filters the request and giving the correct output but the response is not handled by same solution. once the response comes from application control goes to OWSAP then I am injecting Script inside it and its get displayed on the browser :(

Xhtml Code:

<p:panel header="Regions">
            <p:dataTable id="regionsTable" 
                var="region" 
                value="#{regionsBean.regions}" 
                rowKey="#{region.id}" 
                selectionMode="single" 
                selection="#{regionsBean.selectedRegion}">

                <p:column styleClass="colID">
                    <f:facet name="header">ID</f:facet>
                    <h:outputText value="#{region.id}" />
                </p:column>

                <p:column>
                    <f:facet name="header">Region</f:facet>
                    <h:outputText value="#{region.regionDescription}" />
                </p:column>


                <p:column  styleClass="colActionRegions">
                    <f:facet name="header">Action</f:facet>
                    <p:commandLink id="deleteRegionLnk"
                        oncomplete="deleteRegionConfirm.show()" update=":regionForm:dltDlg">
                        <p:graphicImage value="/resources/images/delete1616.png"/>
                        <f:setPropertyActionListener value="#{region}" target="#{regionsBean.forDelete}" />
                    </p:commandLink>
                    <p:tooltip id="toolTipDelete" for="deleteRegionLnk" value="Delete" showEffect="fade" hideEffect="fade" />
                </p:column>
    </p:dataTable>
      </p:panel>

        <p:confirmDialog id="dltDlg" message="You are about to delete the Region [#{regionsBean.forDelete.regionDescription}]. Proceed?" header="Delete Region" severity="alert" widgetVar="deleteRegionConfirm">

            <p:commandButton id="confirm" value="Yes" styleClass="iot-button" update="regionsTable,growl" oncomplete="deleteRegionConfirm.hide()" actionListener="#{regionsBean.delete}" style="color: #FFF"/>
            <p:commandButton id="decline" value="Cancel" styleClass="iot-button" onclick="deleteRegionConfirm.hide()" type="button" style="color: #FFF"/> 

        </p:confirmDialog>

response in OWSAP:

OWSAP response modification in red box If You see the above code here i am inserting alert <.script>confirm(1);<./script>. tag.

The solution which i tried :

1) Filter which is working for request not for response.

2) used escape attribute

3) Content Security Policy inside tag (i am using mozila firefox)

 <meta http-equiv="Content-Security-Policy" content="script-src  'self' https://apis.google.com;" />

Thanks For your help in advance.


Solution

  • After reading three times, your fairly convoluted question boils down to:

    The <p:confirmDialog message> attribute does not escape HTML, hereby opening a potential XSS attack hole. How can I solve it?

    This is a known issue which was already fixed since PrimeFaces 3.5. Further the <p:confirmDialog header> has also a XSS vulrenability which is only fixed since PrimeFaces 5.2 RC1. PrimeFaces is currently already available as 5.3. So, just upgrade to latest and this problem should disappear.

    If you really can't upgrade, below are your options:

    • Make sure that user-controlled input never ends up in <p:confirmDialog message>. It's only vulrenable when enduser has full control over its value.
    • Or, rebuild the older versioned JAR to include the fix.
    • Or, escape it yourself beforehand using JSTL #{fn:escapeXml()} function.

      <p:confirmDialog message="#{fn:escapeXml(bean.message)}" />
      

      Don't forget to remove after a upgrade to at least PrimeFaces 5.2, otherwise it will be double-escaped.

    To be clear, JSF is designed to have builtin XSS prevention over all place. When you discover a XSS hole while already using the most recent version of the JSF implementation or JSF library, then it's just a bug which you should by all means report to the JSF impl/library guys. See also CSRF, XSS and SQL Injection attack prevention in JSF.