XSRF Prevention


Cross Site Request Forgery (XSRF) is a "confused delegate" exploit that takes advantage of the ability of a web browser to make authenticated calls on a target system without the user knowing. An example exploit against Pebble might be if a user, Mallory, wanted their comment on Bobs blog automatically approved. Mallory would leave a comment, which by default would be in the pending state. Mallory would then craft a web page on her own server containing a script tag that looks like the following:

<script src="http://bobsblog.com/manageResponses.secureaction?response=c/entryid/commentid&submit=Approve"></script>

Mallory then would need to convince Bob to visit her page. If Bob did visit her page, and he also happened to be logged into Pebble at the same time, Mallory's comment would be approved without Bob knowing.

For more information, see:

Pebbles prevention

Pebble uses a few simple and generic methods for preventing XSRF attacks. Each action that is vulnerable to XSRF is annotated with @RequireSecurityToken. This instructs the HttpController to do security token validation, using SecurityTokenValidator. If the validation fails, the request is rejected, and an error page is shown saying there was no security token. The following methods of validation are used:

Double submitted cookies

This is done by generating a random token, and setting it as a cookie for the user. In addition to this, each form in Pebble includes this token as a hidden input field. This is done using the convenient <pebble:token/> tag. There are a few places where mutable actions are done by GET requests when a user clicks on a link, in this case, the <pebble:token query="true"/> can be used to add the token as a query parameter to a link. The SecurityTokenValidator checks that both this cookie is set, and the token has been submitted as a parameter, and checks that they equal each other. If they are equal, validation passes.

HTTP Header

Attackers can not set arbitrary headers in XSRF attacks. This validation method checks for a simple header, X-Pebble-Token: nocheck, and if it finds it, validation passes. This is useful for scripts that make requests on Pebble.

Signing request

Pebble sends a number of emails out containing links that will do mutable actions, for example, to approve and reject comments. In order to allow for this, a third mechanism of signing the request URI is used. A secret salt is generated for each blog, this can be obtained by calling Blog.getXsrfSigningSalt(). When generating a signed link, Pebble then sorts the query parameters alphabetically, and generates a URI that doesn't include the blog base URL or leading slash. This URI includes HTTP parameters. It then MD5s the concatenation of this URI and the salt, and base 64s that, and adds the result as a final parameter. When validating, Pebble strips the hash from the URI, and does the same process as above, checking that the hash from the URI matches the newly generated hash.

If all of the above validation methods fail, then validation of the request fails.