新增URL检测和清理函数

优化登录和注册链接跳转

(cherry picked from commit 3549e95ea1)
pull/455/head
Karson 2023-06-16 17:32:00 +08:00 committed by F4nniu
parent 8947877915
commit 9bbd11e4bc
3 changed files with 49 additions and 9 deletions

View File

@ -66,7 +66,7 @@ class Index extends Backend
*/ */
public function login() public function login()
{ {
$url = $this->request->get('url', 'index/index'); $url = $this->request->get('url', 'index/index', 'url_clean');
if ($this->auth->isLogin()) { if ($this->auth->isLogin()) {
$this->success(__("You've logged in, do not login again"), $url); $this->success(__("You've logged in, do not login again"), $url);
} }

View File

@ -467,6 +467,19 @@ if (!function_exists('xss_clean')) {
} }
} }
if (!function_exists('url_clean')) {
/**
* 清理URL
*/
function url_clean($url)
{
if (!check_url_allowed($url)) {
return '';
}
return xss_clean($url);
}
}
if (!function_exists('check_ip_allowed')) { if (!function_exists('check_ip_allowed')) {
/** /**
* 检测IP是否允许 * 检测IP是否允许
@ -485,6 +498,36 @@ if (!function_exists('check_ip_allowed')) {
} }
} }
if (!function_exists('check_url_allowed')) {
/**
* 检测URL是否允许
* @param string $url URL
* @return bool
*/
function check_url_allowed($url = null)
{
//允许的主机列表
$allowedHostArr = [
strtolower(request()->host())
];
//如果是站内相对链接则允许
if (preg_match("/^[\/a-z][a-z0-9][a-z0-9\.\/]+\$/i", $url) && substr($url, 0, 2) !== '//') {
return true;
}
//如果是站外链接则需要判断HOST是否允许
if (preg_match("/((http[s]?:\/\/)+(?>[a-z\-0-9]{2,}\.){1,}[a-z]{2,8})(?:\s|\/)/i", $url)) {
if (in_array(strtolower(parse_url($url, PHP_URL_HOST)), $allowedHostArr)) {
return true;
}
}
return false;
}
}
if (!function_exists('build_suffix_image')) { if (!function_exists('build_suffix_image')) {
/** /**
* 生成文件后缀图片 * 生成文件后缀图片

View File

@ -129,9 +129,8 @@ class User extends Frontend
} }
} }
//判断来源 //判断来源
$referer = $this->request->server('HTTP_REFERER'); $referer = $this->request->server('HTTP_REFERER', '', 'url_clean');
if (!$url && (strtolower(parse_url($referer, PHP_URL_HOST)) == strtolower($this->request->host())) if (!$url && $referer && !preg_match("/(user\/login|user\/register|user\/logout)/i", $referer)) {
&& !preg_match("/(user\/login|user\/register|user\/logout)/i", $referer)) {
$url = $referer; $url = $referer;
} }
$this->view->assign('captchaType', config('fastadmin.user_register_captcha')); $this->view->assign('captchaType', config('fastadmin.user_register_captcha'));
@ -147,7 +146,7 @@ class User extends Frontend
{ {
$url = $this->request->request('url', '', 'trim,xss_clean'); $url = $this->request->request('url', '', 'trim,xss_clean');
if ($this->auth->id) { if ($this->auth->id) {
$this->success(__('You\'ve logged in, do not login again'), $url ? $url : url('user/index')); $this->success(__('You\'ve logged in, do not login again'), $url ?: url('user/index'));
} }
if ($this->request->isPost()) { if ($this->request->isPost()) {
$account = $this->request->post('account'); $account = $this->request->post('account');
@ -175,7 +174,6 @@ class User extends Frontend
$result = $validate->check($data); $result = $validate->check($data);
if (!$result) { if (!$result) {
$this->error(__($validate->getError()), null, ['token' => $this->request->token()]); $this->error(__($validate->getError()), null, ['token' => $this->request->token()]);
return false;
} }
if ($this->auth->login($account, $password)) { if ($this->auth->login($account, $password)) {
$this->success(__('Logged in successful'), $url ? $url : url('user/index')); $this->success(__('Logged in successful'), $url ? $url : url('user/index'));
@ -184,9 +182,8 @@ class User extends Frontend
} }
} }
//判断来源 //判断来源
$referer = $this->request->server('HTTP_REFERER'); $referer = $this->request->server('HTTP_REFERER', '', 'url_clean');
if (!$url && (strtolower(parse_url($referer, PHP_URL_HOST)) == strtolower($this->request->host())) if (!$url && $referer && !preg_match("/(user\/login|user\/register|user\/logout)/i", $referer)) {
&& !preg_match("/(user\/login|user\/register|user\/logout)/i", $referer)) {
$url = $referer; $url = $referer;
} }
$this->view->assign('url', $url); $this->view->assign('url', $url);