在bottle框架中使用bottle-utils预防csrf跨站攻击

苗康平
2023-12-01

bottle.py也是一个轻量级的python框架,略近似于flask。相对来说,bottle的资料不太好找,今天在网上扒拉了一阵,终于大致弄清楚了基本用法,现将具体设置作个粗略的笔记,希望对和我一样抓狂了一小会儿的人有所帮助。

我使用的是bottle-utils,里面包含了csrf模块。你需要下载安装bottle-utils,见https://pypi.python.org/pypi/bottle-utils/0.3.2,使用pip或easy_install的安装命令如下:

pip install bottle-utils
easy_install bottle-utils

首先,我们假设你做的是一个简单的blog,app名为blog.py,包含一个简单的登录功能。代码清单如下,csrf相关部分用橙黄色标出:


import pymongo  #或者任何你使用的数据库
import bottle
from bottle_utils import csrf

app=bottle.default_app()
# 此处需要使用你自己的一个相当难猜测出的随机值替代secret_key
# bottle-utils文档相关的部分是这样说的:secret setting is a secret key used for setting cookies; it should be fairly random and difficult to guess
app.config['csrf.secret'] = secret_key

#login 显示页面部分
@bottle.get('/login')
@csrf.csrf_token
def present_login():
    return bottle.template("login", dict(username="", password="", login_error="",token=bottle.request.csrf_token)

#处理login请求
@bottle.post('/login')
@csrf.csrf_protect
def process_login():
    bottle.request.app = app
    u=bottle.request.forms.get("username")
    p=bottle.request.forms.get("password")

    # 此处应使用你自己的验证模块来代替myusers.validate(u,p)
    user_record = myusers.validate(u,p)
    if user_record:
        # TODO: 登录成功处理,如设置session,重定向等
    else:
        # TODO: 登录失败处理


在login.tpl模板中,相关部分如下:

%if (username==None or username==""):
<form method="post">
<input type="hidden" name="_csrf_token" value="{{ token }}">
用户名:<input type="text" name="username" value="{{username}}" /><br />
密码:<input type="password" name="password" value="" /><br />
{{login_error}}<br>
<input type="submit">
</form>
%end

关于csrf,stackoverflow上还有人提出了一个方法,见: http://stackoverflow.com/questions/16025932/methods-to-protect-a-bottle-py-webapplication-against-xss-and-csrf,但是我没搞清楚具体的设置,而且也需要安装一个叫 functools的包。此处在bottle中使用的方法与django大同小异,当然还有其它一些不同的方法,但本文不打算深入讨论跨站攻击,这里不再赘述。另外本人水平有限,如有错漏之处欢迎指出。


参考链接:http://outernet-project.github.io/bottle-utils/csrf.html

http://bottlepy.org/docs/0.12/configuration.html


 类似资料: