一. xss
XSS(跨站脚本攻击,Cross-Site Scripting) 是一种常见的网络安全漏洞,攻击者通过向网页中注入恶意脚本(如JavaScript),当其他用户访问该页面时,脚本会在其浏览器中执行,从而窃取数据、劫持会话或破坏网站功能
XSS 的核心原理
- 攻击目标:利用网站对用户输入的不安全处理,将恶意代码“伪装”成合法内容。
- 执行条件:恶意脚本被浏览器误认为是网站的正常代码,直接执行。
- 传播方式:通过用户输入、URL参数、表单提交等途径注入恶意内容
XSS 的三种类型
1. 存储型 XSS(持久化)
- 原理:恶意脚本被永久存储在目标服务器(如数据库、评论、用户资料)。
- 触发场景:用户访问包含恶意脚本的页面时(如论坛帖子、商品详情页)。
- 示例: 攻击者在评论区提交 ,所有访问该评论的用户都会触发攻击。
2. 反射型 XSS(非持久化)
- 原理:恶意脚本通过URL参数传递,由服务器“反射”回页面中。
- 触发场景:用户点击攻击者构造的恶意链接后触发(如钓鱼邮件、虚假广告)。
- 示例:
http://example.com/search?keyword=<script>alert('XSS')</script>
如果服务器未过滤参数,页面会直接执行脚本。
3. DOM 型 XSS
- 原理:漏洞存在于客户端JavaScript代码中,通过修改DOM(文档对象模型)触发。
- 触发场景:前端代码直接使用未处理的用户输入(如document.write()、innerHTML)
- 示例:
// 假设从URL获取参数并直接写入页面
var userInput = location.hash.substring(1);
document.getElementById("content").innerHTML = userInput;
XSS 的危害
1. 窃取敏感信息
- 盗取用户Cookie、登录凭证、银行卡信息等。
2. 会话劫持
- 攻击者冒充用户登录账户,进行转账、发帖等操作。
3. 网页篡改
- 插入虚假内容(如钓鱼表单、广告),强制跳转到恶意网站。
4. 传播恶意软件
- 通过用户社交关系链扩散攻击(如蠕虫式传播)。
5. 法律与声誉损失
- 数据泄露可能导致法律追责(如违反GDPR),损害企业声誉。
防御 XSS
1. 输入过滤与验证
- 对用户输入进行严格校验(如长度、格式),过滤
2. 输出编码
- 根据输出位置(HTML、JavaScript、URL)对动态内容进行转义,例如:
- HTML转义:将 < 转为 <,> 转为 >。
- JavaScript转义:使用 JSON.stringify() 或 \xXX 格式。
3. 内容安全策略(CSP)
- 通过HTTP头限制页面资源加载,禁止执行内联脚本(Content-Security-Policy: script-src 'self')。
4. 使用安全框架
- React、Vue等现代前端框架默认转义动态内容,避免直接操作DOM。
5. 设置 Cookie 属性
- 标记敏感Cookie为 HttpOnly(禁止JavaScript读取)和 Secure(仅通过HTTPS传输)
总结
XSS的本质是信任了不可信的用户输入。防御的关键在于:
- 永远不要信任用户提交的内容。
- 对输入过滤、对输出编码。
- 利用现代技术(如CSP、安全框架)降低风险
二 CSRF (跨站请求伪造,Cross-Site Request Forgery)
CSRF 是一种利用用户已登录的身份,通过诱导用户点击恶意链接或访问恶意页面,以用户名义发起非授权请求的攻击方式。其核心是 “借用”用户的身份权限,绕过服务端验证。
1、CSRF 攻击原理
1. 攻击条件:
- 用户已登录目标网站(如银行网站),并在浏览器中保存了会话凭证(如 Cookie)。
- 目标网站未对敏感操作(如转账、修改密码)做防 CSRF 校验。
2. 攻击流程:
- 用户访问恶意网站或页面。
- 恶意页面中隐藏一个自动触发的请求(如
)。
- 浏览器自动携带用户的 Cookie 向目标网站发起请求,完成攻击者指定的操作。
二、CSRF 攻击示例
场景:银行转账接口未防护 CSRF
* 正常转账请求(GET 请求,实际应使用 POST):
Host: bank.com
Cookie: sessionId=用户登录凭证
* 恶意页面:
<html>
<body>
<!-- 隐藏请求自动触发转账 -->
<img src="http://bank.com/transfer?to=attacker&amount=10000">
</body>
</html>
- 用户访问该页面时,浏览器自动发送请求完成转账。
三、CSRF 防御措施
1. CSRF Token
* 原理:服务端生成随机 Token,嵌入表单或请求头,验证请求的合法性。
* 实现步骤:
- a. 用户访问表单页时,服务端生成 Token 并存储在 Session 或 Cookie 中。
- b. 表单提交时携带该 Token(如隐藏字段或请求头)。
- c. 服务端验证 Token 是否匹配。
代码示例
<!-- 表单中嵌入 Token -->
<form action="/transfer" method="POST">
<input type="hidden" name="csrfToken" value="随机值">
<!-- 其他表单字段 -->
</form>
2. SameSite Cookie 属性
* 原理:通过 Cookie 的SameSite属性限制跨域请求携带 Cookie。
- SameSite=Strict:完全禁止跨域携带 Cookie。
- SameSite=Lax(默认):允许部分安全跨域请求(如导航跳转)。
* 设置方式:
Set-Cookie:sessionId=123; SameSite=Lax; Secure
3. 验证 Referer/Origin 请求头
* 原理:检查请求来源是否合法(需注意 Referer 可能被篡改或缺失)。
* 代码示例(服务端校验):
python if request.referer not in ["https://trusted.com", "https://bank.com"]:
raise CSRFValidationError("非法来源")
4. 关键操作使用 POST 而非 GET
- GET 请求易被嵌入
<img>或<script>标签自动触发,POST 需构造表单或 AJAX,增加攻击难度。
5. 自定义请求头(结合 CORS)
* 原理:前端在 AJAX 请求中设置自定义头(如X-Requested-With: XMLHttpRequest)。
* 服务端校验:仅允许携带自定义头的请求(需配合 CORS 策略)。
Access-Control-Allow-Headers:X-Requested-With
四、CSRF 与 XSS 的区别
| 特性 | CSRF | XSS |
|---|---|---|
| 攻击目标 | 利用用户身份发起请求 | 用户已登录目标网站 |
| 依赖条件 | 用户已登录目标网站 | 网站存在未过滤的用户输入注入点 |
| 防御核心 | 验证请求的合法性(Token、来源) | 过滤输入和转义输出 |
| 攻击范围 | 跨站请求 | 同站脚本注入 |
五、现代框架的 CSRF 防护
1. React/Vue(前端):
从 Cookie 读取 CSRF Token,并在请求头中携带:
const csrfToken = document.cookie.replace(/(?:(?:^|.*;\s*)XSRF-TOKEN\s\*=\s\*(\[^;]*).*$)|^.*$/, '\$1');
// 发送请求时携带 Token
fetch('/api/transfer', {
method: 'POST',
headers: {
'X-XSRF-TOKEN': csrfToken
}
});
六、总结
| 防御方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| CSRF Token | 表单和 AJAX | 请求高安全性 | 需前后端配合 |
| SameSite Cookie | 所有 Cookie 敏感操作 | 浏览器自动支持 | 兼容性需考虑(旧浏览器) |
| 校验Referer/Origin | 简单接口防护 | 实现简单 | Referer 可能被伪造或缺失 |
核心原则:
- 敏感操作必须验证来源(如 Token、Referer)。
- 避免将敏感接口设计为 GET 请求。
- 结合 SameSite Cookie 和 CSRF Token 实现双重防护。
三 跨域问题
跨域(Cross-Origin) 是浏览器出于安全考虑实施的 同源策略(Same-Origin Policy) 导致的限制。当网页的 协议(HTTP/HTTPS)、域名(domain) 或 端口(port) 中任意一项与目标资源不一致时,浏览器会阻止页面通过脚本(如JavaScript)访问跨域资源,除非目标服务器明确允许。
一、为什么需要跨域限制?
1. 保护用户数据安全
- 防止恶意网站通过脚本窃取其他网站的敏感信息(如Cookie、用户隐私)。
- 例如:攻击者网站无法直接通过AJAX读取银行网站的登录状态。
2. 防御攻击
- 避免跨站请求伪造(CSRF)和跨站脚本攻击(XSS)等安全风险。
利用跨域限制及相关安全措施辅助防御XSS的方法:
- 限制源、限制HTTP方法和请求头、禁止携带敏感凭证(Access-Control-Allow-Credentials)
二、什么是同源策略?
- 同源的定义:两个URL的 协议、域名、端口 完全一致。
- 例:example.com:443 和 example.com/api 同源。
- 不同源的示例:
- example.com vs example.com(协议不同)
- example.com vs api.example.com(域名不同)
- example.com:80 vs example.com:8080(端口不同)
- 受限制的操作:
- JavaScript无法读取跨域请求的响应(如AJAX、Fetch API)。
- 无法通过iframe嵌入跨域页面并操作其DOM。
- 无法读取跨域的Cookie、LocalStorage等。
三、解决跨域的常用方法
1. JSONP(JSON with Padding)
- 原理:利用
<script>标签不受同源策略限制的特性,通过动态创建脚本获取跨域数据。 - 局限性:仅支持GET请求,且需服务器返回特定格式(如callback(data))
function handleResponse(data) { console.log(data); } const script = document.createElement('script'); script.src = '<http://api.example.com/data?callback=handleResponse>'; document.body.appendChild(script); handleResponse({"name": "Alice", "age": 30});
2. CORS(跨域资源共享,Cross-Origin Resource Sharing)
- 原理:服务端通过HTTP响应头(如Access-Control-Allow-Origin)声明允许哪些域访问资源。
- 实现步骤:
-
- 简单请求(GET/POST/HEAD且无自定义头):浏览器直接发送请求,服务器返回Access-Control-Allow-Origin: *(允许所有域)或指定域名。
-
- 预检请求(复杂请求如PUT/DELETE或带自定义头):浏览器先发送OPTIONS请求,服务器返回允许的方法和头。
Access-Control-Allow-Origin: <https://example.com> # 允许指定域 Access-Control-Allow-Methods: GET, POST, PUT # 允许的方法 Access-Control-Allow-Headers: Content-Type # 允许的请求头 Access-Control-Allow-Credentials: true # 允许携带Cookie -
3. 代理服务器
原理:前端请求同域代理服务器,由代理服务器转发请求到目标服务器,绕过浏览器限制.
1. //Nginx反向代理
location /api {
proxy\_pass <http://api.example.com>;
add\_header Access-Control-Allow-Origin \*;
}
2. devserver等
4. WebSocket
**原理**:WebSocket协议本身支持跨域通信(需服务器支持)
```
const socket = new WebSocket('ws\://api.example.com');
socket.onmessage = (event) => {
console.log(event.data);
};
```
5. 修改浏览器安全策略(仅开发环境)
Chrome启动参数:--disable-web-security --user-data-dir=/tmp
6. 跨域的安全注意事项
1. 敏感操作需验证来源
- 使用Origin请求头校验请求来源。
2. 处理凭证(Cookie)
- 若需跨域携带Cookie,需设置:
- 前端:fetch(url, { credentials: 'include' })
- 服务端:Access-Control-Allow-Credentials: true + 明确指定Access-Control-Allow-Origin(不能为*)