Skip to content

Commit eb2592d

Browse files
authored
Merge pull request #6852 from magento-tsg/MC-41013
[Condor] MC-41013: [Backport for 2.4.x] [PSIRT-16297] Widget update layout xml leads to RCE
2 parents 8f33dd5 + aa46ad8 commit eb2592d

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

app/etc/di.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,9 @@
698698
<item name="0" xsi:type="string">Magento\Framework\Data\OptionSourceInterface</item>
699699
<item name="1" xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface</item>
700700
</argument>
701+
<argument name="deniedClassList" xsi:type="array">
702+
<item name="0" xsi:type="string">Magento\Framework\Model\ResourceModel\AbstractResource</item>
703+
</argument>
701704
</arguments>
702705
</type>
703706
<type name="Magento\Framework\Mview\View">

lib/internal/Magento/Framework/View/Element/UiComponent/Argument/Interpreter/ConfigurableObject.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ class ConfigurableObject implements InterpreterInterface
2424
*/
2525
private $classWhitelist = [];
2626

27+
/**
28+
* @var array
29+
*/
30+
private $deniedClassList = [];
31+
2732
/**
2833
* @var ObjectManagerInterface
2934
*/
@@ -52,17 +57,20 @@ class ConfigurableObject implements InterpreterInterface
5257
* @param array $classWhitelist
5358
* @param ClassReader|null $classReader
5459
* @param ConfigInterface|null $objectManagerConfig
60+
* @param array $deniedClassList
5561
*/
5662
public function __construct(
5763
ObjectManagerInterface $objectManager,
5864
InterpreterInterface $argumentInterpreter,
5965
array $classWhitelist = [],
6066
ClassReader $classReader = null,
61-
ConfigInterface $objectManagerConfig = null
67+
ConfigInterface $objectManagerConfig = null,
68+
array $deniedClassList = []
6269
) {
6370
$this->objectManager = $objectManager;
6471
$this->argumentInterpreter = $argumentInterpreter;
6572
$this->classWhitelist = $classWhitelist;
73+
$this->deniedClassList = $deniedClassList;
6674
$this->classReader = $classReader ?? $objectManager->get(ClassReader::class);
6775
$this->objectManagerConfig = $objectManagerConfig ?? $objectManager->get(ConfigInterface::class);
6876
}
@@ -72,6 +80,7 @@ public function __construct(
7280
*/
7381
public function evaluate(array $data)
7482
{
83+
$type = null;
7584
if (isset($data['value'])) {
7685
$className = $data['value'];
7786
$arguments = [];
@@ -104,6 +113,21 @@ public function evaluate(array $data)
104113
}
105114
}
106115

116+
if ($type === null) {
117+
$type = $this->objectManagerConfig->getInstanceType(
118+
$this->objectManagerConfig->getPreference($className)
119+
);
120+
$classParents = array_merge([$type], $this->getParents($type));
121+
}
122+
123+
$deniedIntersection = array_intersect($classParents, $this->deniedClassList);
124+
125+
if (!empty($deniedIntersection)) {
126+
throw new \InvalidArgumentException(
127+
sprintf('Class argument is invalid: %s', $className)
128+
);
129+
}
130+
107131
return $this->objectManager->create($className, $arguments);
108132
}
109133

@@ -115,7 +139,7 @@ public function evaluate(array $data)
115139
*/
116140
private function getParents(string $type)
117141
{
118-
$classParents = $this->classReader->getParents($type);
142+
$classParents = $this->classReader->getParents($type) ?? [];
119143
foreach ($classParents as $parent) {
120144
if (empty($parent)) {
121145
continue;

lib/internal/Magento/Framework/View/Test/Unit/UiComponent/Argument/Interpreter/ConfigurableObjectTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ protected function setUp(): void
6565
],
6666
'classReader' => $this->classReader,
6767
'objectManagerConfig' => $this->objectManagerConfig,
68+
'deniedClassList' => [
69+
\Foo\Bar\ClassC::class,
70+
\Foo\Bar\InterfaceC::class,
71+
],
6872
]
6973
);
7074
}
@@ -268,6 +272,27 @@ public function invalidDataProvider()
268272
\InvalidArgumentException::class,
269273
'Class argument is invalid: MyFooClass'
270274
],
275+
[
276+
[
277+
'argument' => [
278+
'class' => ['value' => 'MyFooClass'],
279+
'myarg' => ['value' => 'bar'],
280+
],
281+
],
282+
'MyFooClass',
283+
[
284+
['MyFooClass', ['Something', 'skipme']],
285+
['Something', ['dontcare', 'SomethingElse']],
286+
['SomethingElse', [\Foo\Bar\ClassC::class, 'unrelated']],
287+
['skipme', []],
288+
['dontcare', []],
289+
['unrelated', [\Foo\Bar\InterfaceC::class]],
290+
[\Foo\Bar\ClassC::class, []],
291+
[\Foo\Bar\InterfaceC::class, []],
292+
],
293+
\InvalidArgumentException::class,
294+
'Class argument is invalid: MyFooClass',
295+
],
271296
];
272297
}
273298
}

0 commit comments

Comments
 (0)