安全实践
从浏览器安全模型到 XSS、CSRF、CSP、Session 与供应链攻击,建立现代前端安全体系
前端安全最容易出现的误区是:
“前端代码都是公开的,所以没什么安全可做。”
实际上前端承担的是:
输入
展示
身份
请求
状态
第三方 SDK
浏览器能力因此前端安全的核心不是:
隐藏 JavaScript。
而是:
正确理解浏览器的安全边界。
1. Origin 是浏览器安全模型的基础
一个 Origin:
scheme
+
host
+
port例如:
https://example.com:443与:
http://example.com:80不是同一个 Origin。
2. Same-Origin Policy
浏览器不会允许一个 Origin 随意读取另一个 Origin 的资源。
例如:
https://evil.example不能随意读取:
https://bank.example中的页面数据。
这就是:
Same-Origin Policy的重要意义。
3. CORS 是什么?
CORS 不是:
“关闭浏览器跨域。”
而是:
服务器通过 HTTP 响应头告诉浏览器,哪些跨 Origin 请求可以被 JavaScript 读取。
例如:
Access-Control-Allow-Origin: https://example.com注意:
CORS 是浏览器安全机制。
服务器之间直接请求并不受浏览器 CORS 限制。
4. XSS
XSS 的核心:
Untrusted Input
↓
HTML / JS Context
↓
Browser Execution常见来源:
- innerHTML
- dangerouslySetInnerHTML
- URL
- Markdown
- 富文本
- 第三方内容
例如:
element.innerHTML = userInput如果:
userInput未经正确处理,就可能产生 XSS。
5. 为什么 React 默认情况下相对安全?
React 通常会对:
<div>{value}</div>进行转义。
所以:
<div>
{userInput}
</div>和:
<div
dangerouslySetInnerHTML={{
__html: userInput
}}
/>安全模型完全不同。
第二种相当于:
“我明确告诉框架,这段字符串就是 HTML。”
因此必须谨慎。
6. CSP
CSP:
Content Security Policy可以理解成:
告诉浏览器哪些资源、脚本和行为是允许的。
例如:
Content-Security-Policy:
default-src 'self';
script-src 'self';如果攻击者注入:
<script src="https://evil.example/x.js">浏览器可以根据 CSP 阻止执行。
但:
CSP 不是 XSS 的替代品。
正确思路是:
输入验证
+
输出编码
+
安全框架
+
CSP形成纵深防御。
7. Nonce CSP
现代严格 CSP 可以使用:
nonce例如:
script-src 'nonce-abc123'HTML:
<script nonce="abc123">只有匹配 nonce 的脚本才允许执行。
关键点:
nonce 必须具有足够随机性,并且每次响应都应该重新生成。
8. CSRF
CSRF 的核心不是:
“黑客拿到了 Cookie。”
而是:
浏览器可能自动携带用户身份信息,使攻击者诱导用户浏览器向目标站点发起带认证信息的请求。
例如:
用户已经登录
↓
Cookie 自动存在
↓
恶意页面诱导请求
↓
目标服务器看到合法 Cookie9. CSRF 防御
常见策略:
SameSite Cookie
+
CSRF Token
+
Origin / Referer 校验
+
服务端鉴权特别需要注意:
CSRF 防护必须在服务端完成。
前端隐藏按钮:
不是安全边界。10. Session Cookie 怎么设计?
推荐:
Set-Cookie:
session=xxx;
HttpOnly;
Secure;
SameSite=Lax;其中:
HttpOnly
JavaScript 无法直接读取:
document.cookie中的这个 Cookie。
因此可以降低部分 XSS 直接窃取 Session Cookie 的风险。
Secure
只通过:
HTTPS发送。
SameSite
控制跨站请求中的 Cookie 发送行为。
11. LocalStorage 存 Token 有什么问题?
例如:
localStorage.setItem(
'token',
token
)一旦发生 XSS:
localStorage.getItem('token')可能直接读取。
因此对于高价值 Session,常见设计是:
HttpOnly Cookie而不是:
localStorage Token但最终方案仍然需要结合:
架构
跨域需求
CSRF 模型
API 设计综合决定。
12. “前端鉴权”不是安全边界
例如:
if (user.role === 'admin') {
showDeleteButton()
}只能控制:
UI不能控制:
Authorization攻击者完全可以:
curl
Postman
自定义请求直接调用 API。
因此:
Frontend Permission
↓
UX
Backend Authorization
↓
Security二者必须分开。
13. 第三方 SDK 是巨大的攻击面
例如:
- Analytics
- Ads
- Chat
- A/B Test
- Payment
- Social Login
第三方 JavaScript 一旦被加载:
<script src="third-party.js">它通常就在你的页面上下文中运行。
因此供应链安全需要关注:
- 依赖数量
- 依赖来源
- 版本锁定
- Subresource Integrity
- CSP
- 第三方脚本权限
- 依赖漏洞扫描
14. 依赖供应链攻击
现代前端:
npm install实际上引入了:
你的代码
↓
依赖
↓
依赖的依赖
↓
更多依赖形成:
Dependency Graph因此:
一个 npm package 被攻击,可能影响整个应用。
成熟工程需要:
Lockfile
+
Dependency Audit
+
版本策略
+
权限控制
+
构建隔离15. 安全 Headers
常见安全 Header:
- Content-Security-Policy
- Strict-Transport-Security
- X-Content-Type-Options
- Referrer-Policy
- Permissions-Policy
以及与页面嵌入相关的:
frame-ancestors安全 Header 的意义不是:
“加几个 Header 就安全了。”
而是:
让浏览器参与执行安全策略。
16. 安全的真正模型
成熟 Web 应用应该形成:
Browser
↓
Origin Boundary
↓
HTTPS
↓
Cookie / Session
↓
Authentication
↓
Authorization
↓
Input Validation
↓
Output Encoding
↓
CSP
↓
Monitoring每一层解决不同问题。