Merge pull request #236 from copenhagentruckwash/fix-task-attachment-link-vulnerability
Enforce lane department authorization for self-serve eligibility
This commit is contained in:
@@ -131,7 +131,7 @@ class departmentSelfserveVehicleConditionsRoute
|
||||
$lane_id = (int)self::getParameter('lane_id');
|
||||
$reg = selfserve::standardize_registration((string)self::getParameter('reg'));
|
||||
|
||||
$lane = $this->assertLaneAccess($user, $lane_id, $has_global);
|
||||
$lane = $this->assertLaneAccess($user, $lane_id);
|
||||
$customer_number = null;
|
||||
if (!$has_global && $has_own) {
|
||||
$customer_number = $this->requireAuthenticatedCustomerNumber($user, 'list_department_selfserve_vehicle_conditions');
|
||||
@@ -193,7 +193,7 @@ class departmentSelfserveVehicleConditionsRoute
|
||||
$lane_id = (int)self::getParameter('lane_id');
|
||||
$reg = selfserve::standardize_registration((string)self::getParameter('reg'));
|
||||
|
||||
$this->assertLaneAccess($user, $lane_id, $has_global);
|
||||
$this->assertLaneAccess($user, $lane_id);
|
||||
$customer_number = null;
|
||||
if (!$has_global && $has_own) {
|
||||
$customer_number = $this->requireAuthenticatedCustomerNumber($user, 'list_department_selfserve_vehicle_conditions');
|
||||
@@ -527,7 +527,7 @@ class departmentSelfserveVehicleConditionsRoute
|
||||
return $default;
|
||||
}
|
||||
|
||||
private function assertLaneAccess(object $user, int $laneId, bool $hasGlobalPermission): department_lanes_o
|
||||
private function assertLaneAccess(object $user, int $laneId): department_lanes_o
|
||||
{
|
||||
global $response;
|
||||
|
||||
@@ -536,11 +536,14 @@ class departmentSelfserveVehicleConditionsRoute
|
||||
$response->error('Department lane not found', 404);
|
||||
}
|
||||
|
||||
if ($hasGlobalPermission) {
|
||||
$authorized_department_ids = $user->getGroup()->getDepartments();
|
||||
if (!in_array((int)$lane->department->value(), $authorized_department_ids, true)) {
|
||||
$this->forbidDepartmentAccess((int)$lane->department->value());
|
||||
}
|
||||
$lane_department_id = (int)$lane->department->value();
|
||||
$authorized_department_ids = array_values(array_filter(
|
||||
array_map('intval', (array)$user->getGroup()->getDepartments()),
|
||||
static fn(int $department_id): bool => $department_id > 0
|
||||
));
|
||||
|
||||
if (!in_array($lane_department_id, $authorized_department_ids, true)) {
|
||||
$this->forbidDepartmentAccess($lane_department_id);
|
||||
}
|
||||
|
||||
return $lane;
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
function selfserve_eligibility_route_source(): string
|
||||
{
|
||||
$route = file_get_contents(app_path('routes/departmentSelfserveVehicleConditionsRoute.php'));
|
||||
if ($route === false) {
|
||||
throw new RuntimeException('departmentSelfserveVehicleConditionsRoute.php not found');
|
||||
}
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
function selfserve_eligibility_route_block(string $route, string $method, string $path): string
|
||||
{
|
||||
$start = strpos($route, "\$this->{$method}('{$path}'");
|
||||
if ($start === false) {
|
||||
throw new RuntimeException("Route block not found: {$method} {$path}");
|
||||
}
|
||||
|
||||
$nextComment = strpos($route, "\n /**", $start + 1);
|
||||
if ($nextComment === false) {
|
||||
return substr($route, $start);
|
||||
}
|
||||
|
||||
return substr($route, $start, $nextComment - $start);
|
||||
}
|
||||
|
||||
function selfserve_eligibility_method_block(string $route, string $signature): string
|
||||
{
|
||||
$start = strpos($route, $signature);
|
||||
if ($start === false) {
|
||||
throw new RuntimeException("Method not found: {$signature}");
|
||||
}
|
||||
|
||||
$nextMethod = strpos($route, "\n private function ", $start + strlen($signature));
|
||||
if ($nextMethod === false) {
|
||||
return substr($route, $start);
|
||||
}
|
||||
|
||||
return substr($route, $start, $nextMethod - $start);
|
||||
}
|
||||
|
||||
it('authorizes customer eligibility preview lanes before returning task attachments', function (): void {
|
||||
$route = selfserve_eligibility_route_source();
|
||||
$allowedBlock = selfserve_eligibility_route_block($route, 'get', '/department/selfserve/vehicle/allowed');
|
||||
$assertBlock = selfserve_eligibility_method_block($route, 'private function assertLaneAccess(object $user, int $laneId): department_lanes_o');
|
||||
|
||||
expect($allowedBlock)->toContain('$lane = $this->assertLaneAccess($user, $lane_id);')
|
||||
->and($allowedBlock)->toContain('previewVehicleEligibility($lane_id, $reg, $customer_number, $vehicle_type_id)')
|
||||
->and(strpos($allowedBlock, '$lane = $this->assertLaneAccess($user, $lane_id);'))
|
||||
->toBeLessThan(strpos($allowedBlock, 'previewVehicleEligibility($lane_id, $reg, $customer_number, $vehicle_type_id)'));
|
||||
|
||||
expect($assertBlock)->toContain('$authorized_department_ids = array_values(array_filter(')
|
||||
->and($assertBlock)->toContain('array_map(\'intval\', (array)$user->getGroup()->getDepartments())')
|
||||
->and($assertBlock)->toContain('if (!in_array($lane_department_id, $authorized_department_ids, true))')
|
||||
->and($assertBlock)->toContain('$this->forbidDepartmentAccess($lane_department_id);')
|
||||
->and($assertBlock)->not->toContain('if ($hasGlobalPermission)');
|
||||
});
|
||||
Reference in New Issue
Block a user