说明:本文是Mozilla Web应用部署文档,对运维或者后端开发团队的部署行为进行指导。该部署安全规范内容充实,对于部署有很大意义。同时也涉及到了许多web前端应用安全的基本知识,如CSP, TOKEN, HTTPSCOOKIES等,对于前端来说了解安全规范相关知识是十分有必要的,尤其是COOKIE以及CSP
原文地址:https://infosec.mozilla.org/guidelines/web_security,以下是翻译内容:

web 安全速查表

本文档的目的在于帮助运维团队构建安全的web应用。所有Mozilla站点和部署应用都应当遵循以下建议,同时也我们也非常鼓励其他开发者遵循这些建议。本文档作为参考指南,由企业信息安全小组(Infosec)维护。

指导 安全收益 部署难度 优先级 需求† 备注
HTTPS 最高 强制 所有通信站点都应该使用https或者其他安全协议
Public Key Pinning 最高 -- 对于存在高风险的站点来说是强制的 不适用所有站点
Redirections from HTTP 最高 3 强制 web站点必须重定向到https,api接口则需要完全禁用http
Resource Loading 最高 2 强制 所有主动或者被动资源,都应该通过使用TLS的协议来加载,例如https
Strict Transport Security 4 强制 最小设置过期时间为六个月
TLS Configuration 1 强制 为你的站点使用最安全的TLS配置
Content Security Policy 10 新部署的站点:强制已经存在的站点:推荐 禁用行内脚本是CSP首先考虑。
Cookies 7 新部署的站点:强制已经存在的站点:推荐 所有的cookie必须带有secure标识,并且尽可能地限定其作用域
contribute.json 9 新部署的站点:强制已经存在的站点:推荐 Mozilla站点应当部署contribute.json文件,并且保持其持续更新
Cross-origin Resource Sharing 11 强制 除非有特殊要求,否则文件不应该允许被共享
Cross-site Request Forgery Tokenization 位置 6 看情况 对于允许毁坏性变化的站点来说是强制的。其他站点则是非必须的,大多数应用程序框架内嵌了CSRF tokenization基础之上,有易于部署
Referrer Policy 12 推荐 提高用户隐私安全,防止内部URL信息通过引用消息头被泄露
robots.txt 14 可选 方式部采用了robot.txt文件的web站点,都应当根据备注中的提示目的。
Subresource Integrity 15 推荐 值推荐给那些加载了外域资源的web站点
X-Content-Type-Options 8 推荐 站点提供的所有资源,都应该确保设置了适当的MIME 类型
X-Frame-Options 5 强制 未使用 DENY or SAMEORIGIN的web站点,必须使用点击劫持防御
X-XSS-Protection 13 新部署的站点:强制已经存在的站点:推荐 现存站点在部署之前,请确保都经过了手动的测试。

†符号表示管理员部署web安全指南的优先级。它从操作和部署的角度触发,综合考虑了安全性和易用性。

Transport Layer Security (TLS/SSL) (传输层安全TLS/SSL)

传输层安全(TLS)为所有的Mozilla的内外通信的机密性,认证性和完整性提供的了保障。为了保护用户和网络系统,我们强制要求所有系统支持和使用TSL加密通信系统。

HTTPS

1.web站点或者应用程序接口(api),与现代浏览器或者系统进行通讯,应当使Mozilla modern TLS configuration. 
2.面向公众使用的web站点应当使用Mozilla intermediate TLS configuration.
3.需要向后兼容很老的浏览器或者系统的站点,应当使用Mozilla backwards compatible TLS configuration. 这些配置并非建议,向后兼容性的标准应当在记录在你的风险评估当中。

Compatibility(兼容性)

机器配置 需要可兼容的最旧客户端
Firefox 27, Chrome 22, Internet Explorer 11, Opera 14, Safari 7, Android 4.4, Java 8
Firefox 1, Chrome 1, Internet Explorer 7, Opera 5, Safari 1, Internet Explorer 8 (XP), Android 2.3, Java 7
Internet Explorer 6 (XP), Java 6

See Also(其他文档)

  • Mozilla Server Side TLS Guidelines

  • Mozilla Server Side TLS Configuration Generator - generates software configurations for the three levels of compatibility

HTTP Strict Transport Security(HTTP 严格传输安全

HTTP Strict Transport Security(HSTS)是一项HTTP消息头,它告诉用户代理(浏览器),它只与基于https协议的给定站点(服务器)进行连接。如果一个站点被指定了HSTS,浏览器会公开将所有请求连接变为https。HSTS禁止用户绕过报错的站点,从而浏览器更加严格地处理TSL或者相关证书错误。

该消息头部由一个必选参数(max-age)和两个由分号分隔的可选参数(includeSubDomains 和 preload)构成。

指令(Directives)

  • max-age: 客户端在多久的时间内保持https定向跳转连接 单位秒

  • includeSubDomains: 当前域名下的子域中的请求是否也要升级为https

  • preload: 该站点是否包含HSTS预加载列表中( HSTS preload list)

max-age :最小值为六个月,一般推荐为两年。一旦被设定,站点必须持续支持HTTPS协议直到过期。
includeSubDomains :告知浏览器,当前域名下的子域名应当通过HSTS进行升级,例如:在domian.mozilla.com域名下设置了includeSubDomains,同样 host1.domain.mozilla.com 和 host2.domain.mozilla.com域名下也遵循https的策略. 设置includeSubDomains标识时应当考虑一些极端情况,因为有些还未部署https的子域站点将无法使用。

preload:如果之前有申请过加入你的域名到HSTS预加载列表,此项指令会告知浏览器你的网站已经被包含HSTS预加载列表中。即使未收到初始化HSTS的指示,浏览器对发送到站点的请求进行https升级。这可以防止基于初次访问的降级攻击,推荐所有高危站点使用。请注意,被包含在HSTS 需要同时设置includeSubDomains指令.

示例
该站点在两年内只能通过https访问 (推荐)

Strict-Transport-Security: max-age=63072000

两年内只允许通过https链接, 并且包含在预加载列表当中

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

See Also(其他文档)

  • MDN on HTTP Strict Transport Security

  • RFC6797: HTTP Strict Transport Security (HSTS)

HTTP Redirections(HTTP 重定向)

网站应该持续监听80(HTTP)端口,这样才不会使用户得到一个链接错误反馈。因为当用户在地址栏里面输入一个URL时,浏览器会通过http协议来建立初始化链接。监听80端口的站点只能重定向到https协议上的同资源上去。一旦连接建立,HSTS将保证所有试图通过http链接的请求都会被https所替代。API或者其他不面向公众开放的web站点,应当禁止使用http协议。

重定向应该在301定向下完成,重定向到不同的路径应该在302定向下完成。站点在一开始设置时就应当避免从http定向到不同的https站点去。
示例

重定向所有的http请求到https上去 nginx配置
server {
  listen 80;
  return 301 https://$host$request_uri;
}
重定向所有http://site.mozilla.orghttps://site.mozilla.org/, Apache配置
<VirtualHost *:80>
  ServerName site.mozilla.org
  Redirect permanent / https://site.mozilla.org/
</VirtualHost>

HTTP Public Key Pinning(HTTP 公钥固定)

存在高风险的站点必须使用HTTP Public Key Pinning (HPKP);它告诉Web客户端将特定加密公钥,与某个Web服务器相关联,以降低使用伪造证书进行MITM攻击的风险。拥有非官方发行的证书的域名,是无法被浏览器信任的。假冒的证书允许攻击者通过MITM(中间人攻击)和授权模拟的行为,拦截认证和其他敏感信息数据。

HPKP如若设置不当,会有中断用户上网行为的风险,因此必须采取防范措施以应对极端情况,例如:有备用的密钥值,非生产环境下的测试,Public-Key-Pins-Report-Only指令的测试,使用非常短的max-age指令值做初始化的测试。HPKP部署是一种“服务器自我否定”(self-denial-of-service)的行为,而伪造证书这种事情发生的概率很低,所以并不推荐所有的web站点都部署此项配置。

指令

  • max-age: 单位为妙,用户代理是否强制使用keypin通过安全的证书请求站点

  • includeSubDomains:  子域是否也使用该证书

与HSTS不一样,设置max-age指令因人而异。值越长当然越安全,但是如果一旦密钥失效了,那么你的网站将很长一段时间都无法访问。因此推荐设置的值为15~120天。
示例

# 固定电子证书, 将(公钥)public-key加密并且本地化, 包含子域, 有效期15天
Public-Key-Pins: max-age=1296000; includeSubDomains; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=";
pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; pin-sha256="P0NdsLTMT6LSwXLuSEHNlvg4WxtWb5rIJhfZMyeXUE0="

See Also(其他文档)

  • About Public Key Pinning

  • The HPKP Toolset - helpful tools for generating key pins

Resource Loading(资源加载)

所有的资源,不管同域或者跨域,都必须在安全通道内加载。安全站点(https)下加载不安全的(http)动态js文件,将会被浏览器阻止,导致用户感受到降级的体验,以及出现mixed- content警告。如果加载的是图片资源,虽然风险相对较低,但也有可能降级体验,也会让网络黑客破坏站点,或者对用户进行欺诈。
只要浏览器下载不安全资源的事实继续存在,上面提到的错误就会经常性出现。要避免这样的情况发生,开发者在部署自己的站点之前,就应该确保被加载资源的安全性。

示例

<!-- 使用HTTPS 加载 JavaScript资源是非常好的方法 -->
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<!-- 使用http协议加载js会被浏览器阻止,并且出现警告 -->
<script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>
<!-- 被动资源内容尽管不会被阻止,但仍然会出现mixed-content的警告 -->
<img src="http://very.badssl.com/image.jpg">

See Also(其他文档)

  • MDN on Mixed Content

Content Security Policy(内容安全策略)

内容安全策略(CSP)是一项HTTP消息头,它允许网站的运营人员很好的控制其站点下加载的资源出处。使用该http消息头能有效的防范跨站脚本攻击(xss)。由于对现有的网站进行CSP扩充比较困难,因此我们强制所有新的网站上必须部署该消息头,并且强烈推荐给所有存在高危风险的网站。

使用CSP的最先受益是可以禁用不安全的行内js脚本。如果不通过合适的转码,用户的输入就会被浏览器解释称为可执行的脚本—即行内脚本。通过使用CSP,你可以有效的避免大多数的XSS攻击。

需要注意,禁用所有行内脚本,意味着所有的脚本必须以script标签的形式下载。即便我们直接给元素绑定onclick事件这一的做法,也会失效。通过script但是没有src属性嵌入的脚本,也同样会失效的。此外,行内样式,通过<style>标签或者style属性引入到文档的,也同样会下载失败。有鉴于此,在设计网站的时我们要格外注意,才能顺利地部署CSP;

Implementation Notes (部署备注)

  • default-src指令的值应当首先设置为https,因为它不仅禁用了行内代码,也指定https请求。

  • 对于已经存在的包含大量基础代码的网站来说,如果禁用行内脚本,将花费大量时间去重新构建网站。但是仍然可以设置default-src:https: ’unsafe-line’。因为它可以保证资源不从http协议中下载, 但是它无法提供XSS防御。

  • 推荐一开始就加入限定策略,例如这样:default-src 'none'; img-src 'self'; script-src 'self'; style-src ‘self’,在开始测试的时候,我们逐步向站点加入资源。

  • 作为http消息头的替代,我们可以在界面head中设置 标签。如果这样做了,请确保该标签为head的首行。

  • 应该注意data协议的统一资源指示器(URI),设置了script-src 和object-src(或者继承自default-src)后,这些就不是安全的协议了。

  • 同样,使用script-src:‘self’对于JSONP端点也是不安全的。这些站点应该设置对应的CSP策略,包含对其他使用期资源文件的配置。

  • 除非你需要使用flash或者silverlight插件,否则你应该通过object-src: ’none'来禁用他们。

  • 站点应该理论上使用report-uri指令。通过post json报告你当前遭遇的CSP破坏。这样你才能及时修复你CSP策略。

  • 在部署之前,推荐使用 Content-Security-Policy-Report-Only HTTP消息头,看看是否有违规现象发生。

示例

# 禁用不安全的行内以及eval代码, 只允许 (图片, 字体, 脚本, 其他.)资源通过https下载
# Note that this does not provide any XSS protection
Content-Security-Policy: default-src https:
<!-- 通过设置meta标签,可以做到同样的事情 -->
<meta http-equiv="Content-Security-Policy" content="default-src https:">
# 禁用不安全的行内以及eval代码, 只允许加载同域资源, 但是图片还可以从 imgur.com 域名下加载。
# Also disables the execution of plugins
Content-Security-Policy: default-src 'self'; img-src 'self' https://i.imgur.com; object-src 'none'
# 禁用不安全的行内以及eval代码,只允许加载同源的脚本和样式表, 字体可以从 google下载, 图片可从本域名或者 imgur.com 域名下加载。你的站点就应该如此部署。
Content-Security-Policy: default-src 'none'; font-src 'https://fonts.googleapis.com';
                         img-src 'self' https://i.imgur.com; object-src 'none'; script-src 'self'; style-src 'self'
# 已经存在的站点很难通过禁用脚本策略修复,但是可以确保资源文件都是从https加载的,并且禁用插件。
Content-Security-Policy: default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'
# 先通过接受报告来发现已经存在的漏洞,然后再去对应部署相关的CSP
Content-Security-Policy-Report-Only: default-src https:; report-uri /csp-violation-report-endpoint/
# 禁止站点被嵌套在iframe中,推荐写apis时可以这样使用。
Content-Security-Policy: default-src 'none'; frame-ancestors 'none'

See Also(其他文档)

  • An Introduction to Content Security Policy

  • Content Security Policy Level 2 Standard

  • Google CSP Evaluator

  • Using the frame-ancestors directive to prevent framing

contribute.json

contribute.json是一份部署在web站点根目录下的文本文件,用于描述该站点是什么,它的资源文件存放在哪里,使用何种技术,以及如何追踪该项目和对其贡献代码。contribute.json是一项Mozilla的标准,用于描述所有的正在运行的Mozilla网站和其他项目。

它的存在使得我们能加快修复缺陷的过程,对于只有拥有一小撮维护者的网站来说尤其如此。未来它还可以协助安全研究员找到可以测试的网站,并且告诉他们应该在哪里生成防御缺陷的文档。contribute.json 对于mozilla是强制性的,因为维护人员会经常变更。

必要的子秘钥包括:name, description, bugs, participate (particularly irc and irc-contacts), and urls.

示例

{
  "name": "Bedrock",
    "description": "The app powering www.mozilla.org.",
    "repository": {
      "url": "https://github.com/mozilla/bedrock",
      "license": "MPL2",
      "tests": "https://travis-ci.org/mozilla/bedrock/"
    },
    "participate": {
      "home": "https://wiki.mozilla.org/Webdev/GetInvolved/mozilla.org",
      "docs": "http://bedrock.readthedocs.org/",
      "mailing-list": "https://www.mozilla.org/about/forums/#dev-mozilla-org",
      "irc": "irc://irc.mozilla.org/#www",
      "irc-contacts": [
        "someperson1",
        "someperson2",
        "someperson3"
      ]
    },
    "bugs": {
      "list": "https://bugzilla.mozilla.org/describecomponents.cgi?product=www.mozilla.org",
      "report": "https://bugzilla.mozilla.org/enter_bug.cgi?product=www.mozilla.org",
      "mentored": "https://bugzilla.mozilla.org/buglist.cgi?f1=bug_mentor&o1=isnotempty
                   &query_format=advanced&bug_status=NEW&product=www.mozilla.org&list_id=10866041"
    },
    "urls": {
      "prod": "https://www.mozilla.org",
      "stage": "https://www.allizom.org",
      "dev": "https://www-dev.allizom.org",
      "demo1": "https://www-demo1.allizom.org"
    },
    "keywords": [
      "python",
      "less-css",
      "django",
      "html5",
      "jquery"
    ]
}

See Also(其他文档)

  • The contribute.json Standard

Cookies

创建任何cookies时,都必须尽可能地限制其可访问性,这有助于减少跨站脚本攻击。因为cookies经常包含session等客户端唯一性标识以及其他敏感信息。

指令

  • Name: Cookie 名如果用 __Secure- 或者 __Host- 来作为前缀修饰,可以防止被不安全的资源所重写。

    • 如果一个域名设置为cookies路径为 /, 为该域名下的cookies使用 __Host-可以指定其唯一性(不包含子域)

    • 为其他cookies设置__Secure- 标明其安全来源 (例如HTTPS)

  • Secure: 所有cookies必须带有安全标书,用以指明其来自安全协议(HTTPS)

  • HttpOnly: Cookies 如果不想被js脚本获取,应当声明该属性

  • Expiration: Cookies 一旦不需要了就需要设置过期,session标识尤其需要快速过期时间。

    • Expires: 给cookie设置绝对的过期时间

    • Max-Age: 给cookies设置相对的过期时间(支持IE8及以上版本)

  • Domain: 如果Cookies需要在其他的站点被访问, 应当设置相应的值。 并且尽可能地严格处理此类值得设定。

  • Path: Cookies 尽可能地严格处理改值得设定 但对于大多数应用来说都是设置为根目录/

  • SameSite: 禁止通过跨域请求携带cookies(例如通过 标签, etc.),作为加强的 anti-CSRF measure

    • SameSite=Strict: 只在站点直接导航过去时发送cookie

    • SameSite=Lax: 当从别的网站过来时,才可以发送cookie

示例

# 带有Session标识的cookie 只能在同源域名下获取,并且在浏览器关闭时清空
Set-Cookie: MOZSESSIONID=980e5da39d4b472b9f504cac9; Path=/; Secure; HttpOnly
# 带有Session标识的Cookies用于所有 mozilla.org站点 有效期三十天, 使用 __Secure- 前缀
# 该cookies无法跨域, 但是可以在 Mozilla 站点 之间传递。
Set-Cookie: __Secure-MOZSESSIONID=7307d70a86bd4ab5a00499762; Max-Age=2592000; Domain=mozilla.org; Path=/; Secure; HttpOnly; SameSite=Lax
# 为当前域名设置有效期为长期的cookie, 可以被js访问, 当用户允许TOS?
# 此cookie会从其他导航到你网站是发送, 例如点击一个链接
Set-Cookie: __Host-ACCEPTEDTOS=true; Expires=Fri, 31 Dec 9999 23:59:59 GMT; Path=/; Secure; SameSite=Lax
# 用于安全站点的Session标识,例如:bugzilla.mozilla.org. 不允许跨域发送,也不允许跨站点发送,结合反CSRF方法,这种方式有效的对抗CSRF攻击
Set-Cookie: __Host-BMOSESSIONID=YnVnemlsbGE=; Max-Age=2592000; Path=/; Secure; HttpOnly; SameSite=Strict

See Also(其他文档)

  • RFC 6265 (HTTP Cookies)

  • HTTP Cookie Prefixes

  • Same-site Cookies

Cross-origin Resource Sharing(跨域资源共享)

Access-Control-Allow-Origin是一项header消息头,它指定了哪些外域脚本可以通过使用通过类似XMLHttpRequest方法来获得你的域名下内容的操控权。crossdomain.xml 和 clientaccesspolicy.xml也提供相似方法,但是他们分别适用于Flash 和 Silverlight应用。

除非有特殊需求,否则无需对此消息头进行配置。只有当你需要通过内容网络分发(CND)的方式来引入js或者css库文件或者使用公共api时,才需要开启使用。一旦设置了该项,就应该在合理地方式为少数指定的资源做配置。例如你的站点同时部署了html文件和apis接口资源,那么你只需要为apis配置该消息头即可。如果不这样,那么跨域的链接是可以无限制地在你域名下操控你的内容文件。

示例

# 允许所有站点读取javascript库文件的内容,保证了子资源工作正常
Access-Control-Allow-Origin: *
# 允许 https://random-dashboard.mozilla.org 读取该资源api返回的结果
Access-Control-Allow-Origin: https://random-dashboard.mozilla.org
<!—允许从 https://random-dashboard.mozilla.org 站点的flash读取该站点的权限 -->
<cross-domain-policy xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFile.xsd">
  <allow-access-from domain="random-dashboard.mozilla.org"/>
  <site-control permitted-cross-domain-policies="master-only"/>
  <allow-http-request-headers-from domain="random-dashboard.mozilla.org" headers="*" secure="true"/>
</cross-domain-policy>
<!— 对Silverlight做同样的事情-->
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="https://random-dashboard.mozilla.org"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>

See Also(其他文档)

  • CORS for Developers

  • MDN on HTTP access control (CORS)

  • Adobe on Setting crossdomain.xml

  • Microsoft on Setting clientaccesspolicy.xml

CSRF Prevention(跨站请求伪造的防御)

跨站请求伪造利用web站点对现有用户的信任,通过使用未认证的命令对其制造攻击。因为它利用了cookies,所以它能获取到sesssion,使得它们看起来是有效的命令。CSFR攻击看起来像下面的样子:

<!-- 试图删除客户的账号 -->
img src="https://accounts.mozilla.org/management/delete?confirm=true">

当用户尝试访问包含此片段代码的网页时,浏览器会自动发送一个get请求。如果用户登陆过,那么浏览器会提供seesion给该请求,本次删除操作就会成功。

虽然有很多缓和策略来防止CSRF攻击,例如使用Origin/Referrer检测或者怀疑-反应系统,但使用最广泛并且易懂的方式是使用anti-CSRF tokens。anti-CSRF tokens利用秘密的,独有的,不可预测的token来阻止那些毁灭性的变化。通过某些规则变化,将完整的用户会话信息保存为token,或者为每个请求设置独里的单独的token。虽然通过SameSite指令是最有效的防御方法,但是此指令未获得浏览器的广泛支持,所以最好将它们结合起来一起使用。

示例

<!-- A secret anti-CSRF token, 隐藏在表单中,用来删除账号 -->
<input type="hidden" name="csrftoken" value="1df93e1eafa42012f9a8aff062eeb1db0380b">
# 服务端: 设置一个无法跨域的anti-CSRF cookie,js会自动发送该消息头
Set-Cookie: CSRFTOKEN=1df93e1eafa42012f9a8aff062eeb1db0380b; Path=/; Secure; SameSite=Strict
// 客户端: 使用js给ajax中添加header头
var token = readCookie(CSRFTOKEN);                   // read the cookie
httpRequest.setRequestHeader('X-CSRF-Token', token); // add it as an X-CSRF-Token header

See Also(其他文档)

  • Wikipedia on CRSF Attacks and Prevention

  • OWASP CSRF Prevention Cheat Sheet

Referrer Policy(引用策略)

当用户通过超链接导航或者通过web站点下载外部资源时,浏览器都会通过http消息头refrrer指令告知该请求所属的目标站点源信息。尽管这种做法用途广泛,当也会将用户隐私暴露在危险的之中。HTTP 引用策略,能全面地控制浏览器何时并且如何传输这些http Referrer消息头信息。

通常情况下,如果https://example.com/page.html界面包含<img src="https://not.example.com/image.jpg”>代码片段,那么浏览器会像下面那样发送请求

GET /image.jpg HTTP/1.1
Host: not.example.com
Referer: https://example.com/page.html

除了包含的一些其他私密信息,浏览器也会传输把一些本来不打算公开的,仅供内部使用的URL(internal-use-only URLs)信息。如果作为运营者,你想要限制其信息的暴露,你可以通过设置HTTP 引用策略,来杜绝此种现象或者减少该请求所包含的信息量。

指令:

  • no-referrer:从不发送 Referer 消息头

  • same-origin: 发送 referrer, 但仅仅限于同源下的请求

  • strict-origin: 发送给指定域下的请求, (e.g. https://example.com/)

  • strict-origin-when-cross-origin: 同源请求下发送所有信息, 非同源请求则不包含URL信息

备注:

引用策略还包含了其他一些的指令。但是这些指令有别于上面提到的指令,并不会保护隐私和限制暴露。

例如:no-referrer-when-downgrade指令是被浏览器默认设置的行为,当站点需要考虑到正在奔溃的现存系统,而这些系统又依赖于完整引用消息头运作时,我们就可以使用该指令。现代浏览器对其支持度都还比较高,除了Microsoft Edge之外,因为它使用了其他一些老旧的策略。

示例

# 在example.com下,只有发送下载或者链接到其他example.com上请求时, 发送Referer消息头 
Referrer-Policy: same-origin
# 同源发送完整的referrer,非同源域名发送信息被减少后referrer消息头
Referrer-Policy: strict-origin-when-cross-origin
# 如果浏览器不支持referrers 则禁用之,反之则使用strict-origin-when-cross-origin
# 使用 strict-origin-when-cross-origin 如果浏览器支持
Referrer-Policy: no-referrer, strict-origin-when-cross-origin
<!--使用meta标签做同样的事情 -->
<meta http-equiv="Referrer-Policy" content="no-referrer, strict-origin-when-cross-origin">
<!-- 使用单独link标签,对本次请求做相同的事情 -->
<a href="https://mozilla.org/" referrerpolicy="no-referrer, strict-origin-when-cross-origin">

See Also(其他文档)

  • Referrer Policy standard

  • MDN on Referrer Policy

robots.txt

Robots.txt是一份部署在站点根目录下的文本文件,它指导机器人(被搜索引擎操控的索引器)如何行动,告诉他们不要为一些网站路径建立索引检索。这对于减少你的网页被下载次数尤其重要。通过禁用自动生产的内容索引,它也可以防止资源被搜索结果污染,毕竟不是所有的资源都从搜索引擎中受益。

站点可以选择性使用robots.txt。但如果使用,请确保是用于以下目的:不要用于阻止信息被暴露或者隐藏部分网站信息。尽管它不会阻止这些站点被搜索引擎获取,但它也不可能阻止黑客的攻击,毕竟robots.txt本身就经常用于做侦查作用。

示例

# 阻止所有搜索引擎收录此站点。
User-agent: *
Disallow: /
# 使用 robots.txt 来隐藏一些目录,但不建议这么做。
User-agent: *
Disallow: /secret/admin-interface

See Also(其他文档)

  • About robots.txt

Subresource Integrity(子资源完整性)

子资源安全性,是w3c的一项新的标准。它保护了所有使用CDN加载javascript类库资源的网站,因为攻击者通过修改这些第三方类库资源文件的内容,从而制造出网站漏洞。

例如,从mozilla.org 站点下加载的jquery.org站点下的资源脚本代码,就有权限修改mozilla.org上的任何内容。如果这些CDN资源被攻击或者篡改,那么它就可以修改下载的链接,损坏站点,偷取证书,造成DoS攻击的后果。等等。

子资源安全性锁定了在特定时间下外部javascript文件的内容。如果该内容实体在此后的任何时刻被修改过,浏览器会拒绝加载它。因此,对于所有非Mozilla-受控系统的资源文件,我们都强烈推荐使用子资源完整性配置。

请注意,CDN必须通过Access-Control-Allow-Origin设置其可跨域资源共享,很多CDN是这样做的,如果有CDN没有这样做,请联系Mozilla 信息安全部门,我们会很高兴为你连上它。

指令

  • integrity: 使用hash函数生成的文件加密字符串

  • crossorigin: 告诉浏览器发送匿名的请求,不带cookie

示例

<!— 从CDN加载 jQuery 2.1.4 —>
<script src="https://code.jquery.com/jquery-2.1.4.min.js" integrity="sha384-R4/ztc4ZlRqWjqIuvf6RX5yb/v90qNGx6fS48N0tRxiGkqveZETq72KgDVJCp2TC" crossorigin="anonymous"></script>
<!— 从CDN加载 AngularJS 1.4.8 —>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js" integrity="sha384-r1y8TJcloKTvouxnYsi4PJAx+nHNr90ibsEn3zznzDzWBN9X3o3kbHLSgcIPtzAp" crossorigin="anonymous"></script>
# 生成自己的hash加密值
$ curl -s https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js | \ openssl dgst -sha384 -binary | \ openssl base64 -A r1y8TJcloKTvouxnYsi4PJAx+nHNr90ibsEn3zznzDzWBN9X3o3kbHLSgcIPtzAp

See Also(其他文档)

  • SRI Hash Generator - 为你生成 <script> 标签, 并且告知你CDN是否支持跨域资源共享。

  • Subresource Integrity W3C Standard

X-Content-Type-Options

X-Content-Type-Options是一项被Internet Explorer, Chrome and Firefox 50+等浏览器支持的消息头,它告诉浏览器除非服务端指明了资源文件的MIME type,否则不加载脚本和样式表。如果没有此消息头,浏览器会错误地把其他类型的文件当成脚本或者样式,从而导致了XSS攻击。因此站点都必须设置X-Content-Type-Options消息头和合适的文本类型。

示例

阻止浏览器错误地将非脚本文件当成脚本文件

X-Content-Type-Options: nosniff

See Also(其他文档)

  • Microsoft on Reducing MIME Type Security Risks

X-Frame-Options
X-Frame-Options是一项http消息头,它能控制你的站点如何被嵌入到iframe当中去。点击劫持(Clickjacking)是一项真实存在的一种攻击,它允许在恶意网站上隐藏你的网站,从而跟踪用户点击行为。因此使用X-Frame-Options对于新的网站来说是强制的。并且现存网站都应该尽快地支持X-Frame-Options。

X-Frame-Options已经被CSP中的frame-ancestors指令所取代,它可以更深入细微地控制哪些需要被插入iframe的网络站点. 但是frame-ancestors指令还不被一些浏览器支持(IE11 and older, Edge, Safari 9.1 (desktop), and Safari 9.2 (iOS),)因此推荐使用X-Frame-Options作为CSP的补充。

如果站点需要被嵌入iframe必须使用内容安全策略或者部署js脚本防御,来防止来自恶意域名的点击劫持。

指令

  • DENY: 不允许被嵌入iframe(推荐)

  • SAMEORIGIN: 只允许被同源网站的iframe嵌入

  • ALLOW-FROM uri: 废弃;请使用 CSP’s frame-ancestors 指令替换

示例

# 阻止站点被嵌入,使用X-Frame-Options 和 CSP
Content-Security-Policy: frame-ancestors 'none'
X-Frame-Options: DENY
# 只嵌套同源域名下的iframe
Content-Security-Policy: frame-ancestors 'self'
X-Frame-Options: SAMEORIGIN
# 只允许 framer.mozilla.org to 嵌套站点
# 这会阻止那些嵌套在不支持CSP2+浏览器中
Content-Security-Policy: frame-ancestors https://framer.mozilla.org
X-Frame-Options: DENY

See Also(其他文档)

  • MDN on X-Frame-Options

  • CSP standard on ‘frame-ancestors’

  • OWASP Clickjacking Defense Cheat Sheet

X-XSS-Protection

X-XSS-Protection是一项chrome和IE的新特性,当它检测到站点被跨站脚本攻击时,会阻止浏览器继续加载网页。尽管大多是现代浏览器中可以不需要使用它,因为通过CSP策略的unsafe-inline’指令,我们可以禁止行内脚本执行。然而对于使用旧的浏览器用户来说,这也是可以提供保护的。

新部署的web站点可以使用该消息头,但考虑到它带来的一些误报的风险,所以只推荐给现存的网站使用。对于API来说,应该部署严格的CSP消息头,而不是使用该策略。

示例

当检测到XSS 攻击则阻断界面加载

X-XSS-Protection: 1; mode=block

更多文章请关注《万象专栏》

本栏目由《康祺惠购APP》独家赞助