From 4cb2be127d5a9fd4a964aea1d7d5d92f639bc99a Mon Sep 17 00:00:00 2001 From: "Mr.Chung" <39075420+zhongshaofa@users.noreply.github.com> Date: Wed, 15 Sep 2021 02:08:49 +0800 Subject: [PATCH] Hotfix/csrf (#102) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [fix]完善csrf过滤功能 * [fix]修改提示信息 * [feat]兼容CK编辑器上传功能 * [fix]删除多余文件 * [fix]删除调试代码 --- .example.env | 2 +- app/admin/controller/Ajax.php | 2 + app/admin/controller/Index.php | 2 + app/admin/controller/mall/Goods.php | 2 +- app/admin/controller/system/Admin.php | 7 ++- app/admin/controller/system/Auth.php | 1 + app/admin/controller/system/Config.php | 1 + app/admin/controller/system/Menu.php | 6 ++- app/admin/controller/system/Node.php | 2 + app/admin/middleware.php | 3 ++ app/admin/middleware/CsrfMiddleware.php | 53 ++++++++++++++++++++ app/admin/traits/Curd.php | 6 ++- app/admin/view/layout/default.html | 1 + app/admin/view/mall/goods/add.html | 1 - app/common/controller/AdminController.php | 10 ++++ public/static/plugs/ckeditor4/ckeditor.js | 2 +- public/static/plugs/easy-admin/easy-admin.js | 11 ++++ 17 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 app/admin/middleware/CsrfMiddleware.php diff --git a/.example.env b/.example.env index daf0fff0..ee1d0bbe 100644 --- a/.example.env +++ b/.example.env @@ -1 +1 @@ -APP_DEBUG=true [APP] DEFAULT_TIMEZONE=Asia/Shanghai [DATABASE] TYPE=mysql HOSTNAME=host.docker.internal DATABASE=easyadmin USERNAME=root PASSWORD=root HOSTPORT=3306 CHARSET=utf8 DEBUG=true PREFIX=ea_ [LANG] default_lang=zh-cn # 后台配置项组 [EASYADMIN] # 后台地址后缀名称 ADMIN=admin # 后台登录验证码开关 CAPTCHA=true # 是否为演示环境 IS_DEMO=true # CDN配置项组 CDN= EXAMPLE=true # 静态文件路径前缀 STATIC_PATH=/static # OSS静态文件路径前缀 OSS_STATIC_PREFIX=static_easyadmin \ No newline at end of file +APP_DEBUG=true [APP] DEFAULT_TIMEZONE=Asia/Shanghai [DATABASE] TYPE=mysql HOSTNAME=host.docker.internal DATABASE=easyadmin USERNAME=root PASSWORD=root HOSTPORT=3306 CHARSET=utf8 DEBUG=true PREFIX=ea_ [LANG] default_lang=zh-cn # 后台配置项组 [EASYADMIN] # 后台地址后缀名称 ADMIN=admin # 后台登录验证码开关 CAPTCHA=true # 是否为演示环境 IS_DEMO=true # CDN配置项组 CDN= EXAMPLE=true # 是否开启CSRF过滤 IS_CSRF=true # 静态文件路径前缀 STATIC_PATH=/static # OSS静态文件路径前缀 OSS_STATIC_PREFIX=static_easyadmin \ No newline at end of file diff --git a/app/admin/controller/Ajax.php b/app/admin/controller/Ajax.php index c30aa46a..ff3b579a 100644 --- a/app/admin/controller/Ajax.php +++ b/app/admin/controller/Ajax.php @@ -63,6 +63,7 @@ public function clearCache() */ public function upload() { + $this->checkPostRequest(); $data = [ 'upload_type' => $this->request->post('upload_type'), 'file' => $this->request->file('file'), @@ -96,6 +97,7 @@ public function upload() */ public function uploadEditor() { + $this->checkPostRequest(); $data = [ 'upload_type' => $this->request->post('upload_type'), 'file' => $this->request->file('upload'), diff --git a/app/admin/controller/Index.php b/app/admin/controller/Index.php index 62acda4c..78851884 100644 --- a/app/admin/controller/Index.php +++ b/app/admin/controller/Index.php @@ -49,6 +49,7 @@ public function welcome() */ public function editAdmin() { + $this->checkPostRequest(); $id = session('admin.id'); $row = (new SystemAdmin()) ->withoutField('password') @@ -81,6 +82,7 @@ public function editAdmin() */ public function editPassword() { + $this->checkPostRequest(); $id = session('admin.id'); $row = (new SystemAdmin()) ->withoutField('password') diff --git a/app/admin/controller/mall/Goods.php b/app/admin/controller/mall/Goods.php index 3cc6bac8..b353511b 100644 --- a/app/admin/controller/mall/Goods.php +++ b/app/admin/controller/mall/Goods.php @@ -67,7 +67,7 @@ public function stock($id) { $row = $this->model->find($id); empty($row) && $this->error('数据不存在'); - if ($this->request->isAjax()) { + if ($this->request->isPost()) { $post = $this->request->post(); $rule = []; $this->validate($post, $rule); diff --git a/app/admin/controller/system/Admin.php b/app/admin/controller/system/Admin.php index ed40b092..17331d1e 100644 --- a/app/admin/controller/system/Admin.php +++ b/app/admin/controller/system/Admin.php @@ -78,7 +78,7 @@ public function index() */ public function add() { - if ($this->request->isAjax()) { + if ($this->request->isPost()) { $post = $this->request->post(); $authIds = $this->request->post('auth_ids', []); $post['auth_ids'] = implode(',', array_keys($authIds)); @@ -101,7 +101,7 @@ public function edit($id) { $row = $this->model->find($id); empty($row) && $this->error('数据不存在'); - if ($this->request->isAjax()) { + if ($this->request->isPost()) { $post = $this->request->post(); $authIds = $this->request->post('auth_ids', []); $post['auth_ids'] = implode(',', array_keys($authIds)); @@ -128,6 +128,7 @@ public function edit($id) */ public function password($id) { + $this->checkPostRequest(); $row = $this->model->find($id); empty($row) && $this->error('数据不存在'); if ($this->request->isAjax()) { @@ -159,6 +160,7 @@ public function password($id) */ public function delete($id) { + $this->checkPostRequest(); $row = $this->model->whereIn('id', $id)->select(); $row->isEmpty() && $this->error('数据不存在'); $id == AdminConstant::SUPER_ADMIN_ID && $this->error('超级管理员不允许修改'); @@ -180,6 +182,7 @@ public function delete($id) */ public function modify() { + $this->checkPostRequest(); $post = $this->request->post(); $rule = [ 'id|ID' => 'require', diff --git a/app/admin/controller/system/Auth.php b/app/admin/controller/system/Auth.php index 57235f00..970fdb5a 100644 --- a/app/admin/controller/system/Auth.php +++ b/app/admin/controller/system/Auth.php @@ -62,6 +62,7 @@ public function authorize($id) */ public function saveAuthorize() { + $this->checkPostRequest(); $id = $this->request->post('id'); $node = $this->request->post('node', "[]"); $node = json_decode($node, true); diff --git a/app/admin/controller/system/Config.php b/app/admin/controller/system/Config.php index e6b727ad..1c959b35 100644 --- a/app/admin/controller/system/Config.php +++ b/app/admin/controller/system/Config.php @@ -47,6 +47,7 @@ public function index() */ public function save() { + $this->checkPostRequest(); $post = $this->request->post(); try { foreach ($post as $key => $val) { diff --git a/app/admin/controller/system/Menu.php b/app/admin/controller/system/Menu.php index 9bc30f17..3dabc9e1 100644 --- a/app/admin/controller/system/Menu.php +++ b/app/admin/controller/system/Menu.php @@ -77,7 +77,7 @@ public function add($id = null) if ($id == $homeId) { $this->error('首页不能添加子菜单'); } - if ($this->request->isAjax()) { + if ($this->request->isPost()) { $post = $this->request->post(); $rule = [ 'pid|上级菜单' => 'require', @@ -110,7 +110,7 @@ public function edit($id) { $row = $this->model->find($id); empty($row) && $this->error('数据不存在'); - if ($this->request->isAjax()) { + if ($this->request->isPost()) { $post = $this->request->post(); $rule = [ 'pid|上级菜单' => 'require', @@ -144,6 +144,7 @@ public function edit($id) */ public function delete($id) { + $this->checkPostRequest(); $row = $this->model->whereIn('id', $id)->select(); empty($row) && $this->error('数据不存在'); try { @@ -164,6 +165,7 @@ public function delete($id) */ public function modify() { + $this->checkPostRequest(); $post = $this->request->post(); $rule = [ 'id|ID' => 'require', diff --git a/app/admin/controller/system/Node.php b/app/admin/controller/system/Node.php index 4faeb603..fdc6f3fb 100644 --- a/app/admin/controller/system/Node.php +++ b/app/admin/controller/system/Node.php @@ -66,6 +66,7 @@ public function index() */ public function refreshNode($force = 0) { + $this->checkPostRequest(); $nodeList = (new NodeService())->getNodelist(); empty($nodeList) && $this->error('暂无需要更新的系统节点'); $model = new SystemNode(); @@ -102,6 +103,7 @@ public function refreshNode($force = 0) */ public function clearNode() { + $this->checkPostRequest(); $nodeList = (new NodeService())->getNodelist(); $model = new SystemNode(); try { diff --git a/app/admin/middleware.php b/app/admin/middleware.php index 95e33e89..56b68978 100644 --- a/app/admin/middleware.php +++ b/app/admin/middleware.php @@ -8,6 +8,9 @@ // 系统操作日志 \app\admin\middleware\SystemLog::class, + // Csrf安全校验 + \app\admin\middleware\CsrfMiddleware::class, + // 后台视图初始化 // \app\admin\middleware\ViewInit::class, diff --git a/app/admin/middleware/CsrfMiddleware.php b/app/admin/middleware/CsrfMiddleware.php new file mode 100644 index 00000000..6ba1aed4 --- /dev/null +++ b/app/admin/middleware/CsrfMiddleware.php @@ -0,0 +1,53 @@ +method(), ['GET', 'HEAD', 'OPTIONS'])) { + + // 跨域校验 + $refererUrl = $request->header('REFERER', null); + $refererInfo = parse_url($refererUrl); + $host = $request->host(); + if (!isset($refererInfo['host']) || $refererInfo['host'] != $host) { + $this->error('当前请求不合法!'); + } + + // CSRF校验 + // @todo 兼容CK编辑器上传功能 + $ckCsrfToken = $request->post('ckCsrfToken', null); + $data = !empty($ckCsrfToken) ? ['__token__' => $ckCsrfToken] : []; + + $check = $request->checkToken('__token__', $data); + if (!$check) { + $this->error('请求验证失败,请重新刷新页面!'); + } + + } + } + return $next($request); + } +} \ No newline at end of file diff --git a/app/admin/traits/Curd.php b/app/admin/traits/Curd.php index 146db389..fcd0f0ab 100644 --- a/app/admin/traits/Curd.php +++ b/app/admin/traits/Curd.php @@ -60,7 +60,7 @@ public function index() */ public function add() { - if ($this->request->isAjax()) { + if ($this->request->isPost()) { $post = $this->request->post(); $rule = []; $this->validate($post, $rule); @@ -81,7 +81,7 @@ public function edit($id) { $row = $this->model->find($id); empty($row) && $this->error('数据不存在'); - if ($this->request->isAjax()) { + if ($this->request->isPost()) { $post = $this->request->post(); $rule = []; $this->validate($post, $rule); @@ -101,6 +101,7 @@ public function edit($id) */ public function delete($id) { + $this->checkPostRequest(); $row = $this->model->whereIn('id', $id)->select(); $row->isEmpty() && $this->error('数据不存在'); try { @@ -143,6 +144,7 @@ public function export() */ public function modify() { + $this->checkPostRequest(); $post = $this->request->post(); $rule = [ 'id|ID' => 'require', diff --git a/app/admin/view/layout/default.html b/app/admin/view/layout/default.html index d774c9b0..6ead6f45 100644 --- a/app/admin/view/layout/default.html +++ b/app/admin/view/layout/default.html @@ -19,6 +19,7 @@ AUTOLOAD_JS: "{$autoloadJs|default='false'}", IS_SUPER_ADMIN: "{$isSuperAdmin|default='false'}", VERSION: "{$version|default='1.0.0'}", + CSRF_TOKEN: "{:token()}", }; diff --git a/app/admin/view/mall/goods/add.html b/app/admin/view/mall/goods/add.html index 69365f85..e323c059 100644 --- a/app/admin/view/mall/goods/add.html +++ b/app/admin/view/mall/goods/add.html @@ -1,6 +1,5 @@