Skip to content

前端攻防安全

概述

前端安全是 Web 应用安全的重要组成部分,涉及 XSS、CSRF、点击劫持等多种攻击方式和防御措施。

常见攻击方式

1. XSS (跨站脚本攻击)

攻击类型

javascript
// 反射型 XSS
// URL: https://example.com?name=<script>alert('XSS')</script>
const name = new URLSearchParams(window.location.search).get('name')
document.body.innerHTML = `Hello ${name}` // 危险!

// 存储型 XSS
// 攻击者提交恶意脚本到数据库,其他用户访问时执行
const comment = '<script>steal(document.cookie)</script>'
saveComment(comment)

// DOM 型 XSS
const input = '<img src=x onerror=alert(1)>'
element.innerHTML = input // 危险!

防御措施

javascript
// 1. 输出编码
function escapeHtml(str) {
  const escapeMap = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#x27;',
    '/': '&#x2F;'
  }
  
  return str.replace(/[&<>"'/]/g, char => escapeMap[char])
}

// 使用
element.textContent = userInput // 安全
element.innerHTML = escapeHtml(userInput) // 安全

// 2. CSP (内容安全策略)
// HTTP Header
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.example.com

// HTML Meta
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

// 3. 使用安全的框架
// Vue 自动转义
<template>
  <div>{{ userInput }}</div> <!-- 安全 -->
</template>

// React 自动转义
function SafeComponent({ userInput }) {
  return <div>{userInput}</div> // 安全
}

// 4. HttpOnly Cookie
// 服务器设置
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict

2. CSRF (跨站请求伪造)

攻击示例

html
<!-- 攻击者网站 -->
<form action="https://bank.com/transfer" method="POST">
  <input type="hidden" name="to" value="attacker">
  <input type="hidden" name="amount" value="10000">
</form>
<script>document.forms[0].submit()</script>

防御措施

javascript
// 1. CSRF Token
// 服务器生成 Token
const csrfToken = generateCSRFToken()

// 前端请求携带 Token
fetch('/api/transfer', {
  method: 'POST',
  headers: {
    'X-CSRF-Token': csrfToken
  },
  body: JSON.stringify(data)
})

// 2. SameSite Cookie
Set-Cookie: sessionId=abc123; SameSite=Strict

// 3. 验证 Referer
// 服务器端验证
const referer = request.headers.referer
if (!referer || !referer.startsWith('https://yoursite.com')) {
  throw new Error('Invalid referer')
}

// 4. 双重 Cookie 验证
// 将 Token 同时放在 Cookie 和请求参数中
fetch('/api/action', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    ...data,
    csrf_token: getCookie('csrf_token')
  })
})

3. 点击劫持

攻击示例

html
<!-- 攻击者网站 -->
<style>
  iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
  }
</style>
<iframe src="https://bank.com/transfer"></iframe>
<button>点击领取奖品</button>

防御措施

javascript
// 1. X-Frame-Options
// HTTP Header
X-Frame-Options: DENY // 禁止所有嵌入
X-Frame-Options: SAMEORIGIN // 只允许同源嵌入

// 2. CSP frame-ancestors
Content-Security-Policy: frame-ancestors 'self' https://trusted.com

// 3. JavaScript 防御
if (window.top !== window.self) {
  window.top.location = window.self.location
}

// 或者
<style>body { display: none; }</style>
<script>
  if (self === top) {
    document.getElementsByTagName('style')[0].innerHTML = ''
  } else {
    top.location = self.location
  }
</script>

4. 中间人攻击

防御措施

javascript
// 1. 使用 HTTPS
// 强制 HTTPS
if (location.protocol !== 'https:') {
  location.href = 'https:' + window.location.href.substring(window.location.protocol.length)
}

// 2. HSTS
Strict-Transport-Security: max-age=31536000; includeSubDomains

// 3. 证书校验
// 使用证书固定(Certificate Pinning)

// 4. 安全的 Cookie
Set-Cookie: sessionId=abc123; Secure; HttpOnly; SameSite=Strict

安全最佳实践

1. 输入验证

javascript
// 前端验证(不能替代后端验证)
function validateInput(input) {
  // 白名单验证
  const allowedPattern = /^[a-zA-Z0-9_-]+$/
  if (!allowedPattern.test(input)) {
    throw new Error('Invalid input')
  }
  
  // 长度限制
  if (input.length > 100) {
    throw new Error('Input too long')
  }
  
  return input
}

// 使用
const userInput = validateInput(formData.username)

2. 安全的 API 调用

javascript
// 使用 HTTPS
const API_BASE = 'https://api.example.com'

// 添加认证头
async function secureFetch(url, options = {}) {
  const token = localStorage.getItem('auth_token')
  
  return fetch(url, {
    ...options,
    headers: {
      ...options.headers,
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    }
  })
}

// 错误处理
async function apiCall(url, options) {
  try {
    const response = await secureFetch(url, options)
    
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`)
    }
    
    return response.json()
  } catch (error) {
    console.error('API call failed:', error)
    throw error
  }
}

3. 敏感数据处理

javascript
// 不要在前端存储敏感信息
// ❌ 错误
localStorage.setItem('password', password)
localStorage.setItem('credit_card', cardNumber)

// ✅ 正确
// 只存储必要的非敏感信息
localStorage.setItem('user_id', userId)
sessionStorage.setItem('temp_token', tempToken)

// 及时清理
function logout() {
  localStorage.removeItem('auth_token')
  sessionStorage.clear()
  window.location.href = '/login'
}

4. 第三方库安全

javascript
// 定期更新依赖
npm audit
npm audit fix

// 检查已知漏洞
npm install -g npm-check-updates
ncu -u

// 使用 SRI (Subresource Integrity)
<script 
  src="https://cdn.example.com/library.js"
  integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux..."
  crossorigin="anonymous"
></script>

安全检测工具

1. 自动化扫描

bash
# OWASP ZAP
zap-cli quick-scan https://example.com

# NPM Audit
npm audit

# Snyk
snyk test

2. 浏览器安全工具

  • Chrome DevTools Security Panel
  • Firefox Developer Tools Security
  • Web Inspector (Safari)

相关资源

基于 VitePress 的本地知识库