请选择 进入手机版 | 继续访问电脑版

笨鸟编程-零基础入门Pyhton教程

 找回密码
 立即注册

安全注意事项

发布者: 笨鸟自学网



跨站请求伪造(CSRF)

另一个大问题是 CSRF 。这是一个非常复杂的话题,我不会在此详细介绍,而只会 提及 CSRF 是什么和理论上如何避免它。

如果你的验证信息存储在 cookie 中,你有隐式的状态管理。“已登入”状态由一个 cookie 控制,并且这个 cookie 在每个页面的请求中都会发送。不幸的是,在第三 方站点触发的请求中也会发送这个 cookie 。如果你不注意这点,一些人可能会通过 社会工程学来诱导你应用的用户在他们不知道的情况下做一些蠢事。

比如你有一个指定的 URL ,当你发送 POST 请求时会删除一个用户的资料(比如 http://example.com/user/delete 。如果一个攻击者现在创造一个页面来用 JavaScript 发送这个 post 请求,他们只是诱骗一些用户加载那个页面,而他们 的资料最终会被删除。

想象你在运行 Facebook ,有数以百万计的并发用户,并且某人放出一些小猫图片 的链接。当用户访问那个页面欣赏毛茸茸的猫的图片时,他们的资料就被删除。

你怎样才能阻止这呢?基本上,对于每个修改服务器上内容的请求,你应该使用 一次性令牌,并存储在 cookie 里, 并且 在发送表单数据的同时附上它。 在服务器再次接收数据之后,你要比较两个令牌,并确保它们相等。

为什么 Flask 没有为你这么做?理想情况下,这应该是表单验证框架做的事,而 Flask 中并不存在表单验证。

JSON 安全

ECMAScript 5 的变更

从 ECMAScript 5 开始,常量的行为变化了。现在它们不由 Array 或其它 的构造函数构造,而是由 Array 的内建构造函数构造,关闭了这个特殊的 攻击媒介。

JSON 本身是一种高级序列化格式,所以它几乎没有什么可以导致安全问题,对吗? 你不能声明导致问题的递归结构,唯一可能导致破坏的就是在接受者角度上,非常 大的响应可以导致某种意义上的拒绝服务攻击。

然而有一个陷阱。由于浏览器在 CSRF 问题上工作的方式, JSON 也不能幸免。幸运 的是, JavaScript 规范中有一个怪异的部分可以用于简易地解决这一问题。 Flask 通过避免你做危险的事情上为你解决了一些。不幸的是,只有在 jsonify() 中有这样的保护,所以如果你用其它方法生成 JSON 仍然 有风险。

那么,问题是什么,并且怎样避免?问题是 JSON 中数组是一等公民。想象你在 一个 JSON 请求中发送下面的数据。比如 JavaScript 实现的用户界面的一部分, 导出你所有朋友的名字和邮件地址。并不罕见:

[
    {"username": "admin",
     "email": "admin@localhost"}
]

这当然只在你登入的时候,且只为你这么做。而且,它对一个特定 URL 上的所有 GET 请求都这么做。比如请求的 URL 是 http://example.com/api/get_friends.json

那么如果一个聪明的黑客把这个嵌入到他自己的网站上,并用社会工程学使得受害 者访问他的网站,会发生什么:

<script type=text/javascript>
var captured = [];
var oldArray = Array;
function Array() {
  var obj = this, id = 0, capture = function(value) {
    obj.__defineSetter__(id++, capture);
    if (value)
      captured.push(value);
  };
  capture();
}
</script>
<script type=text/javascript
  src=http://example.com/api/get_friends.json></script>
<script type=text/javascript>
Array = oldArray;
// now we have all the data in the captured array.
</script>

如果你懂得一些 JavaScript 的内部工作机制,你会知道给构造函数打补丁和为 setter 注册回调是可能的。一个攻击者可以利用这点(像上面一样上)来获取 所有你导出的 JSON 文件中的数据。如果在 script 标签中定义了内容类型是 text/javascript ,浏览器会完全忽略 application/json 的 mimetype ,而把其作为 JavaScript 来求值。因为顶层数组元素是允许的(虽然 没用)且我们在自己的构造函数中挂钩,在这个页面载入后, JSON 响应中的数据 会出现在 captured 数组中。

因为在 JavaScript 中对象字面量( {...} )处于顶层是一个语法错误,攻 击者可能不只是用 script 标签加载数据并请求一个外部的 URL 。所以, Flask 所做的只是在使用 jsonify() 时允许对象作为顶层元素。确保使用 普通的 JSON 生成函数时也这么做。

12

Archiver|手机版|笨鸟自学网 ( 粤ICP备20019910号 )

GMT+8, 2024-12-5 23:20 , Processed in 0.370794 second(s), 17 queries .

© 2001-2020

返回顶部