client. JSF ViewStates are typically automatically embedded into HTML forms as hidden field with the name
javax.faces.ViewState. They are sent back to the server if the form is submitted.
javax.faces.ViewStatefield contains an id that helps the server to retrieve the correct state. In the case of MyFaces that id is a serialized Java object!
javax.faces.ViewStatefield contains a serialized Java object that is at least Base64 encoded. You might have realized by now that this is a potential road to disaster! That might be one of the reasons why nowadays JSF ViewStates are encrypted and signed before being sent to the client.The dangers of serialized Java objects
InvokerTransformerfrom commons-collections-3.2.1.jar) or even a gadget that is not yet known to the public. With said malicious gadget placed in the ViewState the attacker specifies which commands he wants to run on the server. The flexibility of what an attacker can do is limited by the powers of the available gadgets on the classpath of the server. In case of the
InvokerTransformerthe attacker can specify which command line commands should be executed on the server. The attacker in our example chose to start a calculator on the UI of our Linux based server.
com.sun.facesor with the ambiguous jar name
client. The param name does in no way give away that changing it to client introduces grave remote code execution vulnerabilities (e.g. a client-side viewstate might be used in clustered web applications).
A vulnerable web application needs to have set javax.faces.STATE_SAVING_METHOD to 'client' to enable client-side view state saving. The default value on Enterprise Application Platform (EAP) 6.4.x is 'server'. If javax.faces.STATE_SAVING_METHOD is set to 'client' a mitigation for this issue is to encrypt the view by setting com.sun.faces.ClientStateSavingPassword in the application web.xml:<context-param><param-name>javax.faces.STATE_SAVING_METHOD</param-name><param-value>client</param-value></context-param><env-entry><env-entry-name>com.sun.faces.ClientStateSavingPassword</env-entry-name><env-entry-type>java.lang.String</env-entry-type><env-entry-value>[some secret password]</env-entry-value></env-entry>
com.sun.faces.ClientStateSavingPasswordis used to change the Client State Saving Password, while the parameter up until 2.1.18 was accidentally called
ClientStateSavingPassword. So providing a Client State Saving Password as documented didn’t have an effect! In Mojarra 2.1.19 and later versions they changed the parameter name to the documented name
AESas encryption algorithm and
HMAC-SHA256to authenticate the ViewState.
javax.faces.STATE_SAVING_METHODsetting of Mojarra is
server. A developer needs to manually change it to
clientso that Mojarra becomes vulnerable to the above described attack scenario. If a serialized ViewState is sent to the server but Mojarra uses
serverside ViewState saving it will not try to deserialize it (However, a
Encryption is enabled by default. Note that encription must be used in production environments and disable it could only be valid on testing/development environments.
false. (Also it would be possible to use encryption but manually set an easy guessable password). By default the ViewState encryption secret changes with every server restart.
DESas encryption algorithm and
HMAC-SHA1to authenticate the ViewState. It is possible and recommended to configure more recent algorithms like
javax.faces.STATE_SAVING_METHODsetting of MyFaces is
server. But: MyFaces does always deserialize the ViewState regardless of that setting. So it is of great importance to not disable encryption when using MyFaces!
org.apache.myfaces.USE_ENCRYPTION) regardless if the ViewState is stored on the client or the server.