From 9bbd11e4bcdbacfac2a5827cc89be2222c2eec79 Mon Sep 17 00:00:00 2001 From: Karson Date: Fri, 16 Jun 2023 17:32:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EURL=E6=A3=80=E6=B5=8B?= =?UTF-8?q?=E5=92=8C=E6=B8=85=E7=90=86=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化登录和注册链接跳转 (cherry picked from commit 3549e95ea11d97434c1b3b3fe76d34df8b63b50c) --- application/admin/controller/Index.php | 2 +- application/common.php | 43 ++++++++++++++++++++++++++ application/index/controller/User.php | 13 +++----- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/application/admin/controller/Index.php b/application/admin/controller/Index.php index 7a6a6a4a..c387bf82 100644 --- a/application/admin/controller/Index.php +++ b/application/admin/controller/Index.php @@ -66,7 +66,7 @@ class Index extends Backend */ public function login() { - $url = $this->request->get('url', 'index/index'); + $url = $this->request->get('url', 'index/index', 'url_clean'); if ($this->auth->isLogin()) { $this->success(__("You've logged in, do not login again"), $url); } diff --git a/application/common.php b/application/common.php index 69eb22cb..744476d3 100755 --- a/application/common.php +++ b/application/common.php @@ -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')) { /** * 检测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')) { /** * 生成文件后缀图片 diff --git a/application/index/controller/User.php b/application/index/controller/User.php index a785fa04..ebceecbe 100644 --- a/application/index/controller/User.php +++ b/application/index/controller/User.php @@ -129,9 +129,8 @@ class User extends Frontend } } //判断来源 - $referer = $this->request->server('HTTP_REFERER'); - if (!$url && (strtolower(parse_url($referer, PHP_URL_HOST)) == strtolower($this->request->host())) - && !preg_match("/(user\/login|user\/register|user\/logout)/i", $referer)) { + $referer = $this->request->server('HTTP_REFERER', '', 'url_clean'); + if (!$url && $referer && !preg_match("/(user\/login|user\/register|user\/logout)/i", $referer)) { $url = $referer; } $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'); 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()) { $account = $this->request->post('account'); @@ -175,7 +174,6 @@ class User extends Frontend $result = $validate->check($data); if (!$result) { $this->error(__($validate->getError()), null, ['token' => $this->request->token()]); - return false; } if ($this->auth->login($account, $password)) { $this->success(__('Logged in successful'), $url ? $url : url('user/index')); @@ -184,9 +182,8 @@ class User extends Frontend } } //判断来源 - $referer = $this->request->server('HTTP_REFERER'); - if (!$url && (strtolower(parse_url($referer, PHP_URL_HOST)) == strtolower($this->request->host())) - && !preg_match("/(user\/login|user\/register|user\/logout)/i", $referer)) { + $referer = $this->request->server('HTTP_REFERER', '', 'url_clean'); + if (!$url && $referer && !preg_match("/(user\/login|user\/register|user\/logout)/i", $referer)) { $url = $referer; } $this->view->assign('url', $url);