同步安全基线说明

This commit is contained in:
JIA-MAC
2026-09-23 14:03:47 +08:00
parent db47278fd1
commit 7d839eb07d
2 changed files with 18 additions and 0 deletions

View File

@@ -122,6 +122,15 @@ ThinkPHP 开启多模块但未强制路由,因此主要 URL 由“模块/控
- 当前没有正式 migration 框架。结构变更至少要同步新安装 SQL,并明确现有环境的升级 SQL/操作步骤;不能只改 `like.sql` 后假设老库会自动升级。 - 当前没有正式 migration 框架。结构变更至少要同步新安装 SQL,并明确现有环境的升级 SQL/操作步骤;不能只改 `like.sql` 后假设老库会自动升级。
- `.env` 只保存本地/部署环境值。不要提交数据库、Redis、支付、短信、微信、对象存储或地图等密钥。 - `.env` 只保存本地/部署环境值。不要提交数据库、Redis、支付、短信、微信、对象存储或地图等密钥。
## 安全基线
- `config/app.php` 的 `app_debug` 默认 `true`(未配置 `.env` 时调试模式开启)、`app_trace` 默认 `false`。生产部署应在 `.env` 显式设置 `[app] app_debug = false` 关闭调试,需要 trace 时设置 `[app] app_trace = true`。`.env` 解析出的值是字符串(如 `"1"`),判断是否开启时必须用 `filter_var($value, FILTER_VALIDATE_BOOLEAN)`,不要做 `=== true` 严格比较。
- 开启 trace 时,`ApiBase::_success()/_error()` 返回的 `debug.request.header` 会掩码 `token`、`X-Consume-Token`、`authorization`、`cookie`、`set-cookie`,不要在 debug 输出中引入新的敏感字段。
- 在线升级入口 `admin/upgrade/index|choosePage|handleUpgrade|addUpdatePkgLog` 以及关系链修复 `admin/upgrade/fixAncestorRelation` 仅超级管理员(admin id=1)可用;权限同时收敛在控制器 `checkSuperAdmin()` 和角色授权数据上。存量环境需执行 `server/public/install/db/security_3.5.1.sql` 移除 `ls_role_dev_auth_index` 中菜单 245(系统更新)的授权,并清理角色权限缓存。
- 提现 `WithdrawLogic::apply()` 在事务内先插提现单,再用 `lock(true)` 锁行重读可提现余额,最后以 `where('earnings', '>=', $money)->setDec()` 条件原子扣减并校验受影响行数,防止并发超提。`Withdraw.php::checkMoney()` 拒绝 0、负数和非数字,最低提现金额未配置时拒绝申请。
- 远程图片/头像下载必须经过 `check_url_safety()`:仅允许 `http/https`,DNS 解析后拒绝回环、私网、链路本地、CGNAT 及云元数据地址(如 `169.254.169.254`)。安全 HTTP 助手连接超时 10s、总超时 30s、不跟随重定向、最大下载 150MB,并通过 `CURLOPT_RESOLVE` 固定已校验 IP;`download_file()`、海报合成、`check_file_exists()` 的远程分支统一走该助手。`StorageDriver->fetch()` 在云存储侧发起抓取,调用方仍需先过 `check_url_safety()`,属于已知残余边界。
- 微信服务器 URL 验证:`WeChatLogic::index()` 仅在携带 `echostr` 的 GET 分支按 token/timestamp/nonce 字典序排序后 SHA1,并用 `hash_equals` 与 `signature` 比对,匹配才回显 `echostr`;`oa.token` 未配置时验证失败。POST 消息回调仍走 EasyWeChat。
## Admin 架构 ## Admin 架构
admin 是 `server/` 内的服务端渲染模块,不存在独立安装或前端构建步骤。 admin 是 `server/` 内的服务端渲染模块,不存在独立安装或前端构建步骤。

View File

@@ -62,6 +62,15 @@
- 交互优先复用 Layui table/form/layer 和 `like.ajax`,不要为单页引入新 SPA 框架。 - 交互优先复用 Layui table/form/layer 和 `like.ajax`,不要为单页引入新 SPA 框架。
- 新增菜单或受控 action 时同步角色权限、缓存逻辑和安装 SQL 中的菜单/权限数据。 - 新增菜单或受控 action 时同步角色权限、缓存逻辑和安装 SQL 中的菜单/权限数据。
### 安全基线
- `config/app.php` 的 `app_debug` 默认 `true`(未配置 `.env` 时调试模式开启)、`app_trace` 默认 `false`;生产部署在 `.env` 显式 `[app] app_debug = false` 关闭调试;判断开关用 `filter_var(..., FILTER_VALIDATE_BOOLEAN)`,`.env` 解析值是字符串,不能 `=== true` 严格比较。
- trace 输出的 `debug.request.header` 会掩码 token/X-Consume-Token/authorization/cookie/set-cookie。
- `admin/upgrade/index|choosePage|handleUpgrade|addUpdatePkgLog` 与 `admin/upgrade/fixAncestorRelation` 仅超管(admin id=1)可用;存量环境执行 `server/public/install/db/security_3.5.1.sql` 移除菜单 245 授权并清权限缓存。
- 提现申请在事务内锁行重读余额 + 条件原子 `setDec`,`checkMoney()` 拒绝 0/负数/非数字且最低提现金额未配置时拒绝。
- 远程下载经 `check_url_safety()`(仅 http/https,拒绝回环/私网/链路本地/云元数据地址),安全 HTTP 助手限时 10s/30s、不跟随重定向、150MB 上限并用 `CURLOPT_RESOLVE` 固定 IP;`download_file()`、海报合成、`check_file_exists()` 远程分支统一走该助手。
- 微信 URL 验证仅在 `echostr` GET 分支做 token/timestamp/nonce 排序 SHA1 + `hash_equals` 校验,POST 回调仍走 EasyWeChat。
## PC 商城边界 ## PC 商城边界
管理后台不是 PC 商城。PC 前台源码位于 `pc/`,后端接入位于以下位置: 管理后台不是 PC 商城。PC 前台源码位于 `pc/`,后端接入位于以下位置: