面试必问:SQL注入与XSS的完整攻防链路(附真题解析)
原创
ladon
ladon
306Safe
2026年7月2日 17:19
北京
在小说阅读器读本章
去阅读
安全岗面试 · 高频硬核考题精讲
SQL注入 × XSS跨站脚本 | 攻防原理 + 面试话术 + 实战要点
前言:为什么这两个漏洞永远面不腻?
在2026年的今天,你可能会想:ORM一把梭、框架自带防护,SQL注入和XSS这类「古典漏洞」早该退出历史舞台了吧?
现实很打脸。根据最新安全审计数据,SQL注入和XSS依然霸榜Web漏洞Top 2。原因很简单:框架能帮你挡掉大部分明面上的问题,但拼接SQL的场景无处不在——报表导出、动态排序、复杂查询、存储过程调用……只要有一个地方手写了字符串拼接,整座城堡就可能出现裂缝。
这也是为什么面试官永远爱问这两道题——它考察的不是你背答案的能力,而是你对Web安全底层逻辑的理解深度。
第一章 SQL注入:从原理到六种类型全覆盖
1.1 什么是SQL注入?一句话说清楚
SQL注入(SQL Injection)是指攻击者通过在用户输入中嵌入恶意的SQL代码片段,欺骗后端数据库引擎执行非预期的SQL命令,从而达到窃取、篡改或删除数据的目的。
// 有漏洞的代码(Java示例)
String sql = \"SELECT \* FROM users WHERE username = '\"
+ request.getParameter(\"username\") + \"'\"
+ \" AND password = '\" + request.getParameter(\"pwd\") + \"'\";
// 攻击者输入 username 为:
' OR '1'='1' --
// 实际执行的SQL变成:
SELECT \* FROM users WHERE username = '' OR '1'='1' --' AND password = ''
→ 永真条件绕过认证,直接登录!
1.2 SQL注入的六大类型(面试必答)
① 联合查询注入(Union-based)
适用场景:页面会回显数据库查询结果
核心Payload:' UNION SELECT username,password FROM users --
关键点:列数要匹配(用 ORDER BY 判断列数)
② 报错注入(Error-based)
适用场景:开启详细错误信息输出
典型函数:ExtractValue(), UpdateXML(), exp()(MySQL)
原理:构造让数据库报错的SQL,从错误信息中提取数据
③ 布尔盲注(Boolean-based Blind)
适用场景:页面只有「正常/异常」两种状态
判断逻辑:' AND 1=1 (正常)/ ' AND 1=2 (异常)
逐字符猜解:ASCII() + SUBSTRING() 逐位提取
④ 时间盲注(Time-based Blind)
适用场景:页面没有任何差异响应
核心函数:SLEEP(), BENCHMARK()(MySQL)
判断依据:响应时间差异(如 IF(1=1,SLEEP(5),0))
⑤ 堆叠查询注入(Stacked Queries)
前提条件:数据库支持多语句执行且权限允许
示例:'; DROP TABLE users; --
危害最大:可直接执行任意DDL/DML语句
⑥ 二次注入(Second Order)
特点:恶意数据先存入数据库,后被读取时触发注入
场景:注册→存储→其他功能读取时被执行
最难防范:即使入库时做了转义,读取拼接时仍可能触发
1.3 注入位置不仅限于输入框
面试加分项:能说出更多注入点说明实战经验丰富。
📍 常见注入点分布:
• GET参数:?id=1, ?search=keyword, ?category=xxx
• POST表单:登录框、搜索框、订单筛选
• HTTP Header:User-Agent、Referer、Cookie(XFF也常见)
• RESTful API:/api/users/1, /api/orders?sort=price
• JSON请求体:{\"filter\": {\"name\": \"admin'}}
• NoSQL:MongoDB的 $where、$ne 操作符注入
第二章 XSS跨站脚本:三种形态与攻击链路
2.1 XSS本质:代码在错误的上下文中执行
XSS(Cross Site Scripting)的核心原理是:攻击者注入的JavaScript代码在受害者的浏览器中被当作合法脚本执行。注意关键词——「受害者浏览器」,这意味着XSS攻击的目标是用户,而不是服务器。
2.2 三种XSS类型对比(面试核心考点)
🔴 反射型XSS(Reflected XSS)
触发方式:恶意URL中的参数直接被页面输出
典型场景:搜索框、错误页、跳转链接
攻击流程:构造恶意链接 → 发给受害者点击 → 参数反射到页面 → JS执行
持久性:非持久,需要诱骗点击
示例:/search?q=
🟠 存储型XSS(Stored / Persistent XSS)
触发方式:恶意内容被服务器存入数据库,每次访问都触发
典型场景:评论区、留言板、个人信息页、商品评价
攻击流程:提交恶意内容 → 服务端存储 → 其他用户访问时加载执行
持久性:持久,危害最大,可蠕虫式传播
案例:2005年 Samy 蠕虫(MySpace),20014年微博XSS蠕虫
🟡 DOM型XSS(DOM-based XSS)
触发方式:前端JS动态修改DOM时未过滤输入
典型场景:location.hash、document.URL、document.referrer
特点:恶意代码不经过服务器,纯前端问题
难点:传统WAF无法检测(请求中不含恶意代码)
示例:eval(location.hash.slice(1))
2.3 XSS能干什么?(危害全景)
☠️ XSS攻击矩阵:
🍪 窃取Cookie → document.cookie发送到攻击者服务器 → 会话劫持
🔑 键盘记录 → 监听onkeydown事件 → 记录密码/银行卡号
📸 网页篡改 → 修改DOM内容 → 钓鱼页面/虚假公告
🚪 流量劫持 → window.location重定向 → 恶意站点
📷 摄像头/麦克风 → getUserMedia() API → 隐私窃取
🕷️ 蠕虫传播 → 自动发消息/发帖 → 指数级扩散
🔗 结合CSRF → 利用已登录状态 → 执行非预期操作
第三章 防御方案:从原理到落地
3.1 SQL注入防御三板斧
🥇 第一板斧:参数化查询(Prepared Statement)
这是最有效、最根本的防御手段。原理:SQL语句结构与数据分离,数据库驱动程序负责正确处理参数转义,用户输入永远不会被解释为SQL代码。
// Java PreparedStatement 示例
String sql = \"SELECT \* FROM users WHERE username = ? AND password = ?\";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, username); // 安全,自动转义
pstmt.setString(2, password); // 安全,自动转义
ResultSet rs = pstmt.executeQuery();
🥈 第二板斧:输入验证与白名单
• 类型检查:ID字段必须是整数,用 parseInt()/intval()
• 长度限制:用户名不超过20字符,搜索词不超过100字符
• 白名单优于黑名单:只允许已知安全的字符通过
• ⚠️ 注意:输入验证是辅助手段,不能替代参数化查询
🥉 第三板斧:最小权限原则 + 错误处理
• 数据库账号不用root/sa,只给必要的SELECT/INSERT/UPDATE权限
• 关闭生产环境的详细错误信息输出
• 使用ORM时避免原生SQL拼接(如 raw() 方法)
• 存储过程同样需要注意SQL拼接问题
3.2 XSS防御策略
🛡️ XSS防御层次模型:
L1 输出编码(Output Encoding) ★★★★★
根据输出上下文选择正确的编码方式:
• HTML实体编码:& < > \" '
• JS编码:\xHH, \uHHHH
• URL编码:encodeURIComponent()
• CSS编码:\HHHHHH
L2 Content Security Policy (CSP) ★★★★☆
通过HTTP头限制资源加载来源:
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com
L3 HttpOnly Cookie ★★★★★
Set-Cookie: sessionid=xxx; HttpOnly; Secure; SameSite=Strict
→ 即使发生XSS,JS也无法读取cookie
L4 输入过滤(Input Filtering) ★★★☆☆
使用成熟的HTML净化库(如DOMPurify)
⚠️ 过滤不能替代编码,只是额外防线
3.3 WAF绕过:面试高频追问
面试官经常追问:「如果对方部署了WAF怎么办?」以下是一些经典绕过思路(仅用于安全研究和授权测试):
🔄 SQL注入WAF绕过技巧:
• 大小写混合:SeLeCt \ FrOm
• 内联注释:/\!50000UNION\/ SELECT
• 编码绕过:URL编码、Unicode、Hex
• 空格替代:/\\*/, %09(TAB), %0a(换行)
• 等价函数:CONCAT()||SUBSTR(), CHAR()||ASCII()
• HTTP参数污染(HPP):?id=1&id=2
🔄 XSS WAF绕过技巧:
• 事件属性变体:onload/onerror/onfocus/onmouseover
• 标签变体:
• 编码混淆:HTML实体、Base64、Unicode
• JavaScript伪协议变体:javascript:, vbscript:, data:
• CSP绕过:jsonp endpoint、domain relaxtion、
第四章 面试模拟:高频问题标准回答
Q1:参数化查询为什么能防止SQL注入?
A:因为参数化查询将SQL命令结构和用户数据分开传输。数据库驱动在执行前先将SQL语句编译为执行计划(Prepare阶段),此时参数占位符的类型已确定。后续传入的参数无论内容是什么,都只会被当作字面量数据处理,不会被二次解析为SQL语法。就像预编译好的模板,填空的内容不会改变模板结构本身。
Q2:存储型XSS和反射型XSS哪个危害更大?为什么?
A:存储型XSS危害更大。原因有三:(1) 持久性——恶意代码存在服务器端,每个访问该页面的用户都会中招;(2) 隐蔽性——攻击者无需持续发送链接,一次提交长期生效;(3) 可蠕虫化——如Samy Worm、新浪微博XSS蠕虫,可实现指数级自我复制传播。反射型XSS需要社会工程学配合(诱骗点击),影响范围有限。
Q3:如何对一个目标做完整的SQL注入测试?
A:标准流程如下:
① 信息收集 → 确定技术栈(报错信息、响应特征)
② 注入点探测 → 单引号、双引号、and 1=1/1=2
③ 判断注入类型 → 联合/报错/布尔/时间
④ 字段/表名猜测 → information\_schema / sysobjects
⑤ 数据提取 → 脱敏/加密字段重点关照
⑥ 权限提升 → 读写文件、UDF提权
⑦ 清理痕迹 → 删除日志(仅授权测试)
Q4:CSP能不能完全防止XSS?
A:CSP是重要的纵深防御手段,但不能完全依赖。已知绕过方式包括:JSONP端点、<base>标签劫持、域名配置过于宽松(如允许 \.cdn.com)、某些浏览器CSP实现差异等。正确的做法是CSP + 输出编码 + HttpOnly*组合使用,形成多层防御。
第五章 总结:安全思维比背诵更重要
面试官问SQL注入和XSS,真正想考察的不是你能不能背出十种绕过技巧,而是:
✅ 你是否理解漏洞产生的根本原因(信任边界模糊)
✅ 你是否掌握系统化的防御方法论(而非单一手段)
✅ 你是否有实战经验(能说出真实场景中的坑)
✅ 你的安全意识是否融入日常开发习惯
记住:安全不是一个功能,而是一种贯穿全生命周期的思维方式。从需求评审时的威胁建模,到代码审查时的安全Checklist,再到上线前的渗透测试——每一步都不能缺席。
🔐 关注我们,每日推送安全面试干货 + 行业热点
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论