Payment Gateways and CSRF protection
Changes and improvements on CSRF protection and their relation to payment gateway IPNs, that are neccessary as a new approach that creates a HttpHandler from the IPN
With great security comes great responsibility. We had tightened our security (In regards to continuous improvement from malicious attacks and request forgery) throughout Kentico 9. In one of our later hotfixes, we increased request checks to all post requests regardless of their headers. However, this created a slight problem with payment gateways IPNs.
The issue lies in the fact that the gateway itself inherits from the CMSPage class and thus is subject to CSRF protection. All posts requests are validated for a hidden field value against a cookie token value but with the way that these gateways work (which only listen to requests from a provider), this is an issue. The Payment provider is not aware of our security policy and does not send any headers much less security tokens generated by us.
This is why we created a hotfix for Kentico 10.0.3 where we check for Page.Items["CsrfProtectionDisabledOnPage"] = true. This is added as part of the out of the box gateways functionality (PayPal and Authorize.net) and can be utilized in your custom gateways as well.
Update (16.1.2018)! This workaround is no longer available in Kentico 11 and higher and API checking for this item was removed. Workaround was added due to issues with protection and payment gateways only and they have been rewritten during v11 e-commerce rebuild.
This approach, however, should only be used as a workaround! Please do not put pages out of the CSRF checks deliberately!
If you want to avoid these complications, you can consider another approach. Gateways are naturally just "receivers" and they do not have to be implemented in an aspx page at all. All they need to do is utilize Kentico API to process and finish the payment process and order.
Instead of the hotfix, you can rewrite your handlers to be http handlers which then process these requests. All you need to do is create a new class that inherits from IhttpHandler and set it up inside Kentico to be the IPN. The following is a rewrite of the PayPal IPN that we used with Kentico 9 ( for version 10 a change of namespace is required CMS.EcommerceProvider does not exist in Kentico 10, and CMS.Ecommerce.Web.UI should be used instead , but that should be all):