Bug #91217

hmac-error due to different sorting in config

Added by David Bruchmann 9 months ago. Updated 9 months ago.

Status:
Closed
Priority:
Should have
Assignee:
-
Category:
Backend User Interface
Target version:
-
Start date:
2020-04-28
Due date:
% Done:

0%

Estimated time:
TYPO3 Version:
9
PHP Version:
7.2
Tags:
hmac, hash, backend, ajax
Complexity:
easy
Is Regression:
Sprint Focus:

Description

I have a case where I have the same array-keys and the same values but different sorting in the config-array.
Array original is this:


"config":{
      ....
      "appearance":{
            ....
            "enabledControls":{
                "info":true,
                "new":true,
                "dragdrop":true,
                "sort":true,
                "hide":true,
                "delete":true,
                "localize":true,
                "0":"info",
                "1":"new",
                "2":"dragdrop",
                "3":"sort",
                "4":"hide",
                "5":"delete",
                "6":"localize" 
            }
            ....
      }
      ....
}

and after ajax-call on server-side its sorted like this:


"config":{
      ....
      "appearance":{
            ....
            "enabledControls":{
                "0":"info",
                "1":"new",
                "2":"dragdrop",
                "3":"sort",
                "4":"hide",
                "5":"delete",
                "6":"localize",
                "info":true,
                "new":true,
                "dragdrop":true,
                "sort":true,
                "hide":true,
                "delete":true,
                "localize":true
            }
            ....
      }
      ....
}

Therefore the hash-comparison fails and the form can't be used.

Attached extension adds a field in table news for content-elements. It can be found in tab "Extra". Clicking on one of both buttons is triggering the error.
Changing the method TYPO3\CMS\Backend\Form\Container\InlineControlContainer::render()
from:

        $this->inlineData['config'][$nameObject] = [
            'table' => $foreign_table,
            'md5' => md5($nameObject)
        ];
        $this->inlineData['config'][$nameObject . '-' . $foreign_table] = [
            'min' => $config['minitems'],
            'max' => $config['maxitems'],
            'sortable' => $config['appearance']['useSortable'],
            'top' => [
                'table' => $top['table'],
                'uid' => $top['uid']
            ],
            'context' => [
                'config' => $config,
                'hmac' => GeneralUtility::hmac(json_encode($config), 'InlineContext'),
            ],
        ];

to this:

        $this->inlineData['config'][$nameObject] = [
            'table' => $foreign_table,
            'md5' => md5($nameObject)
        ];
        $configAltered = $config;
        if (isset($configAltered['appearance']['enabledControls'])) {
            $enabledControls = $configAltered['appearance']['enabledControls'];
            $tmpIntVals = [];
            $tmpStrVals = [];
            foreach ($enabledControls as $key => $enabledControl) {
                if (MathUtility::canBeInterpretedAsInteger($key)) {
                    $tmpIntVals[$key] = $enabledControl;
                } else {
                    $tmpStrVals[$key] = $enabledControl;
                }
            }
            $configAltered['appearance']['enabledControls'] = array_merge($tmpIntVals, $tmpStrVals);
        }
        $this->inlineData['config'][$nameObject . '-' . $foreign_table] = [
            'min' => $configAltered['minitems'],
            'max' => $configAltered['maxitems'],
            'sortable' => $configAltered['appearance']['useSortable'],
            'top' => [
                'table' => $top['table'],
                'uid' => $top['uid']
            ],
            'context' => [
                'config' => $configAltered,
                'hmac' => GeneralUtility::hmac(json_encode($configAltered), 'InlineContext'),
            ],
        ];

... is sorting the concerned array in advance and the hashes are the same on client and server.
The code id neither nice, nor does it take other array-parts in consideration as I primary wanted to test if the calculated hashes are the same then.
Nevertheless together with the extension the fault can be reproduced and the code can serve as base for a solution.

BTW: the field in the extension is bidirectional and shows IRRE-functionality combined with select-dropdown.


Files

wdb_news_snapin.zip (66.4 KB) wdb_news_snapin.zip Extension to reproduce hmac-error David Bruchmann, 2020-04-28 02:59

Related issues

Related to TYPO3 Core - Bug #88094: Opening inline elements failsClosed2019-04-05

Actions

Also available in: Atom PDF