CORS相关安全漏洞分析
- CORS配置错误(CORS misconfiguration):
- 描述:错误地配置CORS允许的源(
Access - Control - Allow - Origin
),例如设置为*
,这会允许来自任何源的请求访问资源。这在一些场景下存在风险,因为恶意网站可能发起跨域请求并获取敏感数据。另一种情况是配置了不应该允许的特定源,导致敏感资源暴露给非预期的第三方。
- 跨站请求伪造(CSRF)与CORS结合:
- 描述:即使有CORS机制,如果存在CSRF漏洞,攻击者可以利用用户已登录的状态,通过构造恶意的HTML页面,在用户不知情的情况下发起跨域请求到目标服务器。因为浏览器会自动带上用户的认证信息(如Cookie),如果CORS配置不当,攻击者可能成功获取数据或执行操作。
服务器端防范措施
- 精确配置允许的源:
- 示例(Node.js with Express):
const express = require('express');
const app = express();
// 仅允许特定源访问
const allowedOrigins = ['http://example.com', 'https://example.com'];
app.use((req, res, next) => {
const origin = req.headers.origin;
if (allowedOrigins.includes(origin) ||!origin) {
res.setHeader('Access - Control - Allow - Origin', origin);
} else {
return res.status(403).send('Forbidden');
}
res.setHeader('Access - Control - Allow - Methods', 'GET, POST, PUT, DELETE');
res.setHeader('Access - Control - Allow - Headers', 'Content - Type, Authorization');
next();
});
// 其他路由和处理逻辑
app.listen(3000, () => {
console.log('Server running on port 3000');
});
- 验证请求来源:除了设置
Access - Control - Allow - Origin
,服务器可以在业务逻辑中进一步验证请求来源,比如结合Referer头(虽然Referer头可以伪造,但能起到一定辅助作用)。
- 示例(Node.js with Express):
app.get('/sensitive - data', (req, res) => {
const referer = req.headers.referer;
if (!referer ||!allowedOrigins.some(origin => referer.startsWith(origin))) {
return res.status(403).send('Forbidden');
}
// 返回敏感数据逻辑
res.send('Sensitive data');
});
- 使用安全的认证机制:采用JSON Web Tokens(JWT)等无状态认证机制,而不是仅依赖Cookie。这样即使请求来自跨域,只要JWT验证通过且CORS配置正确,就可以安全地处理请求。
前端JavaScript防范措施
- 验证响应头:在前端收到响应时,验证
Access - Control - Allow - Origin
头是否符合预期。
fetch('https://api.example.com/data', {
method: 'GET',
credentials: 'include'
})
.then(response => {
const allowedOrigin = 'https://your - app.com';
if (response.headers.get('Access - Control - Allow - Origin')!== allowedOrigin) {
throw new Error('Unexpected CORS origin');
}
return response.json();
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error('Error:', error);
});
- 防止CSRF攻击:在前端发送请求时,添加CSRF令牌(如在表单或请求头中)。服务器验证令牌的有效性,确保请求是合法的。
- 示例(使用Axios发送带有CSRF令牌的请求):
import axios from 'axios';
// 假设从Cookie中获取CSRF令牌
const csrfToken = document.cookie.split('csrf_token=')[1].split(';')[0];
axios.defaults.headers.common['X - CSRF - Token'] = csrfToken;
axios.get('https://api.example.com/data')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error('Error:', error);
});