banner
约 300 字
1 分钟

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

摘要

拆解 XSS(存储/反射/DOM 型)与 SQL 注入(UNION/报错/盲注)的原理、危害与防护,强调按上下文输出转义、CSP、参数化查询与最小权限等根本手段。

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

引言

如果 Web 安全有一份“必考清单”,XSS 和 SQL 注入一定在榜首。两者都源于同一个根因——“把不可信输入当可信数据处理”,但表现与防护各不相同。

一、XSS(跨站脚本)

攻击者把恶意脚本注入页面,其他用户浏览时脚本在其浏览器执行,可窃取 Cookie、伪造操作、钓鱼。

三种类型

  • 存储型:恶意脚本存进数据库,所有访问者都中招(如评论区)。危害最大。

  • 反射型:脚本藏在 URL 参数里,诱骗点击触发。

  • DOM 型:纯前端修改 DOM 触发,不经过服务器,常规 WAF 难防。

输出上下文决定编码方式

不同位置需要不同编码,缺一不可:

上下文

编码方式

HTML 正文

HTML 实体编码

HTML 属性

属性编码 + 加引号

JavaScript

JS 编码(\xHH)

URL 参数

URL 编码

防护手段

  1. 输出转义:按上下文正确编码(框架通常自带,如 React 默认转义)。

  2. CSP(内容安全策略):限制脚本来源,即使被注入也难以执行。

http
Content-Security-Policy: default-src 'self'; script-src 'self'
  1. 敏感 Cookie 加 HttpOnly:防止 JS 读取,缓解会话被盗。

  2. 输入校验:白名单校验长度、格式、字符集。

二、SQL 注入

把用户输入拼进 SQL 语句,改变原语义,可绕过登录、拖库、删表。

SQL
-- 危险写法
SELECT * FROM users WHERE name='" + input + "' AND pwd='" + pw + "';
-- 输入 admin' -- 直接注释掉密码校验,登录任意账户

常见手法

  • 联合查询(UNION):拼接出额外结果集,拖出其他表数据。

  • 报错注入:利用数据库报错回显敏感信息。

  • 盲注(布尔/时间):无回显时,靠页面差异或 SLEEP() 延迟判断。

防护(由根到表)

  1. 参数化查询(Prepared Statement)——最根本、必须默认采用。

Python
cursor.execute("SELECT * FROM users WHERE name=%s", (name,))
  1. ORM 框架:多数 ORM 默认参数化。

  2. 最小权限:应用数据库账号禁止 FILEDROP 等危险操作。

  3. WAF/输入校验:作为补充,不能替代参数化。

  4. 关闭详细错误:生产环境不向用户暴露 SQL 报错。

三、两者的共同根因

都源于“输入不可信”。养成习惯:所有外部输入先校验,输出时按上下文转义,数据落库时参数化

四、如何测试自己的系统

  • 自动化:用 SQLMap(SQLi)、XSS 扫描器做授权测试。

  • 代码审计:搜索字符串拼接 SQL、.innerHTML= 等危险模式。

  • 依赖检查:用 npm audit/pip-audit 查已知漏洞组件。

五、真实代价

历史上多起大规模数据泄露都源于未参数化查询或存储型 XSS。这类漏洞修复成本极低(改成参数化),但泄露代价极高。

小结

XSS 防在“输出”,SQL 注入防在“查询”。把“输入不可信”刻进开发习惯,能挡掉绝大多数 Web 攻击。下一篇我们补上密码学这一底层基石。

延伸

  • OWASP XSS 防护备忘单

  • OWASP SQLi 防护备忘单

  • 下一篇:《密码学入门:对称加密、非对称加密与哈希》

END