请结合代码,讲一下csrf漏洞的产生
时间: 2024-04-05 14:33:23 浏览: 18
CSRF(Cross-Site Request Forgery)跨站请求伪造是一种常见的Web安全漏洞,攻击者可以盗用用户的身份,以用户的名义发送恶意请求。造成的危害包括但不限于:修改用户信息、发邮件、发微博、加好友、发私信、甚至财产操作等。
CSRF攻击的原理是攻击者构造出一个后端请求地址,诱导用户点击或者通过其他方式自动发起请求。如果被攻击用户在网站中已经登录过,那么该请求会默认携带用户的登录凭证,后端服务器就会根据请求的内容进行相应的操作,如修改用户信息等。
下面是一个简单的示例,演示了在不使用CSRF防御措施的情况下,如何利用CSRF漏洞进行攻击:
后端代码:
```python
@app.route('/change_password', methods=['POST'])
def change_password():
username = request.form.get('username')
new_password = request.form.get('new_password')
# 设置新密码
# ...
return 'Password changed successfully!'
```
前端代码:
```html
<html>
<head>
<title>Change Password</title>
</head>
<body>
<form action="http://www.example.com/change_password" method="POST">
<input type="hidden" name="username" value="admin">
<input type="hidden" name="new_password" value="hacked">
<input type="submit" value="Change Password">
</form>
</body>
</html>
```
攻击者可以在自己的网站中构造一个类似于上面的表单,然后诱导用户点击提交按钮。当用户点击提交按钮后,浏览器会自动向`http://www.example.com/change_password`地址发送POST请求,其中会包含攻击者构造的username和new_password参数。由于用户已经登录过`www.example.com`网站,所以请求会默认携带用户的登录凭证,后端服务器会根据请求的内容进行相应的操作,如修改用户密码等。
在实际应用中,为了防止CSRF攻击,我们可以在后端代码中添加CSRF令牌验证:
```python
from flask_wtf.csrf import CSRFProtect
app = Flask(__name__)
csrf = CSRFProtect(app)
@app.route('/change_password', methods=['POST'])
@csrf.protect()
def change_password():
username = request.form.get('username')
new_password = request.form.get('new_password')
# 设置新密码
# ...
return 'Password changed successfully!'
```
在前端代码中,我们可以使用`csrf_token`字段来传递CSRF令牌:
```html
<html>
<head>
<title>Change Password</title>
</head>
<body>
<form action="http://www.example.com/change_password" method="POST">
<input type="hidden" name="username" value="admin">
<input type="hidden" name="new_password" value="hacked">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<input type="submit" value="Change Password">
</form>
</body>
</html>
```
在后端代码中,`@csrf.protect()`装饰器会自动验证CSRF令牌的有效性,如果验证失败,则会返回`400 Bad Request`错误。在前端代码中,我们使用`{{ csrf_token() }}`来生成CSRF令牌,并将其作为隐藏字段传递给后端。这样,即使攻击者构造了类似的表单,由于没有正确的CSRF令牌,后端服务器也会拒绝处理该请求。