上线前 checklist 漏掉「演示账号」这一项,我差点把超管密码写进游客可见的演示站
上周帮朋友公司收尾一个后台管理系统,代码测完、接口通完、SSL 也挂好了,心想这回总该稳了吧。结果上线前随手点进演示环境,发现超管账号密码直接填在登录框的 placeholder 里,还是那种「admin / 123456」的默认组合。后背一凉——这要是被爬虫扫到,等于白送。
从那以后我把上线前的检查项重新捋了一遍,专门拆成四类,每次部署前对着勾一遍,分享出来给同样马虎的站长:
一、权限:别让用户摸到不该摸的
• 后台目录有没有独立鉴权,还是只靠「URL 藏得深」?
• 文件上传目录是否禁用了脚本执行(Nginx 的 location ~* \.(php|php5)$ deny all; 有没有配)
• 数据库账号是不是按最小权限开的,演示站有没有误用 root 账号
• .env 文件、日志目录、runtime 是否对 web 用户不可写或不可读
之前见过最离谱的,是宝塔一键部署后 .env 直接 644,访问 /application/.env 能下载完整配置。现在我的习惯是部署完先用 dirsearch 扫一遍敏感路径,再手动试几个常见的。
二、路由:隐藏的不一定安全,暴露的一定要可控
• ThinkPHP 的 route/app.php 里有没有调试阶段开的闭路,比如 /test/ 开头的临时接口
• 资源路由有没有漏掉 delete 或 put,导致本来只该读数据的接口能改能删
• 前后端分离项目里,API 路由和页面路由是否混在同一个域名下,CORS 配置是否过宽
有个坑我踩过两次:本地开发为了方便,在 middleware 里全局放行了 OPTIONS 预检,上线时忘了收紧,结果任意来源都能跨域调接口。现在我在代码里用条件编译区分环境,生产环境的 CORS 白名单必须显式配置,空值直接报错阻断部署。
三、菜单与按钮:看不见的权限比看得见的更危险
• 角色权限表初始化数据有没有把「测试角色」带进去
• 前端菜单过滤是否和后端接口鉴权一致——只藏按钮不拦接口等于没藏
• 超级管理员的标识字段(比如 is_super)是否在普通注册流程里可篡改
这次帮朋友检查时就发现,前端根据 role_id === 1 判断超管,但注册接口没校验 role_id 范围,抓包改个 1 直接晋升。这种前后端逻辑对不齐的问题,代码 review 很难看出来,必须专门列一条检查。
四、配置:环境变量是最后一条防线
• APP_DEBUG 到底关没关,不只是 config/app.php,还要看 .env 是否覆盖
• 邮件、短信、OSS 的密钥是不是生产环境的,测试用的「AKIAIOSFODNN7EXAMPLE」有没有残留
• 定时任务 crontab 里有没有指向旧服务器 IP 的硬编码
• 缓存前缀是否带环境标识,避免演示站和正式站共用一个 Redis 库时互相覆盖
我现在的做法是维护两份清单:一份「代码层」随仓库走,一份「部署层」存在本地笔记。每次上线前,代码层用脚本自动扫描(比如 grep -r "APP_DEBUG.*true"),部署层人工逐项确认。两次回滚的教训告诉我,再熟的流程,不写下来就一定会漏。
你们有没有那种「以为没问题,上线后才发现」的惊险时刻?欢迎丢出来互相补漏。

