Search: Set limits on the amount of search terms

Sets some reasonable limits, which are higher when logged in since that
infers a little extra trust.
Helps prevent against large resource consuption attacks via super heavy
search queries.

Thanks to Gabriel Rodrigues AKA TEXUGO for reporting.
This commit is contained in:
Dan Brown
2025-12-30 13:29:04 +00:00
parent 88d86df66f
commit b08d1b36de
4 changed files with 82 additions and 2 deletions

View File

@@ -142,4 +142,53 @@ class SearchOptionsTest extends TestCase
$this->assertEquals('dino', $options->exacts->all()[0]->value);
$this->assertTrue($options->exacts->all()[0]->negated);
}
public function test_from_string_results_are_count_limited_and_larger_for_logged_in_users()
{
$terms = [
...array_fill(0, 40, 'cat'),
...array_fill(0, 50, '"bees"'),
...array_fill(0, 50, '{is_template}'),
...array_fill(0, 50, '[a=b]'),
];
$options = SearchOptions::fromString(implode(' ', $terms));
$this->assertCount(5, $options->searches->all());
$this->assertCount(2, $options->exacts->all());
$this->assertCount(4, $options->tags->all());
$this->assertCount(5, $options->filters->all());
$this->asEditor();
$options = SearchOptions::fromString(implode(' ', $terms));
$this->assertCount(10, $options->searches->all());
$this->assertCount(4, $options->exacts->all());
$this->assertCount(8, $options->tags->all());
$this->assertCount(10, $options->filters->all());
}
public function test_from_request_results_are_count_limited_and_larger_for_logged_in_users()
{
$request = new Request([
'search' => str_repeat('hello ', 20),
'tags' => array_fill(0, 20, 'a=b'),
'extras' => str_repeat('-[b=c] -{viewed_by_me} -"dino"', 20),
]);
$options = SearchOptions::fromRequest($request);
$this->assertCount(5, $options->searches->all());
$this->assertCount(2, $options->exacts->all());
$this->assertCount(4, $options->tags->all());
$this->assertCount(5, $options->filters->all());
$this->asEditor();
$options = SearchOptions::fromRequest($request);
$this->assertCount(10, $options->searches->all());
$this->assertCount(4, $options->exacts->all());
$this->assertCount(8, $options->tags->all());
$this->assertCount(10, $options->filters->all());
}
}