上线前的安全自查,是 Web 应用交付前最后一道、也是成本最低的一道防线。很多严重漏洞并非源于高深攻击手法,而是基础防护缺失:一个未过滤的输入框、一条拼接的 SQL、一台暴露 root 登录的服务器。本文按 XSS 防御、SQL 注入防御、Linux 服务器加固 三个维度,整理一份可直接落地的上线前自查清单,供开发、测试和运维在发布前逐项核对。
一、XSS 的常见方式与前端防御
XSS(跨站脚本攻击)的本质是:用户可控的数据被当作代码在浏览器中执行。常见类型有三类:
- 存储型 XSS:恶意脚本存入数据库,所有访问该页面的用户都会中招,常见于评论、昵称、商品描述。
- 反射型 XSS:恶意脚本通过 URL 参数带入,服务端直接回显到页面,常见于搜索框、错误提示页。
- DOM 型 XSS:服务端未参与,前端 JS 直接把
location.hash、innerHTML等不可信数据写入 DOM。
前端防御清单:
- 输出编码优先于输入过滤。在把数据插入 HTML 时,对
& < > " '做实体编码;插入属性、URL、JS 上下文时使用对应的编码规则,不要用同一套规则应付所有场景。 - 禁用危险的 DOM 操作。避免使用
innerHTML、outerHTML、document.write插入不可信内容,优先使用textContent、createElement。React 默认转义,但dangerouslySetInnerHTML、Vue 的v-html必须配合 DOMPurify 等库净化。 - 警惕 URL 协议。对
href、src做白名单校验,禁止javascript:、data:等协议,防止javascript:alert(1)类链接。 - 启用 CSP。通过
Content-Security-Policy限制脚本来源,禁止unsafe-inline,即使漏掉一处转义也能形成兜底。 - Cookie 加 HttpOnly。让会话 Cookie 无法被 JS 读取,降低 XSS 成功后的危害。
- 自查动作:搜索代码中所有
innerHTML、v-html、dangerouslySetInnerHTML、eval,逐一确认数据来源是否可信。
二、MySQL 防止 SQL 注入的几种写法
SQL 注入的根因是 SQL 语句与用户数据拼接。防御的核心原则只有一条:让数据永远以参数形式进入数据库,而不是拼进 SQL 文本。以下是几种正确与错误写法对比。
错误写法(禁止上线):
// 字符串拼接,注入点
$sql = "SELECT * FROM users WHERE name = '" . $_GET['name'] . "'";
正确写法一:预处理语句(Prepared Statement)
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = ?");
$stmt->execute([$_GET['name']]);
参数占位符由数据库驱动处理,数据不会被解析为 SQL 语法,这是最推荐的方案。
正确写法二:命名占位符
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name AND status = :status");
$stmt->execute([':name' => $name, ':status' => $status]);
正确写法三:ORM 与查询构造器
Laravel、Django ORM、MyBatis 的 #{} 等默认使用参数绑定,能有效防注入。但要注意:MyBatis 的 ${} 是直接拼接,仍会注入;ORM 中的原生 SQL 方法(如 whereRaw)同样需要手动绑定参数。
正确写法四:存储过程
使用带参数的存储过程,避免在过程内部用 CONCAT 拼接 SQL。
补充自查项:
- 数据库账号遵循最小权限,Web 应用账号不要有
DROP、FILE权限。 - 关闭详细报错回显,避免泄露表结构。
- 对
ORDER BY、表名等无法用占位符的位置,使用白名单映射,不要直接拼接。 - 上线前用 sqlmap 对主要接口做一轮扫描。
三、Linux 服务器安全加固清单
应用再安全,服务器被攻破也毫无意义。以下是上线前应逐项确认的加固项:
1. 账号与登录
- 禁止 root 直接 SSH 登录:
PermitRootLogin no。 - 禁用密码登录,改用密钥:
PasswordAuthentication no。 - 删除或锁定无用账号,检查
cat /etc/passwd中 UID 为 0 的账号是否只有 root。 - 配置
sudo精细化授权,避免全员 root。
2. SSH 与端口
- 修改默认 22 端口,减少自动化扫描噪音。
- 使用
fail2ban对暴力破解自动封禁。 - 通过防火墙(iptables / firewalld / 安全组)只放行必要端口,数据库端口不对公网开放。
3. 系统与软件更新
- 开启自动安全更新,或建立定期补丁机制。
- 卸载无用服务与软件包,减少攻击面。
- 检查
systemctl list-unit-files中是否有意外启动的服务。
4. 文件与权限
- 敏感文件权限收紧:
/etc/shadow为 600,SSH 私钥为 600。 - Web 目录禁止执行脚本(上传目录尤其重要),避免上传木马被直接执行。
- 检查 SUID 文件:
find / -perm -4000 -type f,确认无异常。
5. 日志与监控
- 确保
auth.log、secure、Web 访问日志正常记录并轮转。 - 接入集中日志或告警,对异常登录、异常进程保持可见性。
6. 备份与恢复
- 数据库与关键配置定期备份,并实际演练一次恢复流程。没有验证过的备份等于没有备份。
结语
安全自查不是一次性任务,而应固化为上线流程中的检查项。建议把上述清单整理成团队的上线 CheckList:前端确认 XSS 输出编码与 CSP,后端确认所有 SQL 使用参数绑定,运维确认服务器加固与备份可用。每一条都不复杂,但漏掉任何一条,都可能让前面所有的努力归零。上线前多花半小时核对,远好过上线后花三天应急。
未经允许不得转载:任鹏个人博客 » Web 应用上线前安全自查清单:从 XSS、SQL 注入到服务器加固


朋友圈点赞图在线生成源码