Magento – How to bypass CSRF validation for certain requests

csrfmagento2.3validation

I am trying to bypass the CSRF validation for my Controller. I had seen a few workaround in the below links.

Magento 2.3 upgrade breaks HTTP POST requests to custom module endpoint

But I need my Module compatible with both Magento 2.2 and 2.3. So, I had overridden a core file Magento\Framework\App\Request\Http like below

public function isAjax()
{
   if ($this->getRequestUri() == 'custom/url') {
        return true;
   }
    if ($this->isXmlHttpRequest()) {
        return true;
    }
    if ($this->getParam('ajax') || $this->getParam('isAjax')) {
        return true;
    }
    return false;
}

To bypass the validateRequest() function in Magento\Framework\App\Request\CsrfValidator

private function validateRequest(
    HttpRequest $request,
    ActionInterface $action
): bool {
    $valid = null;
    if ($action instanceof CsrfAwareActionInterface) {
        $valid = $action->validateForCsrf($request);
    }
    if ($valid === null) {
        $valid = !$request->isPost()
            || $request->isAjax()
            || $this->formKeyValidator->validate($request);
    }

    return $valid;
}

It was working fine. I want to know does it affect the technical review in the Magento Marketplace in any way (or) is there any other better way. Thanks in advance.

Best Answer

Answer #1: I'd recommend creating a webapi endpoint instead of an ajax controller. If you look at Magento core, the checkout is has many ajax calls and they all point to webapi endpoints which are defined in vendor/magento/module-checkout/etc/webapi.xml. You can define resources to make access to the controller as public or as restricted as you want.

Answer #2: Make sure that your form key is being properly submitted and check for any other requirements.

Answer #3: Maybe the easiest but absolutely one I don't recommend. However, since it works, I'll post it here. See code below.

<?php

namespace Foo\Bar\Controller\Baz;

use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Request\InvalidRequestException;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Controller\ResultInterface;

/**
 * Class Index
 *
 * @package Foo\Bar\Controller\Baz
 */
class Index extends Action implements \Magento\Framework\App\CsrfAwareActionInterface
{
    /**
     * @return ResponseInterface|ResultInterface
     */
    public function execute()
    {
        /** @var ResultInterface $result */
        $result = $this->resultFactory->create(ResultFactory::TYPE_JSON);
        $result->setData(['whatever data']);

        return $result;
    }

    /**
     * @param RequestInterface $request
     *
     * @return bool|null
     */
    public function validateForCsrf(RequestInterface $request): ?bool
    {
        return true;
    }

    /**
     * @param RequestInterface $request
     *
     * @return InvalidRequestException|null
     */
    public function createCsrfValidationException(RequestInterface $request): ?InvalidRequestException
    {
        return null;
    }
}
Related Topic