1、通过签名防止cookie篡改
import tornado.httpserver import tornado.ioloop import tornado.web import tornado.options from tornado.options import define, options define("port", default=8000, help="run on the given port", type=int) class MainHandler(tornado.web.RequestHandler): def get(self): cookie = self.get_secure_cookie("count") count = int(cookie) + 1 if cookie else 1 countString = "1 time" if count == 1 else "%d times" % count self.set_secure_cookie("count", str(count)) self.write( ‘<html><head><title>Cookie Counter</title></head>‘ ‘<body><h1>You’ve viewed this page %s times.</h1>‘ % countString + ‘</body></html>‘ ) if __name__ == "__main__": tornado.options.parse_command_line() settings = { "cookie_secret": "bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E=" } application = tornado.web.Application([ (r‘/‘, MainHandler) ], **settings) http_server = tornado.httpserver.HTTPServer(application) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start()
Tornado的set_secure_cookie()和get_secure_cookie()函数发送和取得浏览器的cookies,以防范浏览器中的恶意修改。为了使用这些函数,你必须在应用的构造函数中指定cookie_secret参数。
Tornado将cookie值编码为Base-64字符串,并添加了一个时间戳和一个cookie内容的HMAC签名。如果cookie的时间戳太旧(或来自未来),或签名和期望值不匹配,get_secure_cookie()函数会认为cookie已经被篡改,并返回None,就好像cookie从没设置过一样。cookie值是签名的而不是加密的。
2、使用HTTP-Only和SSL Cookies属性保证cookie安全
HTTP-Only属性:禁止JavaScript访问cookie
SSL Cookies属性:指示浏览器只通过SSL连接传递cookie
用法:
self.set_cookie(‘foo‘, ‘bar‘, httponly=True,
secure=True)
self.set_secure_cookie(‘foo‘,
‘bar‘, httponly=True, secure=True)
3、防止cookie的跨站访问攻击
通过在应用的构造函数中包含xsrf_cookies参数来开启XSRF保护:
settings = { "cookie_secret": "bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E=", "xsrf_cookies": True } application = tornado.web.Application([ (r‘/‘, MainHandler), (r‘/purchase‘, PurchaseHandler), ], **settings)
当这个应用标识被设置时,Tornado将拒绝请求参数中不包含正确的_xsrf值的POST、PUT和DELETE请求。Tornado将会在幕后处理_xsrf cookies,但你必须在你的HTML表单中包含XSRF令牌以确保授权合法请求。要做到这一点,只需要在你的模板中包含一个xsrf_form_html调用即可:
<form action="/purchase" method="POST"> {% raw xsrf_form_html() %} <input type="text" name="title" /> <input type="text" name="quantity" /> <input type="submit" value="Check Out" /> </form>
AJAX请求也需要一个_xsrf参数
jQuery.postJSON = function(url, data, callback) { data._xsrf = getCookie("_xsrf"); jQuery.ajax({ url: url, data: jQuery.param(data), dataType: "json", type: "POST", success: callback }); }