Skip to content

Commit 8e409df

Browse files
author
hwyu@adobe.com
committed
MC-36035: Prevent input based resource allocation
- Added min page size validation
1 parent f05e488 commit 8e409df

File tree

6 files changed

+70
-22
lines changed

6 files changed

+70
-22
lines changed

app/etc/di.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1943,6 +1943,7 @@
19431943
</type>
19441944
<type name="Magento\Framework\Webapi\Validator\SearchCriteriaValidator">
19451945
<arguments>
1946+
<argument name="minimumPageSize" xsi:type="number">10</argument>
19461947
<argument name="maximumPageSize" xsi:type="number">300</argument>
19471948
</arguments>
19481949
</type>
@@ -1956,6 +1957,7 @@
19561957
</type>
19571958
<type name="Magento\Framework\GraphQl\Query\Resolver\Argument\Validator\SearchCriteriaValidator">
19581959
<arguments>
1960+
<argument name="minPageSize" xsi:type="number">10</argument>
19591961
<argument name="maxPageSize" xsi:type="number">300</argument>
19601962
</arguments>
19611963
</type>

lib/internal/Magento/Framework/GraphQl/Query/Resolver/Argument/Validator/SearchCriteriaValidator.php

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,42 @@
1717
*/
1818
class SearchCriteriaValidator implements ValidatorInterface
1919
{
20+
/**
21+
* @var int
22+
*/
23+
private $minPageSize;
24+
2025
/**
2126
* @var int
2227
*/
2328
private $maxPageSize;
2429

2530
/**
31+
* @param int $minPageSize
2632
* @param int $maxPageSize
2733
*/
28-
public function __construct(int $maxPageSize)
34+
public function __construct(int $minPageSize, int $maxPageSize)
2935
{
36+
$this->minPageSize = $minPageSize;
3037
$this->maxPageSize = $maxPageSize;
3138
}
3239

3340
/**
3441
* @inheritDoc
35-
* @throws GraphQlInputException
3642
*/
3743
public function validate(Field $field, $args): void
3844
{
39-
if (isset($args['pageSize']) && $args['pageSize'] > $this->maxPageSize) {
40-
throw new GraphQlInputException(
41-
__("Maximum pageSize is %max", ['max' => $this->maxPageSize])
42-
);
45+
if (isset($args['pageSize'])) {
46+
if ($args['pageSize'] < $this->minPageSize) {
47+
throw new GraphQlInputException(
48+
__("Minimum pageSize is %min", ['min' => $this->minPageSize])
49+
);
50+
}
51+
if ($args['pageSize'] > $this->maxPageSize) {
52+
throw new GraphQlInputException(
53+
__("Maximum pageSize is %max", ['max' => $this->maxPageSize])
54+
);
55+
}
4356
}
4457
}
4558
}

lib/internal/Magento/Framework/GraphQl/Test/Unit/Query/Resolver/Argument/Validator/SearchCriteriaValidatorTest.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,31 @@ class SearchCriteriaValidatorTest extends TestCase
2323
*/
2424
public function testValidValue()
2525
{
26-
$validator = new SearchCriteriaValidator(3);
26+
$validator = new SearchCriteriaValidator(1, 3);
2727
$field = self::getMockBuilder(Field::class)
2828
->disableOriginalConstructor()
2929
->getMock();
30+
$validator->validate($field, ['pageSize' => 1]);
31+
$validator->validate($field, ['pageSize' => 2]);
3032
$validator->validate($field, ['pageSize' => 3]);
3133
}
3234

33-
public function testValidInvalidValue()
35+
public function testValidInvalidMinValue()
36+
{
37+
$this->expectException(GraphQlInputException::class);
38+
$this->expectExceptionMessage("Minimum pageSize is 1");
39+
$validator = new SearchCriteriaValidator(1, 3);
40+
$field = self::getMockBuilder(Field::class)
41+
->disableOriginalConstructor()
42+
->getMock();
43+
$validator->validate($field, ['pageSize' => 0]);
44+
}
45+
46+
public function testValidInvalidMaxValue()
3447
{
3548
$this->expectException(GraphQlInputException::class);
3649
$this->expectExceptionMessage("Maximum pageSize is 3");
37-
$validator = new SearchCriteriaValidator(3);
50+
$validator = new SearchCriteriaValidator(1, 3);
3851
$field = self::getMockBuilder(Field::class)
3952
->disableOriginalConstructor()
4053
->getMock();

lib/internal/Magento/Framework/Webapi/ServiceInputProcessor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public function __construct(
135135
$this->customAttributePreprocessors = $customAttributePreprocessors;
136136
$this->serviceInputValidator = $serviceInputValidator
137137
?: ObjectManager::getInstance()->get(ServiceInputValidatorInterface::class);
138-
$this->defaultPageSize = $defaultPageSize ?: 20;
138+
$this->defaultPageSize = $defaultPageSize;
139139
}
140140

141141
/**

lib/internal/Magento/Framework/Webapi/Test/Unit/Validator/SearchCriteriaValidatorTest.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,28 @@ class SearchCriteriaValidatorTest extends TestCase
2121
/**
2222
* @doesNotPerformAssertions
2323
*/
24-
public function testAllowsPageSizeWhenBelowLimit()
24+
public function testAllowsPageSizeWhenAboveMinLimitAndBelowMaxLimit()
2525
{
2626
$searchCriteria = new SearchCriteria();
27-
$validator = new SearchCriteriaValidator(3);
27+
$validator = new SearchCriteriaValidator(1, 3);
2828
$validator->validateEntityValue($searchCriteria, 'pageSize', 2);
2929
}
3030

31-
public function testFailsPageSizeWhenAboveLimit()
31+
public function testFailsPageSizeWhenBelowMinLimit()
32+
{
33+
$this->expectException(InvalidArgumentException::class);
34+
$this->expectErrorMessage('Minimum SearchCriteria pageSize is 1');
35+
$searchCriteria = new SearchCriteria();
36+
$validator = new SearchCriteriaValidator(1, 3);
37+
$validator->validateEntityValue($searchCriteria, 'pageSize', 0);
38+
}
39+
40+
public function testFailsPageSizeWhenAboveMaxLimit()
3241
{
3342
$this->expectException(InvalidArgumentException::class);
3443
$this->expectErrorMessage('Maximum SearchCriteria pageSize is 3');
3544
$searchCriteria = new SearchCriteria();
36-
$validator = new SearchCriteriaValidator(3);
45+
$validator = new SearchCriteriaValidator(1, 3);
3746
$validator->validateEntityValue($searchCriteria, 'pageSize', 4);
3847
}
3948
}

lib/internal/Magento/Framework/Webapi/Validator/SearchCriteriaValidator.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,23 @@
1616
*/
1717
class SearchCriteriaValidator implements ServiceInputValidatorInterface
1818
{
19+
/**
20+
* @var int
21+
*/
22+
private $minimumPageSize;
23+
1924
/**
2025
* @var int
2126
*/
2227
private $maximumPageSize;
2328

2429
/**
30+
* @param int $minimumPageSize
2531
* @param int $maximumPageSize
2632
*/
27-
public function __construct(int $maximumPageSize)
33+
public function __construct(int $minimumPageSize, int $maximumPageSize)
2834
{
35+
$this->minimumPageSize = $minimumPageSize;
2936
$this->maximumPageSize = $maximumPageSize;
3037
}
3138

@@ -42,13 +49,17 @@ public function validateComplexArrayType(string $className, array $items): void
4249
*/
4350
public function validateEntityValue(object $entity, string $propertyName, $value): void
4451
{
45-
if ($entity instanceof SearchCriteriaInterface
46-
&& $propertyName === 'pageSize'
47-
&& $value > $this->maximumPageSize
48-
) {
49-
throw new InvalidArgumentException(
50-
__('Maximum SearchCriteria pageSize is %max', ['max' => $this->maximumPageSize])
51-
);
52+
if ($entity instanceof SearchCriteriaInterface && $propertyName === 'pageSize') {
53+
if ($value < $this->minimumPageSize) {
54+
throw new InvalidArgumentException(
55+
__('Minimum SearchCriteria pageSize is %min', ['min' => $this->minimumPageSize])
56+
);
57+
}
58+
if ($value > $this->maximumPageSize) {
59+
throw new InvalidArgumentException(
60+
__('Maximum SearchCriteria pageSize is %max', ['max' => $this->maximumPageSize])
61+
);
62+
}
5263
}
5364
}
5465
}

0 commit comments

Comments
 (0)