Skip to content

Backend Security key broken for controllers with frontname not equal to route ID #7557

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
AlexandreKhayrullin opened this issue Nov 24, 2016 · 14 comments
Assignees
Labels
bug report Fixed in 2.2.x The issue has been fixed in 2.2 release line Fixed in 2.3.x The issue has been fixed in 2.3 release line Issue: Clear Description Gate 2 Passed. Manual verification of the issue description passed Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development Progress: PR Created Indicates that Pull Request has been created to fix issue Reproduced on 2.1.x The issue has been reproduced on latest 2.1 release Reproduced on 2.2.x The issue has been reproduced on latest 2.2 release Reproduced on 2.3.x The issue has been reproduced on latest 2.3 release

Comments

@AlexandreKhayrullin
Copy link

Preconditions

The Magento used is the "develop" branch.
PHP: PHP 7.0.10-1+deb.sury.org~xenial+1

Steps to reproduce

  1. Create a new module with a controller usable in the backend.
  2. Define a new route for the controller (new adminhtml/routes.xml file) with a frontname different from the route ID.
  3. Add the new controller to the menu and add the appropriate item to the ACL.
  4. Log into the backend, locate the new item and click on it.

Expected result

  1. The new controller is executed.

Actual result

  1. The user is redirected back to the dashboard.

After a debugging session, it appears that the security key is incorrectly generated during either the creation of backend URLs or the security key validation.

If you place a breakpoint at the last line of \Magento\Backend\Model\Url::getSecretKey(), you'll notice the following discrepancy:

  • While generating the security key used during the creation of the URL, the "$secret" string (the one that is hashed to form the security key) starts with the frontname.
  • While checking the security key after having clicked on the link, the "$secret" string starts with the route ID instead.
@magento-engcom-team magento-engcom-team added bug report develop Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed labels Sep 11, 2017
@flancer64
Copy link
Contributor

These are stack traces and secret sources for hashing in my case (Magento ver. 2.2.0-rc30).

Secret key generation for navigation links:
secret_generate

Secret key validation on route action:
secret_validate

My module's descriptors for routes & menu:

./etc/adminhtml/routes.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">

        <route id="fl32_login_as_route" frontName="loginas">
            <module name="Flancer32_LoginAs"/>
        </route>

    </router>
</config>

./etc/adminhtml/menu.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
    <menu>
        <add id="Flancer32_LoginAs::customer_logged"
                module="Flancer32_LoginAs"
                action="loginas/logged"/>
    </menu>
</config>

@magento-engcom-team magento-engcom-team added the Issue: Clear Description Gate 2 Passed. Manual verification of the issue description passed label Oct 13, 2017
@magento-engcom-team magento-engcom-team self-assigned this Oct 13, 2017
@magento-engcom-team magento-engcom-team added 2.1.x Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed labels Oct 13, 2017
@magento-engcom-team
Copy link
Contributor

@AlexandreKhayrullin, thank you for your report.
We've created internal ticket(s) MAGETWO-81949 to track progress on the issue.

@magento-engcom-team magento-engcom-team added Reproduced on 2.1.x The issue has been reproduced on latest 2.1 release Reproduced on 2.2.x The issue has been reproduced on latest 2.2 release Reproduced on 2.3.x The issue has been reproduced on latest 2.3 release labels Oct 13, 2017
@magento-engcom-team
Copy link
Contributor

Hi @AlexandreKhayrullin

This ticket has been marked as "Triage Wanted" due to low user involvement over time. Over the next 2 weeks we are looking for additional community feedback to decide if it should be archived or not. More information on this is available on the GitHub wiki.

Thank you for collaboration.

lfolco added a commit to lfolco/magento2 that referenced this issue Aug 15, 2018
@lfolco
Copy link
Contributor

lfolco commented Aug 15, 2018

I have a commit that I'm testing, please don't close this.

lfolco added a commit to lfolco/magento2 that referenced this issue Aug 16, 2018
lfolco added a commit to lfolco/magento2 that referenced this issue Aug 16, 2018
@magento-engcom-team magento-engcom-team added Progress: PR Created Indicates that Pull Request has been created to fix issue and removed triage wanted labels Aug 20, 2018
@ishakhsuvarov ishakhsuvarov added the Fixed in 2.3.x The issue has been fixed in 2.3 release line label Sep 11, 2018
@sidolov sidolov closed this as completed Sep 22, 2018
@romanrabotaet
Copy link

romanrabotaet commented Apr 3, 2019

Fix is wrong in 2.2.8.
code in 2.2.8
protected function _callbackSecretKey($match)
{
$routeId = $this->routeConfig->getRouteByFrontName($match[1]);
return \Magento\Backend\Model\UrlInterface::SECRET_KEY_PARAM_NAME . '/' . $this->_url->getSecretKey(
$routeId,
$match[2],
$match[3]
);
}

code in 2.3
protected function _callbackSecretKey($match)
{
$routeId = $this->routeConfig->getRouteByFrontName($match[1]);
return \Magento\Backend\Model\UrlInterface::SECRET_KEY_PARAM_NAME . '/' . $this->_url->getSecretKey(
$routeId?:$match[1],
$match[2],
$match[3]
);
}

@richardgrey-netxtra
Copy link

Had this issue after upgrading to 2.2.8. Caused problems if the admin/startup/menu_item_id is set to redirect to a specific page after login, I was unable to access any of the adminhtml routes and was redirected back to the page defined in admin/startup/menu_item_id.

@chrisputnam9
Copy link

Definitely still broken in 2.2.8 - can this be re-opened @sidolov ?

@sidolov
Copy link
Contributor

sidolov commented Jun 12, 2019

Hi @chrisputnam9 , yes, we should reopen it if the issue still reproducing

@novikor
Copy link
Contributor

novikor commented Sep 3, 2019

Still is being reproduced on 2.3.1.

I`ll reopen and fix it when I have some time.

@novikor novikor self-assigned this Sep 3, 2019
@m2-assistant
Copy link

m2-assistant bot commented Sep 3, 2019

Hi @novikor. Thank you for working on this issue.
Looks like this issue is already verified and confirmed. But if you want to validate it one more time, please, go though the following instruction:

  • 1. Add/Edit Component: XXXXX label(s) to the ticket, indicating the components it may be related to.

  • 2. Verify that the issue is reproducible on 2.3-develop branch

    Details- Add the comment @magento give me 2.3-develop instance to deploy test instance on Magento infrastructure.
    - If the issue is reproducible on 2.3-develop branch, please, add the label Reproduced on 2.3.x.
    - If the issue is not reproducible, add your comment that issue is not reproducible and close the issue and stop verification process here!

  • 3. If the issue is not relevant or is not reproducible any more, feel free to close it.


@vasilii-b
Copy link

vasilii-b commented Jul 19, 2024

2024, Magento 2.4.6-p6 - same dam issue!

image

The issue is reproducible when creating urls from the UI Components.

Example

<column name="download" class="Vendor\Name\Ui\Component\Listing\Columns\Download">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>                 
                    <item name="label" xsi:type="string" translate="true">Download Link</item>
                </item>
            </argument>
        </column>
<?php

declare(strict_types=1);

namespace Vendor\Name\Ui\Component\Listing\Columns;

use Magento\Framework\UrlInterface;
use Magento\Ui\Component\Listing\Columns\Column;
use Magento\Framework\View\Element\UiComponentFactory;
use Vendor\Name\Data\QueueInterface;
use Magento\Framework\View\Element\UiComponent\ContextInterface;

class Download extends Column
{
    /**
     * @var UrlInterface
     */
    private $urlBuilder;

    private const URL_PATH_EDIT = 'order_history/export/download';

    /**
     * Download constructor.
     *
     * @param ContextInterface $context
     * @param UiComponentFactory $uiComponentFactory
     * @param UrlInterface $urlBuilder
     * @param array $components
     * @param array $data
     */
    public function __construct(
        ContextInterface $context,
        UiComponentFactory $uiComponentFactory,
        UrlInterface $urlBuilder,
        array $components = [],
        array $data = []
    ) {
        parent::__construct($context, $uiComponentFactory, $components, $data);
        $this->urlBuilder = $urlBuilder;
    }

    /**
     * Prepare Data Source
     *
     * @param array $dataSource
     * @return array
     */
    public function prepareDataSource(array $dataSource): array
    {
        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as &$item) {
                $name = $this->getData('name');
                if (isset($item[QueueInterface::IS_GENERATED]) && $item[QueueInterface::IS_GENERATED] == 1) {
                    $item[$name] = html_entity_decode(sprintf(
                        "<a href='%s' target='_blank'>%s</a>",
                        $this->urlBuilder->getUrl(
                            self::URL_PATH_EDIT,
                            ['filename' => $item['filename']]
                        ),
                        __('Download')
                    ));
                } else {
                    $item[$name] = '';
                }
            }
        }
        return $dataSource;
    }
}
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">
        <route id="digital_order_history" frontName="order_history">
            <module name="Vendor_Name" before="Magento_Backend" />
        </route>
    </router>
</config>

When adding the custom URL in the admin menu, for example, it works w/o problems.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
    <menu>
        <add
            id="Vendor_Name::order_history_export"
            title="Export Queue"
            module="Vendor_Name"
            sortOrder="20"
            parent="Vendor_Name::order_history_operation"
            action="order_history/export/queue"
            resource="Magento_Sales::sales_order"
        />
    </menu>
</config>

cc @sidolov

@tufahu
Copy link
Contributor

tufahu commented Mar 3, 2025

Yes the problem is with \Magento\Backend\Model\Url::getUrl() uses frontName for secretKey generation and when we want to call the controller action secretKey validation runs with router id , so mismatch happens.

The only solution is to use same id and frontName at backend :\ good to know

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug report Fixed in 2.2.x The issue has been fixed in 2.2 release line Fixed in 2.3.x The issue has been fixed in 2.3 release line Issue: Clear Description Gate 2 Passed. Manual verification of the issue description passed Issue: Confirmed Gate 3 Passed. Manual verification of the issue completed. Issue is confirmed Issue: Format is valid Gate 1 Passed. Automatic verification of issue format passed Issue: Ready for Work Gate 4. Acknowledged. Issue is added to backlog and ready for development Progress: PR Created Indicates that Pull Request has been created to fix issue Reproduced on 2.1.x The issue has been reproduced on latest 2.1 release Reproduced on 2.2.x The issue has been reproduced on latest 2.2 release Reproduced on 2.3.x The issue has been reproduced on latest 2.3 release
Projects
None yet
Development

No branches or pull requests