Tornado的XSRF防范
XSRF
XSRF即为跨站请求伪造
这个漏洞利用了浏览器的一个允许恶意攻击者在受害者网站注入脚本使未授权请求代表一个已登录用户的安全漏洞。
了解XSRF
当一个网站的图片SRC属性为另一个网站的链接时,浏览器加载这个网站的这张图片时就会访问另一个网站。
防范请求伪造
重要的请求尽可能使用post方法,但这并不是万能的,因为post方法也会被伪造(如HTML表单或XMLHTTPRequest API来向你的应用发送POST请求)。
为了防范伪造POST请求,我们会要求每个请求包括一个参数值作为令牌(token)来匹配存储在cookie中的对应值。我们的应用将通过一个cookie头和一个隐藏的HTML表单元素向页面提供令牌。当一个合法页面的表单被提交时,它将包括表单值和已存储的cookie。如果两者匹配,我们的应用认定请求有效。
由于第三方站点没有访问cookie数据的权限,他们将不能在请求中包含令牌cookie。这有效地防止了不可信网站发送未授权的请求。
使用Tornado的XSRF保护
在setting中做如下设置
settings = {
"cookie_secret": "bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E=",
"xsrf_cookies": True
}
当这个应用标识被设置时,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>
实现原理
- 为浏览器设置了一个名为_xsrf的安全cookie,这个cookie在关闭浏览器后会失效
- 为模板表单添加了一个隐藏域,名为_xsrf,值为_xsrf这个cookie的值
手动设置_xsrf的cookie
class SetXSRFCookieHandler(RequestHandler):
def get(self, *args, **kwargs):
# 设置_xsrf的cookie
self.xsrf_token
self.finish("ok")
为了让用户一访问就加载上,通常将其放在请求主页的Handler中,而一般将静态页面作为主页,所以在StaticHandler中添加即可
# 定义自己的StaticFileHandler
class StaticFileHandler(StaticFileHandler):
def __init__(self, *args, **kwargs):
super(StaticFileHandler, self).__init__(*args, **kwargs)
self.xsrf_token
XSRF令牌和AJAX请求
AJAX请求也需要一个_xsrf参数,但不是必须显式地在渲染页面时包含一个_xsrf值,而是通过脚本在客户端查询浏览器获得cookie值。下面的两个函数透明地添加令牌值给AJAX POST请求。第一个函数通过名字获取cookie,而第二个函数是一个添加_xsrf参数到传递给postJSON函数数据对象的便捷函数。
function getCookie(name) {
var c = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return c ? c[1] : undefined;
}
jQuery.postJSON = function(url, data, callback) {
data._xsrf = getCookie("_xsrf");
jQuery.ajax({
url: url,
data: jQuery.param(data),
dataType: "json",
type: "POST",
success: callback
});
}
原文地址:https://www.cnblogs.com/kainhuck/p/11688745.html
- 温故而知新:HttpApplication,HttpModule,HttpContext及Asp.Net页生命周期
- proxy_pass反向代理配置中url后面加不加/的说明
- Android新手之旅(10) 嵌套布局
- C#代码也VB
- Docker容器学习梳理--SSH方式登陆容器
- Docker网络解决方案-Flannel部署记录
- Nginx的location配置规则梳理
- 统计代码行数的方法梳理
- 如何在不影响asp.net默认安全性的前提下使用ckeditor/fckeditor?
- Linux下防御DDOS攻击的操作梳理
- Android新手之旅(8) ListView的使用
- 更换Ubuntu源为国内源的操作记录
- Android新手之旅(8) ListView的使用
- CKEditor/CKFinder升级心得
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Django1.11 简单登录注册
- 基因表达聚类分析之初探SOM - 自组织特征图
- JMH - Java 代码性能测试的终极利器、必须掌握
- 从零搭建Spring Boot脚手架(6):整合Redis作为缓存
- 换一种姿势挖掘CORS漏洞
- 新的Spring OAuth2.0 授权服务器项目正式发布
- spring boot整合apollo
- 枚举和List的几个共有方法
- AtomicInteger源码解析
- AtomicIntegerArray源码解析
- AtomicIntegerFieldUpdater源码解析
- “终于懂了” 系列:Android屏幕刷新机制—VSync、Choreographer 全面理解!
- 一些PHP选项参数相关的函数
- 【Flutter 专题】98 易忽略的【小而巧】的技术点汇总 (六)
- PHP脚本设置及获取进程名