XSS 与 SQL 注入：Web 安全两大经典漏洞

XSS 与 SQL 注入：Web 安全两大经典漏洞引言如果 Web 安全有一份“必考清单”，XSS 和 SQL 注入一定在榜首。两者都源于同一个根因——“把不可信输入当可信数据处理”，但表现与防护各不相同。一、XSS（跨站脚本）攻击者把恶意脚本注入页面，其他用户浏览时脚本在其浏览器执行，可窃取 Cookie、伪造操作、钓鱼。三种类型存储型：恶意脚本存进数据库，所有访问者都中招（如评论区）。危害最大。反射型：脚本藏在 URL 参数里，诱骗点击触发。 DOM 型：纯前端修改 DOM 触发，不经过服务器，常规 WAF 难防。输出上下文决定编码方式不同位置需要不同编码，缺一不可：上下文编码方式 HTML 正文 HTML 实体编码 HTML 属性属性编码 + 加引号 JavaScript JS 编码（\xHH） URL 参数 URL 编码防护手段输出转义：按上下文正确编码（框架通常自带，如 React 默认转义）。 CSP（内容安全策略）：限制脚本来源，即使被注入也难以执行。 Content-Security-Policy: default-src 'self'; script-src 'self' 敏感 Cookie 加 HttpOnly：防止 JS 读取，缓解会话被盗。输入校验：白名单校验长度、格式、字符集。二、SQL 注入把用户输入拼进 SQL 语句，改变原语义，可绕过登录、拖库、删表。 -- 危险写法 SELECT * FROM users WHERE name='" + input + "' AND pwd='" + pw + "'; -- 输入 admin' -- 直接注释掉密码校验，登录任意账户常见手法联合查询（UNION）：拼接出额外结果集，拖出其他表数据。报错注入：利用数据库报错回显敏感信息。盲注（布尔/时间）：无回显时，靠页面差异或 SLEEP() 延迟判断。防护（由根到表）参数化查询（Prepared Statement）——最根本、必须默认采用。 cursor.execute("SELECT * FROM users WHERE name=%s", (name,)) ORM 框架：多数 ORM 默认参数化。最小权限：应用数据库账号禁止 FILE、DROP 等危险操作。 WAF/输入校验：作为补充，不能替代参数化。关闭详细错误：生产环境不向用户暴露 SQL 报错。三、两者的共同根因都源于“输入不可信”。养成习惯：所有外部输入先校验，输出时按上下文转义，数据落库时参数化。四、如何测试自己的系统自动化：用 SQLMap（SQLi）、XSS 扫描器做授权测试。代码审计：搜索字符串拼接 SQL、.innerHTML= 等危险模式。依赖检查：用 npm audit/pip-audit 查已知漏洞组件。五、真实代价历史上多起大规模数据泄露都源于未参数化查询或存储型 XSS。这类漏洞修复成本极低（改成参数化），但泄露代价极高。小结 XSS 防在“输出”，SQL 注入防在“查询”。把“输入不可信”刻进开发习惯，能挡掉绝大多数 Web 攻击。下一篇我们补上密码学这一底层基石。延伸 OWASP XSS 防护备忘单 OWASP SQLi 防护备忘单下一篇：《密码学入门：对称加密、非对称加密与哈希》