From line 2 changed to line 2:
A vulnerable web application executes actions that are triggered by requests, with only a trivial check of the current users session and privileges. For example, if an application deletes a row in a database if it receives the GET request |http://example.com/delete.action?rowId=1234|, it is vulnerable to an XSRF attack if it only checks the current users privileges. The current users privileges are present in the current users HTTP session, and the session identifier cookie will automatically be send by the web browser with any request. The attacker only needs to trick the user or the browser into executing that request, maybe in a hidden frame or browser window.
A vulnerable web application executes actions that are triggered by requests, with only a trivial check of the current users session and privileges. For example, if an application deletes a row in a database if it receives the GET request |http://example.com/delete.action?rowId=1234|, it is vulnerable to an XSRF attack if it only checks the current users privileges. The current users privileges are present in the current users HTTP session, and the session identifier cookie will automatically be send by the victims web browser with any request. The attacker only needs to trick the victim or the victims browser into executing that request, maybe in a hidden frame or browser window.
From line 10 changed to line 10:
The attack may begin with a social engineering action in order to forge an HTTP request that triggers a privileged action. A typical victim is an administrator using a web-based remote management software. The attacker prepares a link that will trigger the privileged action and may embed it in an email or hide it on his website in an invisible frame. Furthermore, this link might be directly injected into the target website if the target is also vulnerable to [=>wiki://64204]. Malware is an additional source to trigger requests that exploit CSRF vulnerabilities.
The attack may begin with a social engineering action in order to forge an HTTP request that triggers a privileged action. A typical victim is an administrator using a web-based remote management software. The attacker prepares a link that will trigger the privileged action and may embed it in an email or hide it on his website in an invisible layer on top of an unsuspicious clickable element. Furthermore, this link might be directly injected into the target website if the target is also vulnerable to [=>wiki://64204]. Malware is an additional source to trigger requests that exploit CSRF vulnerabilities.
From line 12 changed to line 12:
For example the attacker may trick the logged-in user onto a password change field, to replace the current password of the administered application with one of his choosing. An additional scenario seen in practice is to log off the user from his account and silently relogin him to a fake account (known to the attacker) to later harvest the data the user entered. Certain web sites also cache unauthenticated web requests and replay them silently when the user has logged in, which is an additional cause for CSRF to happen. Recent click-jacking attacks are a variant of Cross Site Request Forgery, allowing to misuse a vulnerable version of the Flash advertisement player to hijack clicks to other webpages or silently activate web cams and microphones.
As an example, the attacker may trick the logged-in user onto a password change field, to replace the current password of the administered application with one of his choosing. An additional scenario seen in practice is to log off the user from his account and silently relogin him to a fake account (known to the attacker) to later harvest the data the user entered. Certain web sites also cache unauthenticated web requests and replay them silently when the user has logged in, which is an additional cause for CSRF to happen. Recent click-jacking attacks are a variant of CSRF, allowing to misuse a vulnerable version of the Flash advertisement player to hijack clicks to other webpages or silently activate web cams and microphones.
From line 14 changed to line 14:
Unfortunately a lot of web-sites offer a "Remember Me on this computer" feature, which dramatically increases CSRF exploitability. If, for example, a "Remember Me" cookie that authenticates the user automatically will be send with every request, the user is vulnerable even if the target website is not "open" in her browser. Any malicious website or e-mail can then trick the user into clicking a link that executes a privileged and automatically authorized action.
Unfortunately a lot of web-sites offer a "Remember Me on this computer" feature, which dramatically increases CSRF exploitability. If, for example, a "Remember Me" cookie that authenticates the victim automatically will be send with every request, the user is vulnerable even if the target website is not "open" in her browser. Any malicious website or e-mail can then trick the victim into clicking a link that executes a privileged and automatically authorized action.
From line 18 changed to line 18:
Users should log off from an application as soon as the privileged actions have been completed. The less time the user spends in “privileged” mode, the less vulnerable the user is. Bookmarkable logoff buttons increase the usability of this precaution. On the other hand, a "Remember Me" feature contradicts this goal. Users should be encouraged to utilize the "Remember Password" feature of their browser instead, so that they can easily log-in with one click, with a pre-filled login form. This provides a balance between security - no fully automated authorization will occur - and convenience. On modern operating systems, login data and passwords remembered by browsers will even be stored encrypted in a central keychain or wallet.
Users should log off from an application as soon as the privileged actions have been completed. The less time the user spends in “privileged” mode, the less vulnerable the user is. Bookmarkable logoff buttons, or logout keyboard shortcuts increase the usability of this precaution. On the other hand, a "Remember Me" feature contradicts this goal. Users should be encouraged to utilize the "Remember Password" feature of their browser instead, so that they can easily log-in with one click, with a pre-filled login form. This provides a balance between security - no fully automated authorization will occur - and convenience. On modern operating systems, login data and passwords remembered by browsers will even be stored encrypted in a central keychain or wallet.
From line 20 changed to line 20:
On the server side some half-solutions have been proposed, such as allowing POST requests only to prevent drive-by changes triggered by simple GET link clicks. Of course, POST requests can also be forged, so this solution is not sufficient. Also, referrer checking does not provide a complete solution, as intermediate web proxies or client security products may block certain HTTP headers such as referrers. Referrer checking does also not block attacks which are caused by cross site scripting problems, with malicious links injected directly into the target web site.
On the server side some half-solutions have been proposed, such as allowing POST requests only, to prevent drive-by changes triggered by simple GET link clicks. Of course, POST requests can also be forged, so this solution is not sufficient. Also, referrer checking does not provide a complete solution, as intermediate web proxies or client security products may block certain HTTP headers such as referrers. Referrer checking does also not block attacks which are caused by cross site scripting problems, with malicious links injected directly into the target web site.
From line 32 changed to line 32:
+++ Protecting JSF POSTbacks
+++ Protecting JSF postbacks
From line 34 added to lines 34 to 35:
JSF tries to ensure that an event is legitimate by requiring a serialized representation of the component tree to be present at the time the form is submitted. Where that component tree is stored depends on the type of state saving that is in use. In client-side state saving, the serialized component tree is stored in the hidden form field |javax.faces.ViewState| and submitted along with the form. In server-side state saving, the serialized component tree is stored in the user's session and an auto-generated identifier token, passed through the hidden form field |javax.faces.ViewState|, is used to identify the component tree object in the users server-side session.
From line 48 changed to line 50:
The important part - the "per-request security token" - is the second hidden field: When the form is submitted, the value |j_id3| will be transfered to the server in a POST request. The server will now first validate the users current HTTP session, which has been identified through the automatically transmitted cookie. Inside that session, the "view state" with the identifier |j_id3| has to be present, or the request will be aborted. This validates that the request originated from the form that has been presented to the user, and has not been forged by an attacker and that the request is not simply "riding" the existing HTTP session.
Here we are assuming the use of server-side state saving. The important part - the "per-request security token" - is the second hidden field: When the form is submitted, the value |j_id3| will be transfered to the server in a POST request. The server will now first validate the users current HTTP session, which has been identified through the automatically transmitted cookie. Inside that session, the "view state" with the identifier |j_id3| has to be present, or the request will be aborted. This validates that the request originated from the form that has been presented to the user, and has not been forged by an attacker and that the request is not simply "riding" the existing HTTP session.
From line 50 changed to line 52:
Unfortunately, the view state identifier is an automatically generated incremented value and quite easy to guess by an attacker. A better solution would be a [cryptographically secure pseudorandom number=>http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator]. As this is dependent on the JSF implementation (this example was created with the Sun JSF RI), a more secure CSRF protection for POST requests is possible with specification compliance.
Unfortunately, the view state identifier is an automatically generated incremented value and quite easy to guess by an attacker. The value is always:
From line 52 added to lines 54 to 79:
`'j_id' + a sequential number`
where the sequential number is the number of views in the user's session (always starting at 1). Thus, it's possible to coerce an unassuming user with a valid session into submitting a form of the attackers choosing.
A better solution would be a [cryptographically secure pseudorandom number=>http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator]. As this is dependent on the JSF implementation (this example was created with the Sun JSF RI), a more secure CSRF protection for POST requests is possible with specification compliance.
Going beyond the use of a random number of the view state token, the most appropriate way of securing a postback is to use a public-private key cryptology negotiation. See Seam's |<s:token>| component tag for an explanation of this solution.
Even worse, client-side state saving is extremely easy to hijack since the component tree is stored on the client. All the attacker needs to have is the signature of the component tree and he can replay and send a valid POST request to the server. The server will restore the view by deserializing the data sent by the client and execute the action. We recommend that you do not use client-side state saving without additional per-request security tokens, see Seam's |<s:token>| tag.
+++ Build on demand of the JSF component tree
In client-side state saving, the restore view step is independent of the user's session. All the state necessary to rebuild the view and process the user-initiated event is sent along in the form POST request. The user could load the form on one day and submit it days later assuming that other session data isn't required (e.g., a login or comment form usually works without requiring a logged-in session).
This portability is not present in server-side state saving. The browser merely sends an identifier for looking up the component tree in the session. Without the session, there is no component tree. When that happens, the only reasonable thing for JSF to do is to throw and |ViewExpiredException| or simply render the page without processing any events.
...that is, until Facelets came along. Facelets offers a "solution" to the stale form problem. By setting the |facelets.BUILD_BEFORE_RESTORE| context-param to true, you can have Facelets reconstruct the component tree in the RESTORE VIEW phase if the one in the session has expired (or the session as a whole has expired). This would seem to match the behavior of client-side state saving. It does not. The reason is that the contract of requiring an existing view state to exist is now absent and a postback is no different than a GET-requested page action. A form on a plain HTML page can now submit a POST request directly to a JSF application (you do need an empty |javax.faces.ViewState| hidden field for it to work).
If you are enabling this global Facelets option, your application is wide open to CSRF attacks.
To make things even more troubling, Facelets has become the standard view handler in JSF 2.0 and this behavior of Facelets is now the default. So what do we do?
Well, as it turns out, because of a recent specification change, the "build before restore" feature has been inadvertently disabled in Mojarra (the JSF reference implementation), so we may not have to worry about it after all in JSF 2.0. See [Mojarra Issue 1028=>https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1028].
A built-on demand of the component tree on the server is only secure if we can ensure that the request is coming from a valid source. Hence, the Seam |<s:token>| support should always be used if you enable "build before restore".
From line 54 changed to line 82:
Seam allows actions to be invoked when a page is requested using a feature known as page actions. A page action is a method expression that is tied to a JSF view ID and is invoked before the Render Response phase on an NonFaces ("GET") request. A page action in Seam is defined in the |pages.xml| descriptor:
Seam allows actions to be invoked when a page is requested using a feature known as page actions. A page action is a method expression that is tied to a JSF view URI and is invoked before the RENDER RESPONSE phase on an NonFaces ("GET") request. A page action in Seam is defined in the |pages.xml| descriptor:
From line 60 changed to line 88:
When a GET request is processed for the URL |http://example.com/myPage.seam|, the action will be executed. Page actions are both a blessing and a curse. They are a better substitutes for filters since they can be associated with a view ID regardless of the request life cycle leading up to it being requested. They can also be tied into the declarative JSF navigation system. However, their downfall is that they can be easily abused. Unlike a postback, they do not require a page to have been viewed previously (i.e., an established javax.faces.ViewState). A page action is an CSRF attack vector if:
When a GET request is processed for the URL |http://example.com/myPage.seam|, the action will be executed. Page actions are both a blessing and a curse. They are a better substitutes for filters since they can be associated with a view URI regardless of the request life cycle leading up to it being requested (bookmarkable). They can also be tied into the declarative JSF navigation system. However, their downfall is that they can be easily abused. Unlike a JSF POSTback, they do not require a page to have been viewed previously (i.e., an established javax.faces.ViewState). A page action is an CSRF attack vector if:
From line 66 changed to line 94:
In general, GET requests should not trigger unsafe actions. It's reasonable to use a page action to preload data or confirm a registration from an e-mail, but it's inappropriate to use a page action for operations that manipulate sensitive or secure data, such as transfer money between accounts. Whenever sensitive data is involved, it's important to provide a "splash page" that confirms the action and the user's intent to perform it.
In general, GET requests should not trigger unsafe actions. It's reasonable to use a page action to preload data but it's inappropriate to use a page action for operations that manipulate sensitive or secure data, such as transfer money between accounts. Whenever sensitive data is involved, it's important to provide a "splash page" that confirms the action and the user's intent to perform it.
From line 68 changed to line 96:
A GET request should be idempotent and repeatable and it should not make changes to persistent (database) state. If you absolutely can not avoid assigning an unsafe action to a page, you need to add an additional random token as a parameter and validate it against the value stored in the users session. This is effectively a secondary session identifier which is, unlike the session cookie, not transmitted automatically by the browser and hence needs to be obtained by an attacker to forge a valid malicious request.
A GET request should be idempotent and repeatable and it should not make changes to persistent (database) state. If you absolutely can not avoid assigning an unsafe action to a view URI, you need to add an additional random token as a parameter and validate it against the value stored in the users session. This is effectively a secondary session identifier which is, unlike the session cookie, not transmitted automatically by the browser and hence needs to be obtained by an attacker to forge a valid malicious request.
From line 72 changed to line 100:
+++ Exposing Javascript actions through @WebRemote
+++ Exposing JavaScript actions through @WebRemote
From line 74 changed to line 102:
If you annotate a Seam component method with |@WebRemote|, Seam will generate a Javascript interface that you can use to call that method directly from the client. This method call is wrapped in an HTTP POST request. The session identifier cookie will be transmitted automatically to the server.
If you annotate a Seam component method with |@WebRemote|, Seam will generate a JavaScript interface that you can use to call that method directly from the client. This method call is wrapped in an HTTP POST request. The session identifier cookie will be transmitted automatically to the server.
From line 78 changed to line 106:
Seam Remoting with Javascript currently offers no automatic protection against CSRF!
Seam Remoting with JavaScript currently offers no automatic protection against CSRF!
From line 80 changed to line 108:
++ Further Reading
+++ Seam's |<s:token>| protection feature
From line 82 changed to line 110:
[=>http://www.owasp.org/index.php/Cross-Site_Request_Forgery] is OWASP's description of CSRF, illustrating how images can be used to conduct CSRF attacks
Seam (starting with 2.1.2RC1) introduces the UI component tag |<s:token>| to secure JSF form POST requests against CSRF attacks. (NOTE: If the solution below is implemented in JSF 2, then Seam does not need to provide a custom solution and we'll remove |<s:token>| from Seam. However, we still need to implement something equivalent for Seam Remoting.)
From line 84 changed to line 112:
[=>http://en.wikipedia.org/wiki/Csrf]
The |<s:token>| UI component performs validation in two steps:
From line 86 changed to line 114:
[=>http://cwe.mitre.org/data/definitions/352.html] describes the classification of XSS within the Common Weakness Enumeration System of the National Vulnerability Database (NVD)
1. When rendered, it assigns a unique identifier to the browser using a cookie that lives until the end of the browser session. This is roughly the browser's private key. The |<s:token>| tag is used inside of an |<h:form>| and generates a hidden form field named |javax.faces.FormSignature.| The form signature is calculated as follows:
From line 88 changed to line 116:
[=>http://www.cgisecurity.com/articles/csrf-faq.shtml] answers typical CSRF related questions
`sha1( signature = viewId + "," + formClientId, salt = clientUid )`
From line 90 changed to line 118:
[=>http://www.owasp.org/index.php/CSRF_Guard] is a server side framework to prevent CSRF within JEE applications
The developer can also choose to incorporate the session identifier into this hash for a more secure token (at the cost of binding it to the session):
From line 92 changed to lines 120 to 139:
[=>http://directwebremoting.org/blog/joe/2007/10/29/web_application_security.html] is an illustrative talk that will help you to get familiar with CSRF
`sha1( signature = viewId + "," + formClientId + "," + sessionId, salt = clientUid )`
2. When the form is submitted, the hash is recreated on the server and compared against the value of the |javax.faces.FormSignature| parameter. If validation fails, an |org.jboss.seam.ui.UnauthorizedCommandException| will be thrown.
When a form with |<s:token>| is rendered, a JavaScript check is used to validate cookie support in the browser. If cookies are disabled, a warning is presented to the user. This warning will let the user know that the form POSTback will fail if cookies are not enabled.
See the [forum discussion thread=>http://http://www.seamframework.org/Community/NewComponentTagStokenAimedToGuardAgainstCSRF] for usage and caveats.
++ Further Reading
= [OWASP Top 10 for Java EE=>https://www.owasp.org/images/8/89/OWASP_Top_10_2007_for_JEE.pdf]
= [Session Riding=>http://www.securenet.de/papers/Session_Riding.pdf] by Thomas Schreiber - *a must read!*
= [Cross Site Reference Forgery=>http://www.isecpartners.com/files/XSRF_Paper_0.pdf] by Jesse Burns
= [=>http://www.owasp.org/index.php/Cross-Site_Request_Forgery] is OWASP's description of CSRF, illustrating how images can be used to conduct CSRF attacks
= [Wikipedia article on CSRF=>http://en.wikipedia.org/wiki/Csrf]
= [=>http://cwe.mitre.org/data/definitions/352.html] describes the classification of XSS within the Common Weakness Enumeration System of the National Vulnerability Database (NVD)
= [=>http://www.cgisecurity.com/articles/csrf-faq.shtml] answers typical CSRF related questions
= [=>http://www.owasp.org/index.php/CSRF_Guard] is a server side framework to prevent CSRF within JEE applications
= [=>http://directwebremoting.org/blog/joe/2007/10/29/web_application_security.html] is an illustrative talk that will help you to get familiar with CSRF