目录


一、现代前端框架概览

框架安全特性对比

特性ReactVueAngularSvelte
默认XSS防护✓ (JSX转义)✓ (模板转义)✓ (模板转义)✓ (编译时)
dangerouslySetInnerHTML---
v-html---
[innerHTML]---
{@html}---
客户端模板JSXtemplatetemplate编译时
SSR支持Next.jsNuxtAngular UniversalSvelteKit
CSP友好
自动净化✗ (需手动)✗ (需手动)✓ (DomSanitizer)✗ (需手动)

XSS在框架中的体现

// 所有框架的默认行为:安全(自动转义)
React:    <div>{userInput}</div>         → &lt;...&gt;
Vue:      <div>{{ userInput }}</div>    → &lt;...&gt;
Angular:  <div>{{ userInput }}</div>    → &lt;...&gt;
 
// 危险API(原始HTML)
React:    <div dangerouslySetInnerHTML={{__html: userInput}} />
Vue:      <div v-html="userInput"></div>
Angular:  <div [innerHTML]="userInput"></div>

二、React 安全分析

dangerouslySetInnerHTML

// 危险:最直接的XSS入口
function UserComment({ text }) {
  return <div dangerouslySetInnerHTML={{ __html: text }} />;
}
// 如果 text = '<img src=x onerror=alert(1)>' → XSS!

href 属性注入

// 危险:javascript: 伪协议
function UserLink({ url }) {
  return <a href={url}>Click me</a>;
}
// url = 'javascript:alert(1)' → 点击弹窗!
 
// 安全:验证协议
function SafeLink({ url }) {
  const safe = url.startsWith('https://') || url.startsWith('http://') 
    ? url : '#';
  return <a href={safe}>Click me</a>;
}

React的防护机制

// 1. JSX自动转义
const userInput = '<img src=x onerror=alert(1)>';
return <div>{userInput}</div>;
// 渲染结果:<div>&lt;img src=x onerror=alert(1)&gt;</div>
// → XSS被自动防护!
 
// 2. 但以下情况不会转义:
// - dangerouslySetInnerHTML
// - href属性
// - 自定义属性(通过回调注入JS)

React SSR (Next.js)

// 危险:SSR中HTML注入
export async function getServerSideProps(context) {
  return {
    props: {
      // 如果用户输入直接渲染到HTML → SSR XSS
      content: context.query.content,
    },
  };
}
 
// 防御:使用DOMPurify
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(dirtyHTML);

React Native 特有攻击面

// WebView注入
<WebView source={{ html: userControlledHTML }} />
// 如果HTML可控 → XSS
 
// Deep Link劫持
// myapp://callback?code=xxx
// 如果Deep Link不验证 → 应用被劫持

三、Vue 安全分析

v-html 注入

<!-- 危险 -->
<div v-html="userInput"></div>
<!-- userInput = '<img src=x onerror=alert(1)>' → XSS -->

动态模板编译

// 非常危险
const template = '<div>' + userInput + '</div>';
new Vue({ template });
// 如果 userInput 是 {{constructor.constructor('alert(1)')()}} → CSTI

Vue SSR攻击 (Nuxt.js)

// Nuxt.js服务端渲染
// 如果数据中含有未转义的内容
<template>
  <div v-html="content"></div>
</template>
 
<script>
export default {
  async asyncData({ query }) {
    return { content: query.content };
    // query.content 如果是服务器渲染的模板 → SSR XSS
  }
}
</script>

Vue特有攻击

1. 原型链污染(Vue 2.x的合并选项)
   Vue.util.defineReactive → 可能被污染利用

2. 动态组件
   <component :is="userControlledComponent">
   如果组件名可控 → 可能加载恶意组件

3. 自定义指令
   v-custom="userInput"
   如果在指令中执行eval → RCE

4. Vuex Store
   XSS读取Vuex中的数据 → 窃取所有前端状态

四、Angular 安全分析

内置防护

// Angular默认进行模板表达式安全上下文检查
@Component({
  template: `<div>{{ userInput }}</div>`
})
// 默认安全 —— Angular自动转义
 
// DOM Sanitizer
constructor(private sanitizer: DomSanitizer) {}
 
// 需要显式绕过安全检查(标记为危险)
this.sanitizer.bypassSecurityTrustHtml(dangerousHtml);
this.sanitizer.bypassSecurityTrustUrl('javascript:alert(1)');
this.sanitizer.bypassSecurityTrustScript(dangerousScript);

Angular安全漏洞历史

1. AngularJS沙箱绕过(1.x系列)
   - 多个版本被绕过(见CSTI章节)
   
2. Angular Universal (SSR)
   - 服务端渲染时的HTML注入
   
3. 第三方组件
   - Angular Material / PrimeNG中的XSS

五、Next.js / Nuxt SSR安全

SSR特有安全问题

// 问题1:__NEXT_DATA__ 泄露
// Next.js在HTML中内嵌初始数据:
<script id="__NEXT_DATA__" type="application/json">
  {"props":{"pageProps":{"user":{"token":"secret"}}}}
</script>
// XSS可以读取这个JSON!
 
// 问题2:API Routes中的SSRF
// pages/api/proxy.js
export default async function handler(req, res) {
  const url = req.query.url;
  const response = await fetch(url);  // ← SSRF!
  res.json(await response.json());
}
 
// 问题3:动态导入中的路径遍历
import(`../components/${userInput}`);  // 如果userInput可控

SSR XSS (Server-Side XSS)

// 场景:用户输入被服务端渲染为HTML
// GET /page?content=<script>alert(1)</script>
 
// 如果服务端直接渲染用户输入:
app.get('/page', (req, res) => {
  const html = `<div>${req.query.content}</div>`;
  res.send(html);  // ← SSR XSS!
});
 
// 防御:服务端也做转义
const escapeHtml = (str) => str
  .replace(/&/g, '&amp;')
  .replace(/</g, '&lt;')
  .replace(/>/g, '&gt;');

六、SPA安全特性

SPA vs 传统MPA

特性SPAMPA
渲染位置客户端服务端
路由Hash/History APIURL路径
状态管理Redux/Vuex/PiniaSession/数据库
XSS面所有JS暴露相对较小
敏感数据前端状态中仅在服务端
SEO需要SSR天然支持

SPA攻击面

// 1. 前端路由中的Token
// https://app.com/reset-password#access_token=xxx
// token在hash → 可能被JS读取
 
// 2. 状态管理中的数据泄露
// Redux DevTools在生产环境启用 → 所有状态可见
const store = createStore(reducer, 
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
 
// 3. Service Worker缓存敏感数据
// Cache API可以存储API响应
caches.open('api-cache').then(cache => {
  cache.put('/api/user/profile', response.clone());
});

七、前端供应链安全

npm依赖攻击

# 1. Typosquatting(拼写错误劫持)
npm install loadsh  # 而不是 lodash → 恶意包
 
# 2. 依赖混淆
# 如果公司使用私有包 @company/utils
# 攻击者在npm注册一个同名的公开包
npm install @company/utils  # → 获取攻击者的包
 
# 3. 版本回退
# 恶意维护者接手不再维护的包
# 发布"安全更新"实际含后门

CDN劫持

<!-- 如果CDN域名过期或被接管 -->
<script src="https://cdn-legacy.example.com/jquery.min.js"></script>
<!-- 攻击者注册 cdn-legacy.example.com → 任意JS -->

子资源完整性 (SRI)

<!-- 安全:使用SRI hash确保CDN脚本未被篡改 -->
<script src="https://cdn.example.com/library.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYXiN21q2yXJEJIYXqL"
  crossorigin="anonymous">
</script>
 
<!-- 如果CDN返回的库内容被篡改 → SRI不匹配 → 浏览器拒绝加载 -->

八、红队视角总结

框架攻击速查

框架主要弱点利用方式
ReactdangerouslySetInnerHTML寻找使用点 + XSS payload
Vuev-html + 动态模板注入模板表达式
AngularbypassSecurityTrust寻找标记为安全的输入
Next.jsSSR XSS + API routes SSRF注入服务端渲染内容
jQueryhtml() + 选择器注入XSS + DOM XSS

框架检测方法

// 检测React
!!document.querySelector('[data-reactroot]')
!!window.React
 
// 检测Vue
!!document.querySelector('[data-v-]')  // scoped css attribute
!!window.__VUE_DEVTOOLS_GLOBAL_HOOK__
 
// 检测Angular
!!document.querySelector('[ng-version]')
!!window.ng
 
// 检测Next.js
!!document.getElementById('__NEXT_DATA__')
 
// 检测Nuxt
!!document.getElementById('__NUXT_DATA__')

推荐工具

工具用途
React Developer Tools检查React组件状态
Vue DevTools检查Vuex Store
Wappalyzer自动检测前端框架
npm audit检查依赖漏洞
retire.js检测已知漏洞的JS库

返回 前端基础总目录