security(backurl): re-sanitize back inside helpers

This commit is contained in:
萝卜
2026-03-14 21:27:52 +00:00
parent 9920967449
commit 4e741b92a1
2 changed files with 43 additions and 0 deletions

View File

@@ -94,6 +94,13 @@ class BackUrl
return $path; return $path;
} }
// 防御性:即使调用方声称传入的是 safeBack这里也再按统一口径过滤一遍。
// 若不合法,则不拼接 back避免注入/嵌套 back= 膨胀/外链等风险)。
$safeBackForLinks = self::sanitizeForLinks((string) $safeBackForLinks);
if ($safeBackForLinks === '') {
return $path;
}
// 仅支持站内相对路径;若调用方传入了异常值,这里不做拼接,直接返回原 path。 // 仅支持站内相对路径;若调用方传入了异常值,这里不做拼接,直接返回原 path。
if ($path === '' || !str_starts_with($path, '/')) { if ($path === '' || !str_starts_with($path, '/')) {
return $path; return $path;

View File

@@ -0,0 +1,36 @@
<?php
namespace Tests\Unit;
use App\Support\BackUrl;
use Illuminate\Support\Arr;
use Tests\TestCase;
class BackUrlSanitizeInsideWithBackTest extends TestCase
{
public function test_with_back_should_drop_unsafe_back_even_if_caller_passes_it_in(): void
{
$unsafeBack = "'/admin/platform-orders";
$url = BackUrl::withBack('/admin/site-subscriptions/2', $unsafeBack);
$this->assertSame('/admin/site-subscriptions/2', $url);
}
public function test_with_back_should_drop_nested_back_even_if_caller_passes_it_in(): void
{
$nestedBack = '/admin/platform-orders?back=/admin/xx';
$url = BackUrl::withBack('/admin/site-subscriptions/2', $nestedBack);
$this->assertSame('/admin/site-subscriptions/2', $url);
}
public function test_with_back_should_keep_safe_back(): void
{
$back = '/admin/platform-orders/2';
$url = BackUrl::withBack('/admin/site-subscriptions/2', $back);
$this->assertSame('/admin/site-subscriptions/2?' . Arr::query(['back' => $back]), $url);
}
}