Flawed CSRF Protections


Before going into the details and the vulnerability in WordPress, I need to say all of credit should go to Gareth Heyes, he talked about CSS Overlays before, but shame on me that I missed his point in the first place. When I looked into his new tool PoC for CSRF bypass in delicious, I realised that, this is a big deal. I know the exploitation requires lots of stuff but it's still important and this is something which can be fixed in server-side, therefore it should be fixed.

There are two common and wrong implementations of CSRF widely deployed;

  1. CSRF Protection which requires confirmation if token / nonce doesn't match.
    For example WordPress CSRF protection.
  2. Form loads with default values thru POST or GET and then generates a new nonce and show you the form with this new nonce.
    For example delicious.

First one is a smelly implementation, any security minded person won't love it even though they couldn't come up with an exploit.

Second one is quite legitimate and common usage and sometimes it's pretty hard to build some functionality without doing this.

Why WordPress is vulnerable?

Because if you do a request with a wrong token / nonce then WordPress will show a confirmation page with a new correct nonce. User need to click "yes" to confirm request. WordPress should cancel the request and error instead of a show a confirmation page to continue. I assume the motivation of WordPress developers was allow users to a more user friendly environment in case of nonce got lost in session or something like that. Generally it's a bad idea to try to fix stuff instead of rejecting them, and in here it's proven again. 

How to Exploit?

  1. Just like a CSRF attack, prepare your attack,
  2. Point your attack to victim' s domain (GET or POST) in an iframe,
  3. Iframe should mask everything but confirmation or save button. This can be done in several ways. The most efficient way is potentially using absolutely positioned divs and inner iframes.
  4. Now user should click this button to carry out final confirmation. This bit might require a bit social engineering.

Obviously final step can not be automated by JavaScript, if you can then it'd a bigger issue, ability to bypass SOP (same-origin policy).

WordPress Exploit and Screenshot

WordPress CSRF Bypass Exploit, to able to test you need to modify form, details and target action. This exploit tested in default installation of WordPress and if admin GUI template or styles changes (unlikely) it's not going to work.

Picture below is from an actual exploit test, and Yes button is coming from WordPress server. When victim clicks it attacker can change admin's e-mail and password.

This is the response after victim clicks yes button. It's not perfect but no one is going to be suspicious because yes button turned to blue.

Patch / Solution for WordPress

This is an unofficial patch, I just scraped it to fix the problem quickly and I relied on that this is the only function deals with this issue.
Go to /includes/functions.PHP replace wp_nonce_ays() function with the new one below.

function wp_nonce_ays($action) {
    global $pagenow, $menu, $submenu, $parent_file, $submenu_file;
    $title = __('WordPress Nonce Error ');
    wp_die('WordPress Nonce Error', $title);

That's it. This will fix the problem. Now you will see a static error message instead of a confirmation page.

What Now?

I bet there are lots of other applications which are vulnerable to either of these CSRF Protection Bypass vulnerabilities.


Recent Blog Posts

See all of the blog posts