6

I'm working with codeigniter-paypal-ipn and have csrf_protection enabled. This seems to block the access from Paypal to my IPN controller. If i disable csrf_protection it works just fine, with csrf_protection enabled, paypal IPN service throws a 500 Internal Server Error.

Is there a way to solve this without disabling the csrf_protection? If not, can i disable the csrf_protection just for that controller?

Thanks.

AFRC
  • 902
  • 3
  • 9
  • 27

3 Answers3

13

I know the question has been answered, but I did it in a similar way without hacking the CI core. I added the following to my application/config/config.php file:

$config['csrf_ignore'] = array('api');

The array can include any paths you like. The example above will apply to any paths that begin with 'api'.

Then, I added the following file: application/core/MY_Input.php:

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Input extends CI_Input
{
    function _sanitize_globals()
    {   
        $ignore_csrf = config_item('csrf_ignore');

        if (is_array($ignore_csrf) && count($ignore_csrf))
        {
            global $URI;
            $haystack = $URI->uri_string();

            foreach($ignore_csrf as $needle)
            {
                if (strlen($haystack) >= strlen($needle) && substr($haystack, 0, strlen($needle)) == $needle)
                {
                    $this->_enable_csrf = FALSE;
                    break;
                }
            }           
        }

        parent::_sanitize_globals();
    }
}
/* EOF: MY_Input */
caseyamcl
  • 1,046
  • 1
  • 10
  • 18
  • Thanks case, that's a very helpful addition! – Alex Dean Oct 11 '11 at 18:07
  • Sorry to bump but I came across this answer after searching and implementing many horrible methods. This is by far, the best solution I've seen (and not just for PayPal requests!). Excellent and many thanks. – twistedpixel Nov 17 '13 at 21:26
  • This should be the accepted answer! I can't believe how simple this was to implement. Just one clarification to the above which threw me off a bit: The string applies to your controller/method for however you implement your IPN. e.g. 'paypal/ipn' would go straight to your IPN method, whereas 'paypal' would open up the whole controller. – gillytech Mar 07 '14 at 04:55
4

Alex the creator of codeigniter-paypal-ipn here. At the moment I'm not aware of a way to get the IPN post working with csrf_protection enabled. If you look at how another language/framework does it, e.g. django-paypal IPN - they add a CSRF exemption to the specific IPN controller.

As imm says, this type of fine-grained control won't be available in CodeIgniter till a version with this pull request is merged (if you can't wait, try caseyamcl's approach below as it doesn't involve hacking CI core...)

I've updated my project's README to make the CSRF situation clearer.

Alex Dean
  • 15,575
  • 13
  • 63
  • 74
2

Someone asked a similar question on http://ellislab.com/forums/viewthread/200625/, disabling csrf for a single controller will be available in the next release.

saravankg
  • 909
  • 1
  • 10
  • 21
imm
  • 5,837
  • 1
  • 26
  • 32