Flask:CSRF 验证失败
Posted
技术标签:
【中文标题】Flask:CSRF 验证失败【英文标题】:Flask : CSRF verification failed 【发布时间】:2015-09-11 00:22:33 【问题描述】:我正在从 ios 客户端发送 POST 请求
-(void)loadFavorite:(NSArray*)favorites
//data and url preparation
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"https://example.com" forHTTPHeaderField: @"Referer"];
[request setValue:[NSString stringWithFormat:@"%tu", [requestData length]] forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody: requestData];
if ([Tools isNetWorkConnectionAvailable])
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
//response handle
这是回复:
<div id="summary">
<h1>Forbidden <span>(403)</span></h1>
<p>CSRF verification failed. Request aborted.</p>
</div>
我正在使用 Flask 框架和 pythonanywhere 进行托管。
当我重新加载 python 脚本时它工作正常,但几个小时/几天后,CSRF 验证失败错误再次出现。
即使我尝试在我的 app.py 中禁用 CSRF 验证:
app.config['WTF_CSRF_CHECK_DEFAULT'] = False
App.py 脚本:
//some import error handlers ...
app = Flask(__name__)
app.config['WTF_CSRF_CHECK_DEFAULT'] = False
@app.route('/api/favorites', methods=['POST'])
def get_favorites_beaches():
if not request.json or not 'favorite' in request.json:
abort(400)
//data process
if __name__ == '__main__':
app.run(host='0.0.0.0',debug=True)
如何正确实现 CSRF 验证或如何禁用它?
【问题讨论】:
Flask 没有内置 CSRF 保护。你是用 Flask-WTF 还是类似的扩展来添加它? 不,我不想使用它,我不明白为什么会收到此错误。我不使用flask_wtf.csrf、CsrfProtect,也不在app.py中使用CsrfProtect(app)。 如果可能我想禁用它,但我不知道为什么 app.config['WTF_CSRF_CHECK_DEFAULT'] = False 在 app.py 中不起作用。 如果您不使用 WTF,那么 'WTF_CSRF_CHECK_DEFAULT' 将不起作用。 好的,我应该导入 Flask-WTF 或类似的扩展来使 WTF_CSRF_CHECK_DEFAULT 工作吗? 【参考方案1】:你的代码中有一行是[request setValue:@"https://example.com" forHTTPHeaderField: @"Referer"];
您没有将其设置为正确的网址吗?错误的引用者是您获得跨站点错误的一种方式。
康拉德
【讨论】:
是的,这是正确的 url,因为当我重新加载网络应用程序时它可以工作几个小时或一天,然后 CSRF 验证错误又回来了。 它回来后会一直停留到你重新加载webapp吗?还是打了几次后它会消失【参考方案2】:PythonAnywhere 开发人员在这里转发我们刚刚在论坛上发布的内容。这在我们的托管平台上被证明是一个相当模糊的问题,我们刚刚发布了一个修复它的系统补丁。
它是这样的:如果 Web 应用程序由于某种原因(系统重启、某些类型的故障、过多的资源使用、可能是休眠)而关闭,那么只有一个 GET 请求才能将其唤醒。特别是 POST 请求将被拒绝并出现 CSRF 错误(由我们的代码生成,旨在启动 Web 应用程序),并且不会唤醒应用程序。因此,如果您的应用程序主要处理 POST 请求,您会看到这个问题。这似乎完全符合您描述的问题。
我们的新代码会在收到 POST 时唤醒应用。一个小问题仍然存在——第一个唤醒它的 POST 请求将收到一个“503 Service Unavailable”响应,其中“retry-after”标头设置为“5”。如果您处理此问题并重试,则下一个请求将起作用。我们相信浏览器会自动执行此操作,但不幸的是,请求库默认情况下不会这样做。
【讨论】:
以上是关于Flask:CSRF 验证失败的主要内容,如果未能解决你的问题,请参考以下文章