I have an application build on top of Mojarra 2.1.20 (package com.sun.faces, RI for JSF 2.2 specification). I have a context param javax.faces.STATE_SAVING_METHOD with value as server specified in my application deployment descriptor file web.xml
JSF is injecting the following ViewState hidden element on my post login page
<input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="random_number1:random_number2" autocomplete="off" />
The hidden element has value in some random number format and separated by a colon. Since STATE_SAVING_METHOD is server, the actual ViewState in my case is getting stored on the server. But the client is just getting the unique ViewState identifier or random numbers from the server. My understanding is that when user submits a form with this hidden element, the server extracts these random numbers, identifies the actual ViewState from these numbers and then processes the request and sends back the response to the client/user.
Based on the above understandings, I have following queries on the ViewState and its vulnerabilities-
Why two colon separated random numbers instead of one? What these two colon separated random numbers represents? What autocomplete="off" means?
Does these server generated random number map to actual ViewState stored on the server? Is this understanding correct?
Are these server generated random numbers already in encrypted format? Is encryption required on these random numbers to potentially avoid data leak and other vulnerabilities in the application?
How to encrypt these random numbers in my case when ViewState is saved on server?
Could we somehow avoid injection of the element in sources without getting displayed as hidden element?
Why two colon separated random numbers instead of one? What these two colon separated random numbers represents?
The view state is basically stored in a nested map like as Map<FirstId, Map<SecondId, ViewState>>
. This map is in turn stored in the HttpSession
. The first ID is the 'logical' view ID (basically representing XHTML page itself) and the second ID is the 'actual' view state ID.
What autocomplete="off" means?
It prevents web browsers from autofilling the value of the input element with previously submitted value from the browser cache. It should not be needed because the value is already prepopulated and the input element is a hidden type, but older Firefox versions were known to incorrectly overwrite this. Using autocomplete="off"
is basically a work around against them.
Does these server generated random number map to actual ViewState stored on the server? Is this understanding correct?
Yes.
Are these server generated random numbers already in encrypted format? Is encryption required on these random numbers to potentially avoid data leak and other vulnerabilities in the application?
No.
How to encrypt these random numbers in my case when ViewState is saved on server?
Not needed.
Could we somehow avoid injection of the element in sources without getting displayed as hidden element?
Not needed. You would in first place still need the JSESSIONID
cookie in order to be able to successfully perform view state injection. But when one already has the JSESSIONID
cookie at hands then you've anyway much bigger problems than only ViewState
tampering, such as potentially a gaping XSS hole. Moreover, in case of server side state saving the "injected" view state can only be user's own view state obtained from another page in the same HTTP session and absolutely not a random one from a completely different user/session.
Your security concern would only apply if the view state was stored in the ServletContext
(the application scope) instead of in the HttpSession
(the session scope). But this is clearly not the case.