Files
saasshop/app/Support/BackUrl.php

72 lines
1.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Support;
class BackUrl
{
/**
* back 参数安全护栏(用于 Blade 中 `{!! !!}` 输出的 href 场景):
* - 仅允许站内相对路径(/ 开头)
* - 拒绝引号/尖括号(防属性注入/XSS
* - 拒绝 nested back=(防 URL 膨胀/绕过)
*/
public static function sanitizeForLinks(string $incomingBack): string
{
$incomingBack = (string) $incomingBack;
if ($incomingBack === '') {
return '';
}
if (!str_starts_with($incomingBack, '/')) {
return '';
}
if (preg_match('/["\'<>]/', $incomingBack)) {
return '';
}
// 拒绝 back 自身再包含 back=(避免无限嵌套导致 URL 膨胀,且容易绕过页面侧护栏)
if (preg_match('/(?:^|[?&])back=/', $incomingBack)) {
return '';
}
return $incomingBack;
}
/**
* 安全版“保留当前 query 并覆盖字段”的站内相对链接构造器。
*
* 典型用途:列表页里的各种「统计卡/治理入口/快捷链接」需要:
* - 保留当前筛选条件
* - 覆盖指定字段
* - 强制清空 page
* - 并且 back 只能保留通过 sanitizeForLinks 的安全值(否则移除)
*/
public static function currentPathWithQuery(array $overrides = [], string $safeBackForLinks = ''): string
{
$q = request()->query();
if ($safeBackForLinks !== '') {
$q['back'] = $safeBackForLinks;
} else {
unset($q['back']);
}
foreach ($overrides as $k => $v) {
if ($v === null) {
unset($q[$k]);
} else {
$q[$k] = $v;
}
}
$url = '/' . ltrim(request()->path(), '/');
if (count($q) > 0) {
$url .= '?' . \Illuminate\Support\Arr::query($q);
}
return $url;
}
}