前端一面:前端安全基础(XSS 与 CSRF)

很多团队在一面/二面都会问一两个前端安全相关的问题,最常见的就是 XSS 和 CSRF。这一篇重点放在“能讲清楚攻击原理 + 基本防御思路”,再补两道常见题的参考答案。

XSS 的核心是:攻击者设法让自己的脚本在受害者的浏览器里执行,一般有几种常见形式:

  • 反射型 XSS

    • 恶意脚本藏在 URL 参数里,服务器拿参数原样拼进 HTML 返回;
    • 受害者点击特制链接,浏览器解析 HTML 时执行了这段脚本。
  • 存储型 XSS

    • 恶意脚本被存进了数据库(例如评论内容、用户昵称等);
    • 其它用户访问页面时,后端从数据库取出这些内容原样输出,脚本在他们的浏览器里执行。
  • DOM 型 XSS

    • 不经过后端模板,而是在前端 JS 里直接把不可信的数据塞进 innerHTML 等 API;
    • 恶意内容通过前端逻辑“拼装”进 DOM。

本质上,XSS 都是在利用“没有对不可信输入做正确转义/过滤”这一点。

  • 输出转义

    • 在把用户输入渲染到 HTML 时进行适当的转义(例如 < 转成 &lt;);
    • 针对不同上下文(HTML、属性、URL、JS 字面量)使用合适的转义规则。
  • 尽量使用安全的 DOM API

    • 能用 textContent/innerText 的地方不要用 innerHTML
    • 如必须插入 HTML 片段,也要对来源做白名单过滤。
  • 内容安全策略(CSP)

    • 通过 HTTP 头 Content-Security-Policy 限制脚本来源;
    • 比如禁止行内脚本,只允许加载指定域名的 JS。

在一面回答时,不需要穷举所有类型,重点是能说明:“XSS 是因为把不可信输入当成 HTML/JS 执行了,我们要做的是合理转义、限制脚本来源、避免随意拼 HTML。”

CSRF 的核心是:攻击者引导用户在登录态下访问一个恶意页面,由这个页面发起对受信任站点的请求,浏览器自动带上 Cookie,从而在用户不知情的情况下完成敏感操作。

典型流程:

  • 用户已经在银行网站 bank.com 登录并保持会话;
  • 攻击者发给用户一个恶意页面 evil.com/attack.html
  • 这个页面里嵌入了一个 <img src="https://bank.com/transfer?amount=1000&to=hacker"> 之类的请求;
  • 浏览器在访问 bank.com 时会自动带上 Cookie,后端如果没有额外校验,就会误以为这是用户的真实操作。
  • CSRF Token

    • 在页面中嵌入一个随机 Token,提交表单/发起请求时必须带上;
    • 服务器验证 Token 是否匹配,防止第三方站点伪造请求。
  • SameSite Cookie

    • 给 Cookie 设置 SameSite 属性(如 Lax/Strict),限制第三方网站发起请求时是否携带 Cookie;
    • 现代浏览器默认会收紧跨站请求中 Cookie 的发送行为。
  • Referer/Origin 检查(有一定局限)

    • 服务器检查请求来源域名是否可信;
    • 对于不可靠或被篡改的环境有局限,但可作为辅助手段。

回答时可以抓住一句话:

“CSRF 利用的是浏览器自动带 Cookie 的特性,防御的核心就是增加一个攻击者无法伪造的额外验证(Token / SameSite 等)。”

参考答案要点:

  • XSS 是攻击者通过注入恶意脚本,让这段脚本在其它用户的浏览器里执行;
  • 可以简单提到反射型/存储型/DOM 型这三类,重点说明“都是因为不可信输入被当作 HTML/JS 执行了”;
  • 防御手段:
    • 输出转义:对用户输入在输出到页面前做适当转义;
    • 避免直接使用 innerHTML 拼接不可信内容,尽量用 textContent 等安全 API;
    • 配置 CSP 限制脚本来源,减少被注入脚本执行的可能性。

如果面试官继续追问,可以举一个简单示例:

1// 危险写法:
2element.innerHTML = userInput;
3
4// 更安全的写法:
5element.textContent = userInput;

参考答案要点:

  • CSRF 是利用浏览器自动带 Cookie 的特性,在用户不知情的情况下伪造对受信任站点的请求;
  • 典型场景是“恶意页面发起转账/修改密码请求,浏览器夹带了用户的登录 Cookie”;
  • 防御手段:
    • 在关键操作里使用 CSRF Token,只有页面内合法生成的表单/请求才能通过验证;
    • 给 Cookie 设置合适的 SameSite 属性,限制第三方站点发起请求时是否带 Cookie;
    • 必要时结合 Referer/Origin 校验。

可以顺带强调一句:CSRF 主要针对“依赖 Cookie 做身份认证的 GET/POST 请求”,
如果前端改用额外的 Header 携带 token,也要注意不能被第三方站点轻易获取。

如果面试官进一步问“还有哪些前端安全问题需要注意?”,可以点几个常见的:

  • 组件中对外暴露的 dangerouslySetInnerHTML / v-html 要非常谨慎使用;
  • 在日志/错误上报中避免包含敏感信息(如 token、密码等);
  • 对文件上传、富文本编辑器这种高风险入口要有白名单/过滤策略。

不需要展开讲细节,但提到这些点,会给人“在实际项目中有安全意识”的印象。