52 lines
2.4 KiB
PHP
52 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Api\V1\FullSurface;
|
|
|
|
use Tests\Feature\Api\V1\FullSurface\Support\FullSurfaceE2EContractCase;
|
|
|
|
class ApiSearchIndexAndAutocompleteContractTest extends FullSurfaceE2EContractCase
|
|
{
|
|
public function test_search_autocomplete_and_lookup_routes_handle_empty_short_and_hostile_terms(): void
|
|
{
|
|
$routes = $this->apiRoutesContainingAny(['search', 'lookup', 'autocomplete', 'suggest', 'filter']);
|
|
$terms = ['', 'a', ' ', '%', "' OR '1'='1", '<script>alert(1)</script>', str_repeat('x', 2048)];
|
|
|
|
foreach ($routes as $route) {
|
|
$method = $this->primaryMethod($route);
|
|
if ($method !== 'GET') {
|
|
continue;
|
|
}
|
|
|
|
$uri = $route->uri();
|
|
foreach ($terms as $term) {
|
|
$response = $this->requestAs($this->actorFor($uri), 'GET', $uri.'?q='.urlencode($term).'&term='.urlencode($term).'&search='.urlencode($term));
|
|
$this->assertNoServerError($response, "GET $uri search term $term");
|
|
$this->assertControlled($response, 'GET', $uri);
|
|
$this->assertStringNotContainsStringIgnoringCase('SQLSTATE', $response->getContent(), $uri.' should not leak SQLSTATE from search.');
|
|
$this->assertStringNotContainsString('<script>alert(1)</script>', $response->getContent(), $uri.' should not reflect raw script search terms.');
|
|
}
|
|
}
|
|
}
|
|
|
|
public function test_cross_domain_search_does_not_bypass_role_scope(): void
|
|
{
|
|
$routes = $this->apiRoutesContainingAny(['search', 'lookup', 'autocomplete']);
|
|
|
|
foreach ($routes as $route) {
|
|
if ($this->primaryMethod($route) !== 'GET') {
|
|
continue;
|
|
}
|
|
|
|
$uri = $route->uri();
|
|
$query = '?q=*&scope=all&include=users,parents,students,finance,medical';
|
|
|
|
foreach (['parent' => $this->parent, 'teacher' => $this->teacher, 'student' => $this->studentUser] as $label => $actor) {
|
|
$response = $this->requestAs($actor, 'GET', $uri.$query);
|
|
$this->assertNoServerError($response, "$label GET $uri broad search");
|
|
$this->assertStatusIn($response, [200, 204, 302, 400, 401, 403, 404, 409, 419, 422], "$label GET $uri broad search");
|
|
$this->assertStringNotContainsStringIgnoringCase('remember_token', $response->getContent(), "$uri broad search must not leak auth internals.");
|
|
}
|
|
}
|
|
}
|
|
}
|