Tuesday, January 12, 2016

Request parameter "_method" may lead to CakePHP CSRF Token Bypass

In CakePHP we noticed that under certain circumstances is it possible to bypass the built-in security checks offered by CSRF and anti-tampering.

As stated in the official documentation "By using the Security Component you automatically get CSRF and form tampering protection" [1], however this is not true in case a form controller does not check whether the request is a 'POST' or 'PUT' using $this->request->is().

This because CSRF protection is only applied to specific methods e.g POST and PUT HTTP Methods. In Addition by leveraging the HTTP method overriding feature defined into the CakeRequest::_processPost() method, is possible to overwrite the original request method with an arbitrary method chosen by the attacker.

The following one is the original proof of concept that we sent to the CakePHP team, were by abusing the "_method" parameter is possible to specify and arbitrary method e.g. "CSRF" that is not checked against CSRF.

CSRF Bypass proof of Concept


The vulnerability can be exploited by tricking a victim user (currently logged into a vulnerable application) into visiting a web page like this:

<html>
<body>
<form action="http://[HOST]/user/add" method="POST">
<input name="_method" type="hidden" value="CSRF" />
<input name="user" type="hidden" value="hacker" />
<input name="password" type="hidden" value="pwd" />
</form>
<script>document.forms[0].submit()</script>
</body>
</html>


This affects CakePHP 2.x:
And similarly affects also CakePHP 3.x:

Thanks to our feedback, developers of CakePHP have issued this patch:

It's important to mention that this patch implemented by CakePHP team now allows only GET, HEAD, OPTIONS methods to be left unprotected: indeed this is a partial fix. Of course the previous proof of concept will no longer work , however with little modifications e.g. <input name="_method" type="hidden" value="HEAD" /> attackers will still have the job done.

Developers  should check HTTP method carefully

 

The official documentation has also been updated


Now we see in here the written evidence that developers should properly check request HTTP methods before processing the request. To not be vulnerable to trivial CSRF attacks be sure that your CakePHP application always checks HTTP methods, as now correctly stated in the updated documentation [2]

The important note regarding the mandatory check is:

 "You should always verify the HTTP method being used before executing side-effects. You should check the HTTP method or use Cake\Network\Request::allowMethod() to ensure the correct HTTP method is used."

References:


[1] http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html
[2] http://book.cakephp.org/3.0/en/controllers/components/csrf.html

Vulnerability Found and Reported by Egidio Romano