未经验证的URL重定向¶
Web表单在成功提交数据后重定向到不同页面是很常见的。这通常通过HTTP请求中的next或return参数完成。任何HTTP参数都可由用户控制,并可能被攻击者滥用以将用户重定向到恶意网站。
这通常用于网络钓鱼攻击,例如攻击者可以将用户从合法的登录表单重定向到虚假的、由攻击者控制的登录表单。如果页面看起来足够像目标网站,并诱骗用户相信他们输错了密码,攻击者就可以说服用户重新输入他们的凭据并将其发送给攻击者。
这是一个恶意重定向URL的示例
https://good.com/login.php?next=http://bad.com/phonylogin.php
为了对抗这种类型的攻击,所有URL在用于重定向用户之前都必须经过验证。这应确保重定向会将用户带到您网站内的页面。
错误¶
此示例仅处理“next”参数,没有进行任何验证
import os
from flask import Flask,redirect, request
app = Flask(__name__)
@app.route('/')
def example_redirect():
return redirect(request.args.get('next'))
正确¶
以下是使用Flask web框架的示例。它检查用户将被重定向到的URL是否源自与提供内容的服务器相同的主机。
from flask import request, g, redirect
from urlparse import urlparse, urljoin
def is_safe_redirect_url(target):
host_url = urlparse(request.host_url)
redirect_url = urlparse(urljoin(request.host_url, target))
return redirect_url.scheme in ('http', 'https') and \
host_url.netloc == redirect_url.netloc
def get_safe_redirect():
url = request.args.get('next')
if url and is_safe_redirect_url(url):
return url
url = request.referrer
if url and is_safe_redirect_url(url):
return url
return '/'
Django框架包含一个django.utils.http.is_safe_url函数,可用于验证重定向,而无需实现自定义版本。
后果¶
未经验证的重定向可能使您的网站成为网络钓鱼攻击的目标,从而导致用户凭据被盗。