Browse Source

新增URL检测和清理函数

优化登录和注册链接跳转
Karson 1 year ago
parent
commit
3549e95ea1

+ 1 - 1
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);
         }

+ 43 - 0
application/common.php

@@ -465,6 +465,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是否允许
@@ -483,6 +496,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')) {
     /**
      * 生成文件后缀图片

+ 7 - 10
application/index/controller/User.php

@@ -65,7 +65,7 @@ class User extends Frontend
      */
     public function register()
     {
-        $url = $this->request->request('url', '', 'trim');
+        $url = $this->request->request('url', '', 'url_clean');
         if ($this->auth->id) {
             $this->success(__('You\'ve logged in, do not login again'), $url ? $url : url('user/index'));
         }
@@ -128,9 +128,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'));
@@ -144,9 +143,9 @@ class User extends Frontend
      */
     public function login()
     {
-        $url = $this->request->request('url', '', 'trim');
+        $url = $this->request->request('url', '', 'url_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');
@@ -174,7 +173,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'));
@@ -183,9 +181,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);