专栏首页JackeyGao的博客使用CSP代替X-frame-options

使用CSP代替X-frame-options

使用CSP代替X-frame-options

Posted December 18, 2018

#Content Security Policy

内容安全策略(Content-Security-Policy)是W3C的一项重要标准,旨在防止广泛的内容注入攻击,如跨站点脚本(XSS)等。 CSP 有着灵活的白名单控制.

CSP 目前支持的浏览器有

  • Chrome 25+
  • Edge 14+
  • Firefox 23+
  • IE 10+
  • Opera 15+

不支持 CSP 的浏览器只会忽略它,如常运行,默认为网页内容使用标准的同源策略。如果网站不提供 CSP 头部,浏览器也使用标准的同源策略(Same origin policy)a 比如: x-frame-options 控制嵌入白名单源, 大多数都是 sameorigin , 表示仅当前主机域名可以嵌入(显然这没必要, 一般嵌入都是外面嵌入)。

CSP 通过指令进行各个安全项控制, 不只是可以对嵌入做控制. 可以参考下面两个文档阅读更多

背景

我最近做的项目是把所有的运维项目合并到一个项目里面, 当然最简单的方式是嵌入, 但在嵌入项目的时候发现了Chrome 控制台这样的错误.

Raw

(index):1 Refused to display 'http://xxx.com/' in a frame because it set 'X-Frame-Options' to 'sameorigin'.

显然这是因为sameorigin导致的.

X-FRAME-Options 写法

如果我要允许被嵌入, 就要更新 X-Frame-Options 的值. 我们先看看此 Header 支持的写法.

  • sameorigin

表示该页面可以在相同域名页面的 frame 中展示。

  • deny

表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。

  • ALLOW-FROM uri

表示该页面可以在指定来源的 frame 中展示。

Django 默认是 SameOrigin. 如果其他项目需要嵌入页面, 必须在被嵌入的项目为每个 endpoint 增加 @xframe_options_exempt 装饰器. 此装饰器是移除X-Frame-Options Response header, 表示此 View 可以嵌入任何页面, 这不符合 OWASP Clickjacking 的建议. 所以我们可以通过ALLOW-FROM uri来指定单个项目来嵌入, 这也是我选择的方案. 或者我可以直接指定 ALLOW_From uri 白名单的形式.

现实的问题.

但 Django 没有任何控制项, 可以完成ALLOW-FROM uri的控制, 虽然可以通过自定义中间件的形式, 或者通过django-xframeoptions第三方项目来设置, 但是我需要嵌入的项目太多, 而且我也不想一个一个的去更新, 这是我想要了在 nginx 上面设置这个header.

于是我在 nginx 配置里面加入.

nginx

add_header X-Frame-Options ALLOW-FROM <my uri>;

但事实是增加这个 header 就出现了两个 X-Frame-Options header.

Raw

X-Frame-Options: sameorigin;
X-Frame-Options: ALLOW-FROM ;

浏览器对于多个值, 是直接不处理, 并直接拒绝通过此次同源策略的检查.

Raw

(index):1 Refused to display 'http://xxx.com' in a frame because it set multiple 'X-Frame-Options' headers with conflicting values ('SAMEORIGIN, ALLOW-FROM '). Falling back to 'deny'.

所以 add_header X-Frame-Options 并不是覆盖, 而且追加到两个 header, 显然这样不行。当然 nginx 上也有其他方式, 去除 SameOrigin 这个值,或者直接更新这个 header. 但我准备采取 CSP, 并移除 X-Frame-Options。

使用 CSP.

前面提到可以使用 @xframe_options_exempt 装饰器, 移除X-Frame-Options。 但是我要移除所有的视图, 就特别麻烦了。 但可以通过移除django.middleware.clickjacking.XFrameOptionsMiddleware中间件来移除当前项目所有视图的x-Frame-Options。

为什么移除X-Frame-Options? 经过 Chrome71 测试, 当 X-Frame-Options 和 Content-Security-Policy 同时设置, 前者依然作用。

settings.py

python

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    # remove this middleware 'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

然后在 nginx 增加, CSP 相关的 Header. 依然是 add_header .

nginx

add_header Content-Security-Policy frame-ancestors <my uri>;

以上, 目前 CSP 正在逐渐取代 X-Frame-Options 。 而 X-Frame-Options 将被弃用. 相信在以后的迭代里, Django 将会默认支持 CSP 的控制. 但在目前(2018-12-18)的时间里, 上面的方法可能对你有帮助.

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 我做的一些项目

    用户1416054
  • Django小技巧10: 自定义认证策略

    Django 内置了一套功能极全的认证系统,而且可以很容易的进行自定义, 本章的内容就是自定义认证策略。

    用户1416054
  • Python 高级并发3

    本篇主要讲案例, 两个使用Concurrent.futures实现的并发, 一个是多线程, 一个是多进程。

    用户1416054
  • 劳斯莱斯宣布与英特尔合作,为自动货船开发全球系统

    劳斯莱斯今天宣布,它将使用英特尔芯片,为在公海上运载货物的自动船舶开发一个全球系统。劳斯莱斯以英国为基础,并且正在芬兰和挪威的研发中心开发运输技术。

    AiTechYun
  • [收藏]几个常用的用正则表达式验证字符串的函数

    <!-- name,phone,age,money checked--> <script language=javascript runat=server> ...

    脑洞的蜂蜜
  • 【leetcode系列】122. 买卖股票的最佳时机 II

    lucifer210
  • 省油一号分销系统模式开发源码

    在平时开发程序的过程中,自己经常会写一些控制台进行测试某个功能,事后我们会寻找这些程序,如果不仔细管理,经常会找不到。由于每个控制台程序都有自己独立的 Main...

    用户3448773
  • 记一次网易前端实习面试

    很幸运地能收到网易的面试通知,就毫不犹豫翘了课去面试了hhhh~三点的面试,因为从来没去过那个中关村西北旺区,吃完饭早早就去了,想象中那里应该是繁华的地方hhh...

    疯狂的技术宅
  • Java里面关于数组拷贝的几种方式

    我是攻城师
  • Personalized Search论文阅读笔记-08年SIGIR

    对于这样允许大众分类的应用,如何满足用户在搜索时尽可能准确地返回用户所需要的资源是一个有意思的问题。因为如果像传统的搜索方法仅通过查询关键词去匹配搜索结果,返回...

    DuncanZhou

扫码关注云+社区

领取腾讯云代金券