CompTIA SY0-701: 应用与 Web 安全 — 学习指南
属于 CompTIA Security+ SY0-701 — 学习指南. 使用经过验证的答案练习: CompTIA 考试中心, 或参加限时模拟考试: ExamRoll.io.
现代应用程序处于业务逻辑、敏感数据和不受信任的用户输入的交汇点。由于 Web 和移动前端暴露于整个互联网,它们构成了任何企业中最大且最常被利用的攻击面之一。要保护它们,需要采用分层控制,从代码的编写方式开始,一直延伸到运行时保护、完整性验证和持续测试。
注入攻击
注入攻击仍然是典型的 Web 漏洞。当应用程序将不受信任的输入拼接到解释器(如 SQL 查询、shell 命令、LDAP 过滤器、XML 解析器或模板引擎)中,而没有正确地将代码与数据分离时,就会发生注入攻击。在 SQL 注入 (SQLi) 攻击中,攻击者操纵查询,使数据库执行由攻击者控制的逻辑。PHP 中一个经典的漏洞模式如下所示:
$query = "SELECT * FROM users WHERE username = '" . $_GET['user'] . "'";
提交 admin' OR '1'='1 会将查询转变为一个返回所有行的恒真式。更高级的变种包括基于联合的提取 (' UNION SELECT credit_card FROM payments--)、盲注布尔或基于时间的推断 (' AND SLEEP(5)--),以及通过 DNS 回调进行的带外数据渗透。根本的修复方法是使用参数化查询或预处理语句,它们将查询模板及其参数作为独立的结构发送到数据库:
cursor.execute("SELECT * FROM users WHERE username = %s", (user_input,))
命令注入遵循相同的模式,但目标是操作系统 shell。像 os.system("ping " + host) 这样的代码允许攻击者提交 8.8.8.8; cat /etc/passwd 来执行任意命令。修复措施要求完全避免 shell 调用,使用接受参数数组的 API(例如 subprocess.run(["ping", host], shell=False)),并对任何必须传递给 shell 的值应用严格的白名单验证。
跨站脚本和 CSRF
跨站脚本 (Cross-site scripting, XSS) 是将恶意脚本注入到受信任应用程序渲染的页面中,导致受害者的浏览器在站点源 (origin) 的上下文中执行攻击者代码。反射型 XSS (Reflected XSS) 将攻击载荷从一个易受攻击的参数中“反弹”回来;存储型 XSS (Stored XSS) 将攻击载荷持久化到数据库中,并将其传送给每一位访问者;基于 DOM 的 XSS (DOM-based XSS) 完全发生在客户端 JavaScript 中,它将不受信任的数据写入 innerHTML、document.write 或类似的接收器 (sinks)。其后果从会话劫持、键盘记录到通过强制操作实现账户完全接管不等。
跨站请求伪造 (Cross-site request forgery, CSRF) 是一种不同但互补的攻击。它滥用浏览器自动包含 cookie 的特性,诱骗已认证的用户提交非预期的请求——例如,在一个恶意网站上隐藏一个表单,该表单向 bank.com/transfer 发送 POST 请求。防御措施包括同步器令牌(嵌入在表单中并在服务器端验证的、每个会话唯一的随机值)、SameSite=Lax 或 SameSite=Strict cookie 属性,以及对敏感操作要求重新认证。XSS 和 CSRF 经常被混淆,但 XSS 是在受害者的浏览器中运行代码,而 CSRF 只是让浏览器发出一个请求;值得注意的是,一次成功的 XSS 攻击可以攻破大多数 CSRF 防御措施。
安全编码:输入验证与输出编码
这两种控制措施经常被混淆,但它们解决的是不同的问题。输入验证确保数据在应用程序处理它之前符合预期的结构——长度、类型、字符集、范围、格式。验证应该在服务器端进行,并尽可能使用白名单(例如,用户名的白名单可以是 ^[A-Za-z0-9_]{3,20}$)。使用 JavaScript 进行的客户端验证仅仅是一个可用性功能;它可以用任何 HTTP 代理绕过,绝不能作为安全边界。
输出编码确保数据在流入的任何上下文中都能被安全地渲染。同一个作为完全有效输入的字符串,根据其最终位置可能需要不同的处理:HTML 主体上下文需要 HTML 实体编码(< → <),属性上下文需要带引号的属性编码,JavaScript 上下文需要 \xHH 转义,而 URL 需要百分号编码。像 O'Brien 这样的用户名是合法的输入,但当放入 HTML 时必须编码为 O'Brien。输入验证不能替代输出编码,输出编码也不能替代输入验证——它们在数据生命周期的不同点解决不同的问题。
额外的加固措施包括使用内容安全策略 (Content Security Policy, CSP) 头部来限制脚本来源,为会话 cookie 设置 HttpOnly 和 Secure 标志,以及在每个信任边界使用参数化 API。
WAF 和文件上传保护
Web 应用程序防火墙 (WAF) 检查 HTTP 流量,并阻止与已知恶意模式匹配的请求——例如 SQLi 特征、XSS 载荷、路径遍历序列、协议异常。WAF 通常作为反向代理部署(例如带有 OWASP 核心规则集的 ModSecurity、AWS WAF、Cloudflare、F5),当发现漏洞但代码尚未修复时,它能提供有价值的虚拟补丁。然而,WAF 是一种补偿性控制,不能替代安全编码。经验丰富的攻击者经常通过编码技巧、HTTP 参数污染和载荷分片来绕过 WAF。
文件上传功能值得特别关注,因为它结合了不受信任的内容、服务器端存储以及通常还涉及执行。保护措施包括:通过检查文件的魔术字节 (magic bytes) 而不是信任文件扩展名或 Content-Type 头部来验证文件类型;将上传的文件存储在 Web 根目录之外;将文件重命名为服务器生成的标识符(以防止通过精心构造的文件名进行目录遍历);在存储前使用反病毒软件进行扫描;以及从一个独立的域提供用户上传的内容,以防止同源脚本执行。
实际案例:SQL 注入导致数据库完全失陷
一家零售公司的产品搜索端点接受一个 category 参数,该参数未经净化处理就被直接拼接到 SQL 查询中。一名安全研究员发现,在提交 ' UNION SELECT table_name,null,null FROM information_schema.tables-- 后,响应中返回了所有数据库表的列表。随后的请求提取了 customers 表,从而获取了 120 万条记录,其中包括姓名、电子邮件地址和经过 bcrypt 哈希处理的密码。攻击者还发现了一个存储过程,可以通过 SQL 注入来调用该过程,以便向 Web 根目录写入文件,从而实现了 webshell 部署和服务器的完全失陷。该漏洞已存在三年之久,并且在之前的两次渗透测试中均被遗漏,因为测试人员只测试了登录表单,而没有测试搜索端点。经验教训是:注入测试必须覆盖每个端点中的每个参数,而不仅仅是那些显而易见的身份验证路径。
← 事件响应、取证与评估 · 所有领域 · 云、虚拟化与容器安全 →
练习这些题目 → · 在 ExamRoll.io 上限时练习 →
Pass the whole exam — not just this question
You found this answer. Get every verified question and explanation in one place, and save hours of prep. Free to start.
通过考试 →