Skip to content

本模块涵盖 Web 安全最核心的攻击手段与防御方案,包括 XSS、CSRF、SQL 注入、文件上传、SSRF、命令注入等常见漏洞类型,以及 OWASP Top 10 安全风险清单。是安全工程师、后端开发、前端开发面试的必考内容。


Q1: 什么是XSS攻击?有哪些类型?如何防御? 「🟡 中级」

考察点:考察 Web 安全最基础也是最重要的 XSS 漏洞。筛掉对 Web 安全毫无概念、不知道前端渲染风险的开发人员。

参考答案

XSS(Cross-Site Scripting,跨站脚本攻击)是指攻击者在网页中注入恶意脚本,当用户浏览页面时脚本在浏览器中执行,从而窃取用户信息、操纵页面内容或进行其他恶意操作。

三种主要类型

  1. 反射型 XSS(Reflected XSS)

    • 恶意脚本通过 URL 参数传递,服务端将参数反射到页面中
    • 攻击流程:攻击者构造恶意链接 → 用户点击 → 服务端返回包含脚本的页面 → 脚本执行
    • 特点:非持久化,需要诱导用户点击链接
    • 示例:http://example.com/search?q=<script>alert(1)</script>
  2. 存储型 XSS(Stored XSS)

    • 恶意脚本被存储到服务端(数据库、文件等),其他用户访问时自动执行
    • 攻击流程:攻击者提交包含脚本的内容 → 服务端存储 → 其他用户浏览页面 → 脚本执行
    • 特点:持久化,危害更大,常见于评论区、留言板、个人资料等
  3. DOM 型 XSS(DOM-based XSS)

    • 恶意脚本在客户端 DOM 解析时执行,不经过服务端处理
    • 攻击流程:攻击者构造恶意 URL → 前端 JS 读取 URL 参数并插入 DOM → 脚本执行
    • 特点:完全发生在客户端,服务端日志可能无记录

防御方案

  • 输入转义/输出编码:对所有用户输入进行转义,根据输出上下文(HTML/JS/CSS/URL)使用不同的编码方式
  • CSP(内容安全策略):设置 Content-Security-Policy 响应头,限制脚本加载来源,禁止内联脚本执行
  • HttpOnly Cookie:将敏感 Cookie 设置为 HttpOnly,防止被 XSS 窃取
  • 输入验证:对白名单字符进行校验,过滤危险标签和属性
  • 使用安全的模板引擎:现代前端框架(Vue/React)默认会对插值内容进行转义

追问延伸

  • CSP 有哪些指令?default-srcscript-srcstyle-srcimg-src 分别控制什么?
  • 如果 CSP 设置了 script-src 'self',还能被 XSS 利用吗?(可以,通过上传 JS 文件、JSONP 绕过等)
  • 什么是 XSS 蠕虫?如何传播?
  • 如何绕过前端转义?双写绕过、编码绕过、利用标签事件等

Q2: 什么是CSRF攻击?原理是什么?怎么防御? 「🟡 中级」

考察点:考察跨站请求伪造的理解。筛掉不清楚浏览器同源策略、Cookie 发送机制的开发人员。

参考答案

CSRF(Cross-Site Request Forgery,跨站请求伪造)是指攻击者诱导用户在已登录的情况下,访问恶意网站,利用用户的登录状态,以用户的名义向目标网站发送请求,执行非用户本意的操作。

攻击原理

用户已登录 A 网站(浏览器保存了 A 的 Cookie)

用户访问攻击者的 B 网站

B 网站的页面中包含向 A 网站发起请求的代码(img/form/script 等)

浏览器自动携带 A 网站的 Cookie 发送请求

A 网站验证通过,执行了用户不知情的操作

与 XSS 的区别

  • XSS:利用用户对网站的信任,注入脚本在网站内执行
  • CSRF:利用网站对用户浏览器的信任,伪造用户发起请求
  • XSS 可以用来实现 CSRF(通过 XSS 窃取 Token 后发起请求)

防御方案

  1. CSRF Token

    • 服务端生成随机 Token,嵌入到表单或请求头中
    • 每次请求携带 Token,服务端验证有效性
    • 攻击者无法获取到 Token,因此无法伪造请求
  2. SameSite Cookie 属性

    • Strict:完全禁止第三方 Cookie,跨站时不发送
    • Lax:仅允许安全的顶级导航(如点击链接)携带 Cookie
    • None:允许跨站发送,但必须配合 Secure 属性
  3. 验证 Referer / Origin

    • 检查请求的来源是否为合法域名
    • 缺点:Referer 可能被伪造或禁用
  4. 二次验证

    • 敏感操作要求输入密码、短信验证码等

追问延伸

  • SameSite 的 Lax 和 Strict 有什么区别?什么场景下 Cookie 会被发送?
  • 如果网站使用 JSON 接口(Content-Type: application/json),还需要担心 CSRF 吗?
    • 常规情况下 form 表单无法发送 JSON Content-Type,但可以通过 Flash 或某些 CORS 配置绕过
  • CSRF Token 为什么放在请求头里比放在表单里更安全?
  • 什么是 CSRF 的登录攻击?

Q3: 什么是SQL注入?有哪些类型?如何防止? 「🟡 中级」

考察点:考察数据库安全最经典的漏洞。筛掉写代码时直接拼接 SQL、不了解预编译的开发人员。

参考答案

SQL 注入(SQL Injection)是指攻击者通过在输入中插入恶意 SQL 代码,操纵后端数据库执行非预期的查询,从而获取、篡改数据,甚至控制服务器。

攻击原理

php
// 不安全的代码:直接拼接 SQL
$sql = "SELECT * FROM users WHERE username = '" . $_GET['username'] . "'";
// 输入:' OR '1'='1
// 变成:SELECT * FROM users WHERE username = '' OR '1'='1'

主要类型

  1. 联合注入(Union-based)

    • 使用 UNION SELECT 合并查询结果,直接获取数据
    • 要求前后查询列数一致、数据类型兼容
  2. 盲注(Blind SQL Injection)

    • 布尔盲注:根据页面返回是否正确判断条件真假
    • 时间盲注:通过 SLEEP() 等函数根据响应时间判断
    • 特点:页面不直接显示查询结果,需要逐字符猜解
  3. 堆叠注入(Stacked Queries)

    • 利用分号 ; 同时执行多条 SQL 语句
    • 取决于数据库驱动是否支持多语句执行
  4. 报错注入(Error-based)

    • 利用数据库报错信息带出数据
    • 如 MySQL 的 updatexml()extractvalue() 函数

防御方案

  1. 预编译(Prepared Statements)+ 参数化查询

    • 使用 ? 占位符,SQL 结构和数据分离
    • 是最根本、最有效的防御手段
  2. ORM 框架

    • 使用 MyBatis、Hibernate、Django ORM 等
    • 注意避免在 ORM 中写原生 SQL 拼接
  3. 输入验证和过滤

    • 白名单校验:限制输入格式(数字、邮箱、手机号等)
    • 黑名单过滤:转义特殊字符(辅助手段,不建议作为主要防御)
  4. WAF(Web 应用防火墙)

    • 检测和拦截常见 SQL 注入特征
    • 作为纵深防御的一环
  5. 最小权限原则

    • 数据库账号只授予必要权限,禁止 DROP、FILE 等高危操作

追问延伸

  • 预编译为什么能防 SQL 注入?原理是什么?
  • MyBatis 中 #{}${} 的区别?哪个会导致注入?
  • 什么是宽字节注入?什么场景下会出现?
  • SQL 注入 bypass WAF 的方法有哪些?(注释绕过、编码绕过、大小写绕过等)
  • order by 字段如何防注入?(因为字段名不能用预编译,需要白名单)

Q4: 什么是文件上传漏洞?怎么利用和防御? 「🟡 中级」

考察点:考察文件处理安全意识。筛掉对上传文件不做校验、直接存储执行的开发人员。

参考答案

文件上传漏洞是指网站允许用户上传文件,但没有正确校验文件类型、内容或存储方式,导致攻击者可以上传恶意脚本文件(如 webshell),并通过访问该文件执行代码,最终控制服务器。

常见绕过方式

  1. 后缀名绕过

    • 黑名单绕过:php5phtmlphp3aspasacer
    • 大小写绕过:PhppHpASP 等(Windows 不区分大小写)
    • 点号绕过:shell.php.(Windows 自动去掉末尾点号)
    • 空格绕过:shell.php (Windows 自动去掉末尾空格)
    • ::DATA 绕过:shell.php::DATA(NTFS 文件系统特性)
  2. MIME 类型绕过

    • 只校验 Content-Type 字段
    • 攻击者修改请求头为 image/jpeg 即可绕过
  3. 00 截断绕过

    • 利用 %00 空字节截断文件名
    • 常见于老版本 PHP(< 5.3.4),move_uploaded_file 等函数
  4. 文件头绕过

    • 只校验文件头(魔数),如 GIF89a
    • 在脚本开头加上 GIF89a 即可绕过
  5. 解析漏洞

    • Apache:shell.php.jpg 可能被当作 PHP 解析
    • Nginx:/shell.jpg/shell.php 路径解析漏洞
    • IIS:文件名分号截断 shell.asp;.jpg
  6. 竞争条件上传

    • 先上传后删除,在删除前访问执行

防御方案

  1. 白名单校验:只允许指定的文件后缀上传(比黑名单安全)
  2. 文件重命名:上传后使用随机文件名 + 白名单后缀,避免直接访问原文件名
  3. 存储隔离:将上传文件存储在非 Web 可访问目录,通过脚本读取输出
  4. 内容检测
    • 检查文件头(魔数)
    • 使用 getimagesize 检测图片尺寸
    • 图片二次渲染(重新生成图片)
  5. 设置正确的 Content-Type:下载时强制设置为 application/octet-stream 或对应类型
  6. 独立域名:上传文件使用独立域名,避免 Cookie 泄露和 XSS 影响主站

追问延伸

  • 如果只能上传图片,还能有什么危害?(图片马配合解析漏洞、XSS 中的 SVG 图片)
  • 什么是 webshell?一句话木马原理是什么?
  • 如何检测服务器上是否被植入了 webshell?
  • 文件上传和 XSS 能结合吗?(上传 SVG/HTML 文件实现 XSS)

Q5: 什么是SSRF攻击?有什么危害? 「🔴 高级」

考察点:考察服务端请求伪造的深度理解。筛掉对内部网络安全无概念、随意调用外部 URL 的后端开发。

参考答案

SSRF(Server-Side Request Forgery,服务端请求伪造)是指攻击者利用服务端的请求功能,构造请求访问内网资源或本地服务,从而探测内网结构、读取本地文件、攻击内网系统。

攻击原理

用户提交一个 URL 给服务端

服务端后端代码请求该 URL(如图片加载、网页抓取、资源获取)

攻击者将 URL 改为内网地址或本地文件协议

服务端以自身身份发起请求,访问了内网资源

常见利用场景

  1. 内网探测与端口扫描

    • 访问 http://127.0.0.1:3306/ 判断 MySQL 是否存在
    • 访问 http://192.168.1.0/24 探测内网网段
    • 根据响应时间、错误信息判断端口是否开放
  2. 读取本地文件

    • 使用 file:///etc/passwd 协议读取本地文件
    • 使用 gopher:// 协议构造 TCP 数据包
  3. 攻击内网服务

    • 攻击 Redis(未授权访问):gopher://127.0.0.1:6379/_*1%0d%0a...
    • 攻击内网 MySQL、MongoDB 等
    • 攻击内网 Web 应用(如 Jenkins、Elasticsearch)
  4. 云环境元数据泄露

    • 访问云服务商的元数据服务(169.254.169.254)
    • 获取临时 Access Key、实例信息等
  5. DoS 攻击

    • 请求大文件、慢响应资源,消耗服务端资源

防御方案

  1. 协议限制:只允许 http/https 协议,禁止 file://、gopher://、dict:// 等危险协议
  2. 内网地址黑名单
    • 禁用内网 IP 段(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、127.0.0.0/8)
    • 禁用云元数据地址(169.254.169.254)
  3. DNS Rebinding 防护
    • 先解析 DNS,再校验 IP → 存在时间差问题
    • 使用 DNS 缓存或直接使用 IP 白名单
    • 设置 DNS TTL 为 0 并在请求后再次验证
  4. URL 白名单:只允许访问指定域名的资源
  5. 统一错误处理:不对外暴露目标服务的响应详情,防止信息泄露
  6. 使用独立出口:外网请求走独立的网络出口,与内网隔离

追问延伸

  • 什么是 DNS Rebinding?如何绕过 IP 黑名单?
    • DNS 第一次返回外网 IP 通过校验,第二次返回内网 IP 实际请求
  • SSRF 中常用的协议有哪些?各自能做什么?
  • 如何利用 SSRF 攻击 Redis?能达到什么效果?
  • 什么是半连接式 SSRF(blind SSRF)?如何利用?
  • Java 和 PHP 中的 SSRF 有什么不同?(如 Java 的 URLConnection 会自动跳转)

Q6: 什么是命令注入/代码注入? 「🟡 中级」

考察点:考察系统安全意识。筛掉随意调用系统命令、不做参数校验的后端开发。

参考答案

命令注入(Command Injection) 是指攻击者通过在输入中注入恶意命令,利用系统命令执行函数,在服务器上执行任意系统命令。

代码注入(Code Injection) 是指攻击者注入恶意代码,由应用程序的解释器执行,如 PHP 的 eval()、Python 的 exec() 等。

命令注入原理

php
// 不安全的代码:直接将用户输入拼接到命令中
$ip = $_GET['ip'];
system("ping -c 4 " . $ip);
// 输入:127.0.0.1; cat /etc/passwd
// 执行:ping -c 4 127.0.0.1; cat /etc/passwd

常见注入符号

  • ;:命令分隔符,顺序执行
  • &&:前一个成功才执行后一个
  • ||:前一个失败才执行后一个
  • |:管道符,将前一个输出作为后一个输入
  • &:后台执行
  • 反引号 ``$():命令替换

代码注入示例

php
// eval 代码注入
$str = $_GET['str'];
eval("\$str = $str;");
// 输入:phpinfo();
python
# Python 代码注入
exec("result = " + user_input)

防御方案

  1. 避免使用危险函数:尽量不使用 system()exec()eval() 等函数,改用编程语言内置 API
  2. 白名单校验:如果必须执行命令,对输入参数进行严格的白名单校验
  3. 参数转义:使用 escapeshellarg()escapeshellcmd() 等函数转义特殊字符
  4. 使用安全的 API
    • 执行命令时使用参数数组形式(如 Python 的 subprocess.run([], shell=False)
    • 避免使用 shell=True
  5. 禁用危险函数:在 PHP.ini 中禁用 execsystemshell_exec
  6. 沙箱隔离:将执行命令的服务放在隔离环境中,限制权限和资源

追问延伸

  • 命令注入和代码注入有什么区别?
  • 什么是无回显的命令注入?如何利用?(带外通信:DNS Log、HTTP 请求)
  • 过滤了空格怎么绕过命令注入?(${IFS}%09、重定向等)
  • 什么是模板注入(SSTI)?和代码注入有什么关系?
  • Windows 和 Linux 下命令注入的语法差异?

Q7: OWASP Top 10 有哪些? 「🟡 中级」

考察点:考察安全知识面的广度。筛掉不关注安全社区、对行业标准不了解的候选人。

参考答案

OWASP(Open Web Application Security Project)是一个非营利的安全组织,其 Top 10 项目每几年更新一次,列出 Web 应用最关键的 10 项安全风险。

2021 版 OWASP Top 10

  1. A01:2021 - 失效的访问控制(Broken Access Control)

    • 用户可以访问未经授权的资源或执行越权操作
    • 包括水平越权、垂直越权、IDOR 等
    • 从第 5 位上升到第 1 位
  2. A02:2021 - 加密机制失效(Cryptographic Failures)

    • 数据传输或存储时未使用适当的加密
    • 明文密码、弱加密算法、证书问题等
    • 由之前的"敏感数据泄露"更名而来,从第 3 位上升到第 2 位
  3. A03:2021 - 注入(Injection)

    • SQL 注入、命令注入、XSS 等
    • 攻击者将恶意代码注入到应用中执行
    • 从第 1 位下降到第 3 位
  4. A04:2021 - 不安全设计(Insecure Design)

    • 设计层面的缺陷,如缺少安全设计模式、威胁建模不足
    • 2021 年新增类别,排名第 4
  5. A05:2021 - 安全配置错误(Security Misconfiguration)

    • 默认配置、不必要的功能、错误的权限设置
    • 目录遍历、默认密码、错误信息泄露等
    • 从第 6 位上升到第 5 位
  6. A06:2021 - 自带缺陷和过时的组件(Vulnerable and Outdated Components)

    • 使用存在已知漏洞的第三方库、框架
    • 组件版本过久未更新
    • 由之前的"使用含有已知漏洞的组件"更名
  7. A07:2021 - 识别和认证失败(Identification and Authentication Failures)

    • 身份认证机制存在缺陷
    • 弱密码、暴力破解、Session 管理不当等
    • 由之前的"身份认证失效"更名
  8. A08:2021 - 软件和数据完整性故障(Software and Data Integrity Failures)

    • 软件更新、关键数据未验证完整性
    • 供应链攻击、CI/CD 管道漏洞
    • 2021 年新增类别
  9. A09:2021 - 安全日志和监控故障(Security Logging and Monitoring Failures)

    • 缺乏安全日志记录和监控机制
    • 攻击无法被及时发现和响应
    • 由之前的"不足的日志记录和监控"更名,从第 10 位上升到第 9 位
  10. A10:2021 - 服务端请求伪造(SSRF)

    • 服务端请求伪造漏洞
    • 2021 年新增,直接进入 Top 10

追问延伸

  • 2021 版相比 2017 版有哪些变化?新增了哪些类别?
  • 你觉得哪个风险在实际项目中最常见?为什么?
  • 针对 A01 失效的访问控制,你会怎么做?
  • 什么是安全左移?和 Top 10 有什么关系?
  • 你如何在项目中落地 OWASP Top 10 的防护?