Skip to content

Commit

Permalink
Hotfix/csrf (#102)
Browse files Browse the repository at this point in the history
* [fix]完善csrf过滤功能

* [fix]修改提示信息

* [feat]兼容CK编辑器上传功能

* [fix]删除多余文件

* [fix]删除调试代码
  • Loading branch information
zhongshaofa committed Sep 14, 2021
1 parent 3888cab commit 4cb2be1
Show file tree
Hide file tree
Showing 17 changed files with 102 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .example.env
@@ -1 +1 @@
APP_DEBUG=true[APP]DEFAULT_TIMEZONE=Asia/Shanghai[DATABASE]TYPE=mysqlHOSTNAME=host.docker.internalDATABASE=easyadminUSERNAME=rootPASSWORD=rootHOSTPORT=3306CHARSET=utf8DEBUG=truePREFIX=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
APP_DEBUG=true[APP]DEFAULT_TIMEZONE=Asia/Shanghai[DATABASE]TYPE=mysqlHOSTNAME=host.docker.internalDATABASE=easyadminUSERNAME=rootPASSWORD=rootHOSTPORT=3306CHARSET=utf8DEBUG=truePREFIX=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
Expand Down
2 changes: 2 additions & 0 deletions app/admin/controller/Ajax.php
Expand Up @@ -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'),
Expand Down Expand Up @@ -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'),
Expand Down
2 changes: 2 additions & 0 deletions app/admin/controller/Index.php
Expand Up @@ -49,6 +49,7 @@ public function welcome()
*/
public function editAdmin()
{
$this->checkPostRequest();
$id = session('admin.id');
$row = (new SystemAdmin())
->withoutField('password')
Expand Down Expand Up @@ -81,6 +82,7 @@ public function editAdmin()
*/
public function editPassword()
{
$this->checkPostRequest();
$id = session('admin.id');
$row = (new SystemAdmin())
->withoutField('password')
Expand Down
2 changes: 1 addition & 1 deletion app/admin/controller/mall/Goods.php
Expand Up @@ -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);
Expand Down
7 changes: 5 additions & 2 deletions app/admin/controller/system/Admin.php
Expand Up @@ -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));
Expand All @@ -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));
Expand All @@ -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()) {
Expand Down Expand Up @@ -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('超级管理员不允许修改');
Expand All @@ -180,6 +182,7 @@ public function delete($id)
*/
public function modify()
{
$this->checkPostRequest();
$post = $this->request->post();
$rule = [
'id|ID' => 'require',
Expand Down
1 change: 1 addition & 0 deletions app/admin/controller/system/Auth.php
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions app/admin/controller/system/Config.php
Expand Up @@ -47,6 +47,7 @@ public function index()
*/
public function save()
{
$this->checkPostRequest();
$post = $this->request->post();
try {
foreach ($post as $key => $val) {
Expand Down
6 changes: 4 additions & 2 deletions app/admin/controller/system/Menu.php
Expand Up @@ -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',
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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 {
Expand All @@ -164,6 +165,7 @@ public function delete($id)
*/
public function modify()
{
$this->checkPostRequest();
$post = $this->request->post();
$rule = [
'id|ID' => 'require',
Expand Down
2 changes: 2 additions & 0 deletions app/admin/controller/system/Node.php
Expand Up @@ -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();
Expand Down Expand Up @@ -102,6 +103,7 @@ public function refreshNode($force = 0)
*/
public function clearNode()
{
$this->checkPostRequest();
$nodeList = (new NodeService())->getNodelist();
$model = new SystemNode();
try {
Expand Down
3 changes: 3 additions & 0 deletions app/admin/middleware.php
Expand Up @@ -8,6 +8,9 @@
// 系统操作日志
\app\admin\middleware\SystemLog::class,

// Csrf安全校验
\app\admin\middleware\CsrfMiddleware::class,

// 后台视图初始化
// \app\admin\middleware\ViewInit::class,

Expand Down
53 changes: 53 additions & 0 deletions app/admin/middleware/CsrfMiddleware.php
@@ -0,0 +1,53 @@
<?php

// +----------------------------------------------------------------------
// | EasyAdmin
// +----------------------------------------------------------------------
// | PHP交流群: 763822524
// +----------------------------------------------------------------------
// | 开源协议 https://mit-license.org
// +----------------------------------------------------------------------
// | github开源项目:https://github.com/zhongshaofa/EasyAdmin
// +----------------------------------------------------------------------

namespace app\admin\middleware;


use app\Request;
use CsrfVerify\drive\ThinkphpCache;
use CsrfVerify\entity\CsrfVerifyEntity;
use CsrfVerify\interfaces\CsrfVerifyInterface;
use think\facade\Session;

class CsrfMiddleware
{
use \app\common\traits\JumpTrait;

public function handle(Request $request, \Closure $next)
{
if (env('EASYADMIN.IS_CSRF', true)) {
if (!in_array($request->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);
}
}
6 changes: 4 additions & 2 deletions app/admin/traits/Curd.php
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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 {
Expand Down Expand Up @@ -143,6 +144,7 @@ public function export()
*/
public function modify()
{
$this->checkPostRequest();
$post = $this->request->post();
$rule = [
'id|ID' => 'require',
Expand Down
1 change: 1 addition & 0 deletions app/admin/view/layout/default.html
Expand Up @@ -19,6 +19,7 @@
AUTOLOAD_JS: "{$autoloadJs|default='false'}",
IS_SUPER_ADMIN: "{$isSuperAdmin|default='false'}",
VERSION: "{$version|default='1.0.0'}",
CSRF_TOKEN: "{:token()}",
};
</script>
<script src="__STATIC__/plugs/layui-v2.5.6/layui.all.js?v={$version}" charset="utf-8"></script>
Expand Down
1 change: 0 additions & 1 deletion app/admin/view/mall/goods/add.html
@@ -1,6 +1,5 @@
<div class="layuimini-container">
<form id="app-form" class="layui-form layuimini-form">

<div class="layui-form-item">
<label class="layui-form-label">商品分类</label>
<div class="layui-input-block">
Expand Down
10 changes: 10 additions & 0 deletions app/common/controller/AdminController.php
Expand Up @@ -280,4 +280,14 @@ private function checkAuth(){

}
}

/**
* 严格校验接口是否为POST请求
*/
protected function checkPostRequest(){
if (!$this->request->isPost()) {
$this->error("当前请求不合法!");
}
}

}
2 changes: 1 addition & 1 deletion public/static/plugs/ckeditor4/ckeditor.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions public/static/plugs/easy-admin/easy-admin.js
Expand Up @@ -28,6 +28,9 @@ define(["jquery", "tableSelect", "ckeditor"], function ($, tableSelect, undefine
url: function (url) {
return '/' + CONFIG.ADMIN + '/' + url;
},
headers: function () {
return {'X-CSRF-TOKEN': window.CONFIG.CSRF_TOKEN};
},
//js版empty,判断变量是否为空
empty: function (r) {
var n, t, e, f = [void 0, null, !1, 0, "", "0"];
Expand Down Expand Up @@ -87,6 +90,7 @@ define(["jquery", "tableSelect", "ckeditor"], function ($, tableSelect, undefine
type: type,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
dataType: "json",
headers:admin.headers(),
data: option.data,
timeout: 60000,
success: function (res) {
Expand All @@ -102,6 +106,9 @@ define(["jquery", "tableSelect", "ckeditor"], function ($, tableSelect, undefine
ex(this);
});
return false;
},
complete: function(){
// @todo 刷新csrf-token
}
});
}
Expand Down Expand Up @@ -188,6 +195,7 @@ define(["jquery", "tableSelect", "ckeditor"], function ($, tableSelect, undefine
options.id = options.id || options.init.table_render_id;
options.layFilter = options.id + '_LayFilter';
options.url = options.url || admin.url(options.init.index_url);
options.headers = admin.headers();
options.page = admin.parame(options.page, true);
options.search = admin.parame(options.search, true);
options.skin = options.skin || 'line';
Expand Down Expand Up @@ -1299,6 +1307,7 @@ define(["jquery", "tableSelect", "ckeditor"], function ($, tableSelect, undefine
url: admin.url(init.upload_url),
accept: 'file',
exts: exts,
headers:admin.headers(),
// 让多图上传模式下支持多选操作
multiple: (uploadNumber !== 'one') ? true : false,
done: function (res) {
Expand Down Expand Up @@ -1417,6 +1426,8 @@ define(["jquery", "tableSelect", "ckeditor"], function ($, tableSelect, undefine
}
},
editor: function () {
CKEDITOR.tools.setCookie('ckCsrfToken', window.CONFIG.CSRF_TOKEN);

var editorList = document.querySelectorAll(".editor");
if (editorList.length > 0) {
$.each(editorList, function (i, v) {
Expand Down

0 comments on commit 4cb2be1

Please sign in to comment.