Web安全:CSRF跨站请求伪造详解
Web安全:CSRF跨站请求伪造详解
1. CSRF概述
CSRF(Cross-Site Request Forgery)是一种利用用户已登录的身份,在用户不知情的情况下发起恶意请求的攻击。
2. CSRF攻击原理
1. 用户登录网站A,获取有效Session 2. 攻击者诱导用户访问恶意网站B 3. 网站B中包含向网站A发送请求的代码 4. 浏览器自动携带Cookie发送请求 5. 网站A执行恶意操作3. CSRF防护措施
3.1 CSRF Token
import "github.com/gin-contrib/sessions" func CSRFMiddleware() gin.HandlerFunc { return func(c *gin.Context) { session := sessions.Default(c) token := session.Get("csrf_token") if c.Request.Method == "POST" { requestToken := c.PostForm("csrf_token") if requestToken == "" { c.AbortWithStatus(403) return } if requestToken != token { c.AbortWithStatus(403) return } } // 生成新Token newToken := generateToken() session.Set("csrf_token", newToken) c.Set("csrf_token", newToken) c.Next() } } // 在表单中嵌入Token func renderForm(c *gin.Context) { token := c.MustGet("csrf_token").(string) c.HTML(200, "form.html", gin.H{ "csrf_token": token, }) }3.2 SameSite Cookie
import "github.com/gin-gonic/gin/sessions" session.Options(sessions.Options{ Path: "/", MaxAge: 86400 * 7, HttpOnly: true, Secure: true, SameSite: http.SameSiteStrictMode, // 防止CSRF })3.3 双重提交Cookie
// 前端设置Cookie document.cookie = 'csrf-token=' + token; // 发送请求时同时发送Cookie和Header fetch('/api/action', { method: 'POST', credentials: 'include', // 包含Cookie headers: { 'X-CSRF-Token': token, }, body: JSON.stringify(data) })4. 验证请求来源
4.1 Referer/Origin检查
func OriginCheckMiddleware() gin.HandlerFunc { return func(c *gin.Context) { if c.Request.Method == "POST" { referer := c.GetHeader("Referer") origin := c.GetHeader("Origin") allowedDomain := "https://example.com" if referer != "" && !strings.HasPrefix(referer, allowedDomain) { c.AbortWithStatus(403) return } } c.Next() } }5. 前端防护
5.1 React CSRF防护
class SafeForm extends React.Component { state = { csrfToken: '' }; componentDidMount() { this.setState({ csrfToken: window.csrfToken }); } handleSubmit = async (e) => { e.preventDefault(); const response = await fetch('/api/action', { method: 'POST', credentials: 'include', headers: { 'X-CSRF-Token': this.state.csrfToken, 'Content-Type': 'application/json', }, body: JSON.stringify(this.props.data) }); }; render() { return ( <form onSubmit={this.handleSubmit}> {/* 表单内容 */} </form> ); } }6. 总结
CSRF通过利用用户已登录的身份发起恶意请求,防护措施包括CSRF Token、SameSite Cookie、请求来源验证等。最佳实践是同时使用多种防护手段。
