User:Apking/Web Security Guidelines: Difference between revisions

From MozillaWiki
Jump to navigation Jump to search
(Redirected page to Security/Guidelines/Web Security)
(aoeu)
Line 1: Line 1:
#REDIRECT [[Security/Guidelines/Web Security]]
__NOTOC__
<div style="max-width: 75em;">
  <table>
    <tr>
      <td style="white-space: nowrap;">
        <!-- Roll our own TOC, since the wiki has very old styles -->
        <div id="toc" class="toc">
          <div id="toctitle">
            <h2>Contents</h2>
          </div>
          <ul style="padding-right: 1em;">
            <li>[[#Web Security Cheat Sheet|1 Cheat Sheet]]
            <li>[[#Transport Layer Security (TLS/SSL)|2 Transport Layer Security (TLS/SSL)]]
            <li>
              <ul>
                <li>[[#HTTPS|2.1 HTTPS]]</li>
                <li>[[#HTTP Strict Transport Security|2.2 HTTP Strict Transport Security]]</li>
                <li>[[#HTTP Redirections|2.3 HTTP Redirections]]</li>
                <li>[[#HTTP Public Key Pinning|2.4 HTTP Public Key Pinning]]</li>
                <li>[[#Resource Loading|2.5 Resource Loading]]</li>
              </ul>
            </li>
            <li>[[#Content Security Policy|3 Content Security Policy]]</li>
            <li>[[#contribute.json|4 contribute.json]]</li>
            <li>[[#Cookies|5 Cookies]]</li>
            <li>[[#Cross-origin Resource Sharing|6 Cross-origin Resource Sharing]]</li>
            <li>[[#CSRF Prevention|7 CSRF Prevention]]</li>
            <li>[[#Referrer Policy|8 Referrer Policy]]</li>
            <li>[[#robots.txt|9 robots.txt]]</li>
            <li>[[#Subresource Integrity|10 Subresource Integrity]]</li>
            <li>[[#X-Content-Type-Options|11 X-Content-Type-Options]]</li>
            <li>[[#X-Frame-Options|12 X-Frame-Options]]</li>
            <li>[[#X-XSS-Protection|13 X-XSS-Protection]]</li>
            <li>[[#Version History|14 Version History]]</li>
          </ul>
        </div>
      </td>
      <td style="vertical-align: top; padding: 1em 0 0 1.5em;">
The goal of this document is to help operational teams with creating secure web applications. All Mozilla sites and deployments are expected to follow the recommendations below. Use of these recommendations by the public is strongly encouraged.
 
The Enterprise Information Security (EIS) team maintains this document as a reference guide to navigate the rapidly changing landscape of web security. Changes are reviewed and merged by the Infosec team, and broadcast to the various Operational teams.
 
Updates to this page should be submitted to the [https://github.com/mozilla/wikimo_opsec source repository on github].
 
 
 
<div style="text-align: center;">'''STATUS: <span style="background-color: #14892c; border-radius: .25em; color: #ffffff; display: inline-block; font-weight: bold; margin: 0 .5em; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">READY</span>'''</div>
      </td>
    </tr>
  </table>
</div>
 
 
= Web Security Cheat Sheet =
 
{| class="wikitable sortable" style="width: 100%;"
|- style="background-color: #aaaaaa;"
! data-sort-type="number" | Guideline
! data-sort-type="number" | Security<br>Benefit
! data-sort-type="number" | Implementation<br>Difficulty
! data-sort-type="number" | Order<sup style="font-size: .8em; position: relative; top: -.4em; vertical-align: baseline;">&dagger;</sup>
! Requirements
! Notes
|- style="background-color: #ffffff;"
| data-sort-value="1" | [[#HTTPS|<span style="color: black;">HTTPS</span>]]
| data-sort-value="4" style="text-align: center;" | <span style="background-color: #d04437; border-radius: .25em; color: #ffffff; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Maximum</span>
| data-sort-value="2" style="text-align: center;" | <span style="background-color: #4a6785; border-radius: .25em; color: #ffffff; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Medium</span>
| style="text-align: center;" data-sort-value="0" |
| Mandatory
| Sites should use HTTPS (or other secure protocols) for all communications
|- style="background-color: #ffffff;"
| data-sort-value="2" style="padding-left: 1.5em;" | [[#HTTP Public Key Pinning|<span style="color: black;">Public Key Pinning</span>]]
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| data-sort-value="4" style="text-align: center;" | <span style="background-color: #d04437; border-radius: .25em; color: #ffffff; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Maximum</span>
| style="text-align: center;" data-sort-value="99" | --
| Mandatory for maximum risk sites only
| Not recommended for most sites
|- style="background-color: #ffffff;"
| data-sort-value="3" style="padding-left: 1.5em;" | [[#HTTP Redirections|<span style="color: black;">Redirections from HTTP</span>]]
| data-sort-value="4" style="text-align: center;" | <span style="background-color: #d04437; border-radius: .25em; color: #ffffff; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Maximum</span>
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| style="text-align: center;" | 3
| Mandatory
| Websites must redirect to HTTPS, API endpoints should disable HTTP entirely
|- style="background-color: #ffffff;"
| data-sort-value="4" style="padding-left: 1.5em;" | [[#Resource Loading|<span style="color: black;">Resource Loading</span>]]
| data-sort-value="4" style="text-align: center;" | <span style="background-color: #d04437; border-radius: .25em; color: #ffffff; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Maximum</span>
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| style="text-align: center;" | 2
| Mandatory for all websites
| Both passive and active resources should be loaded through protocols using TLS, such as HTTPS
|- style="background-color: #ffffff;"
| data-sort-value="5" style="padding-left: 1.5em;" | [[#HTTP Strict Transport Security|<span style="color: black;">Strict Transport Security</span>]]
| data-sort-value="3" style="text-align: center;" | <span style="background-color: #ffd351; border-radius: .25em; color: #594300; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">High</span>
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| style="text-align: center;" | 4
| Mandatory for all websites
| Minimum allowed time period of six months
|- style="background-color: #ffffff;"
| data-sort-value="6" style="padding-left: 1.5em;" | [[#HTTPS|<span style="color: black;">TLS Configuration</span>]]
| data-sort-value="2" style="text-align: center;" | <span style="background-color: #4a6785; border-radius: .25em; color: #ffffff; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Medium</span>
| data-sort-value="2" style="text-align: center;" | <span style="background-color: #4a6785; border-radius: .25em; color: #ffffff; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Medium</span>
| style="text-align: center;" | 1
| Mandatory
| Use the most secure Mozilla TLS configuration for your user base, typically [[Security/Server Side TLS#Intermediate compatibility (default)|Intermediate]]
|- style="background-color: #ffffff;"
| data-sort-value="7" | [[#Content Security Policy|<span style="color: black;">Content Security Policy</span>]]
| data-sort-value="3" style="text-align: center;" |<span style="background-color: #ffd351; border-radius: .25em; color: #594300; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">High</span>
| data-sort-value="3" style="text-align: center;" | <span style="background-color: #ffd351; border-radius: .25em; color: #594300; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">High</span>
| style="text-align: center;" | 10
| Mandatory for new websites<br>Recommended for existing websites
| Disabling inline script is the greatest concern for CSP implementation
|- style="background-color: #ffffff;"
| data-sort-value="8" | [[#Cookies|<span style="color: black;">Cookies</span>]]
| data-sort-value="3" style="text-align: center;" | <span style="background-color: #ffd351; border-radius: .25em; color: #594300; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">High</span>
| data-sort-value="2" style="text-align: center;" | <span style="background-color: #4a6785; border-radius: .25em; color: #ffffff; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Medium</span>
| style="text-align: center;" | 7
| Mandatory for all new websites<br>Recommended for existing websites
| All cookies must be set with the Secure flag, and set as restrictively as possible
|- style="background-color: #ffffff;"
| data-sort-value="9" | [[#contribute.json|<span style="color: black;">contribute.json</span>]]
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| style="text-align: center;" | 9
| Mandatory for all new Mozilla websites<br>Recommended for existing Mozilla sites
| Mozilla sites should serve contribute.json and keep contact information up-to-date
|- style="background-color: #ffffff;"
| data-sort-value="10" | [[#Cross-origin Resource Sharing|<span style="color: black;">Cross-origin Resource Sharing</span>]]
| data-sort-value="3" style="text-align: center;" | <span style="background-color: #ffd351; border-radius: .25em; color: #594300; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">High</span>
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| style="text-align: center;" | 11
| Mandatory
| Origin sharing headers and files should not be present, except for specific use cases
|- style="background-color: #ffffff;"
| data-sort-value="11" | [[#CSRF Prevention|<span style="color: black;">Cross-site Request Forgery Tokenization</span>]]
| data-sort-value="3" style="text-align: center;" | <span style="background-color: #ffd351; border-radius: .25em; color: #594300; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">High</span>
| data-sort-value="99" style="text-align: center;" | <span style="background-color: #ffffff; border: solid 1px #aaaaaa; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Unknown</span>
| style="text-align: center;" | 6
| Varies
| Mandatory for websites that allow destructive changes<br>Unnecessary for all other websites<br>Most application frameworks have built-in CSRF tokenization to ease implementation
|- style="background-color: #ffffff;"
| data-sort-value="11" | [[#Referrer Policy|<span style="color: black;">Referrer Policy</span>]]
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| data-sort-value="99" style="text-align: center;" | <span style="background-color: #ffffff; border: solid 1px #aaaaaa; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Unknown</span>
| style="text-align: center;" | 6
| Recommended for all websites
| Improves privacy for users, prevents leaking of internal URLs via Referer
|- style="background-color: #ffffff;"
| data-sort-value="12" | [[#robots.txt|<span style="color: black;">robots.txt</span>]]
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| style="text-align: center;" | 13
| Optional
| Websites that implement robots.txt must use it only for noted purposes
|- style="background-color: #ffffff;"
| data-sort-value="13" | [[#Subresource Integrity|<span style="color: black;">Subresource Integrity</span>]]
| data-sort-value="2" style="text-align: center;" | <span style="background-color: #4a6785; border-radius: .25em; color: #ffffff; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Medium</span>
| data-sort-value="2" style="text-align: center;" | <span style="background-color: #4a6785; border-radius: .25em; color: #ffffff; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Medium</span>
| style="text-align: center;" | 14
| Recommended<sup style="font-size: .8em; position: relative; top: -.4em; vertical-align: baseline;">&Dagger;</sup>
| <sup style="font-size: .8em; position: relative; top: -.4em; vertical-align: baseline;">&Dagger;</sup> Only for websites that load JavaScript or stylesheets from foreign origins
|- style="background-color: #ffffff;"
| data-sort-value="14" | [[#X-Content-Type-Options|<span style="color: black;">X-Content-Type-Options</span>]]
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| style="text-align: center;" | 8
| Recommended for all websites
| Websites should verify that they are setting the proper MIME types for all resources
|- style="background-color: #ffffff;"
| data-sort-value="15" | [[#X-Frame-Options|<span style="color: black;">X-Frame-Options</span>]]
| data-sort-value="3" style="text-align: center;" | <span style="background-color: #ffd351; border-radius: .25em; color: #594300; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">High</span>
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| style="text-align: center;" | 5
| Mandatory for all websites
| Websites that don't use DENY or SAMEORIGIN must employ clickjacking defenses
|- style="background-color: #ffffff;"
| data-sort-value="16" | [[#X-XSS-Protection|<span style="color: black;">X-XSS-Protection</span>]]
| data-sort-value="1" style="text-align: center;" | <span style="background-color: #cccccc; border-radius: .25em; color: #000000; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Low</span>
| data-sort-value="2" style="text-align: center;" | <span style="background-color: #4a6785; border-radius: .25em; color: #ffffff; display: inline-block; font-weight: bold; margin: .1em 0; min-width: 6em; padding: .05em .5em; text-transform: uppercase; text-align: center;">Medium</span>
| style="text-align: center;" | 12
| Mandatory for all new websites<br>Recommended for existing websites
| Manual testing should be done for existing websites, prior to implementation
|}
 
<div style="margin-left: 1.5em;"><sup style="font-size: .8em; position: relative; top: -.4em; vertical-align: baseline;">&dagger;</sup> Suggested order that administrators implement the web security guidelines. It is based on a combination of the security impact and the ease of implementation from an operational and developmental perspective.</div>
 
 
 
<div style="max-width: 75em;">
= Transport Layer Security (TLS/SSL) =
 
Transport Layer Security provides assurances about the confidentiality, authentication, and integrity of all communications both inside and outside of Mozilla. To protect our users and networked systems, the support and use of encrypted communications using TLS is mandatory for all systems.
 
 
== HTTPS ==
 
Websites or API endpoints that only communicate with modern browsers and systems should use the [[Security/Server Side TLS#Modern compatibility|Mozilla modern TLS configuration]].
 
Websites intended for general public consumption should use the [[Security/Server Side TLS#Intermediate compatibility (default)|Mozilla intermediate TLS configuration]].
 
Websites that require backwards compatibility with extremely old browsers and operating systems may use the [[Security/Server Side TLS#Old backward compatibility|Mozilla backwards compatible TLS configuration]]. This is not recommended, and use of this compatibility level should be noted in your risk assessment.
 
=== Compatibility ===
 
{| class="wikitable" style="width: 100%;"
|-
! Configuration
! Oldest compatible clients
|- style="background-color: #9EDB58;"
| align="center" | Modern
| style="padding-left: .5em;" | Firefox 27, Chrome 22, Internet Explorer 11, Opera 14, Safari 7, Android 4.4, Java 8
|- style="background-color: #E8E27A;"
| align="center" | Intermediate
| style="padding-left: .5em;" | Firefox 1, Chrome 1, Internet Explorer 7, Opera 5, Safari 1, Internet Explorer 8 (XP), Android 2.3, Java 7
|- style="background-color: #CCCCCC;"
| align="center" | Backwards Compatible (Old)
| style="padding-left: .5em;" | Internet Explorer 6 (XP), Java 6
|}
 
=== See Also ===
 
* [[Security/Server Side TLS|Mozilla Server Side TLS Guidelines]]
* [https://mozilla.github.io/server-side-tls/ssl-config-generator/ Mozilla Server Side TLS Configuration Generator] - generates software configurations for the three levels of compatibility
 
 
 
== HTTP Strict Transport Security ==
 
HTTP Strict Transport Security (HSTS) is an HTTP header that notifies user agents to only connect to a given site over HTTPS, even if the scheme chosen was HTTP.  Browsers that have had HSTS set for a given site will transparently upgrade all requests to HTTPS.  HSTS also tells the browser to treat TLS and certificate-related errors more strictly by disabling the ability for users to bypass the error page.
 
The header consists of one mandatory parameter (<tt>max-age</tt>) and two optional parameters (<tt>includeSubDomains</tt> and <tt>preload</tt>), separated by semicolons.
 
=== Directives ===
 
* <tt>max-age:</tt> how long user agents will redirect to HTTPS, in seconds
* <tt>includeSubDomains:</tt> whether user agents should upgrade requests on subdomains
* <tt>preload:</tt> whether the site should be included in the [https://hstspreload.appspot.com/ HSTS preload list]
 
<tt>max-age</tt> must be set to a minimum of six months (15768000), but longer periods such as one year (31536000) are recommended.  Note that once this value is set, the site must continue to support HTTPS until the expiry time has been reached.
 
<tt>includeSubDomains</tt> notifies the browser that all subdomains of the current origin should also be upgraded via HSTS.  For example, setting <tt>includeSubDomains</tt> on <tt>domain.mozilla.com</tt> will also set it on <tt>host1.domain.mozilla.com</tt> and <tt>host2.domain.mozilla.com</tt>. Extreme care is needed when setting the <tt>includeSubDomains</tt> flag, as it could disable sites on subdomains that don't yet have HTTPS enabled.
 
<tt>preload</tt> allows the website to be included in the [https://hstspreload.appspot.com/ HSTS preload list], upon submission. As a result, web browsers will do HTTPS upgrades to the site without ever having to receive the initial HSTS header.  This prevents downgrade attacks upon first use and is recommended for all high risk websites.  Note that being included in the HSTS preload list requires that <tt>includeSubDomains</tt> also be set.
 
=== Examples ===
 
<pre># Only connect to this site via HTTPS for the next year (recommended)
Strict-Transport-Security: max-age=31536000</pre>
 
<pre># Only connect to this site and subdomains via HTTPS for the next year and also include in the preload list
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload</pre>
 
=== See Also ===
 
* [https://developer.mozilla.org/docs/Web/Security/HTTP_strict_transport_security MDN on HTTP Strict Transport Security]
* [https://tools.ietf.org/html/rfc6797 RFC6797: HTTP Strict Transport Security (HSTS)]
 
 
== HTTP Redirections ==
 
Websites may continue to listen on port 80 (HTTP) so that users do not get connection errors when typing a URL into their address bar, as browsers currently connect via HTTP for their initial request.  Sites that listen on port 80 should only redirect to the same resource on HTTPS. Once the redirection has occured, [[#HTTP Strict Transport Security|HSTS]] should ensure that all future attempts go to the site via HTTP are instead sent directly to the secure site. APIs or websites not intended for public consumption should disable the use of HTTP entirely.
 
Redirections should be done with the 301 redirects, unless they redirect to a different path, in which case they may be done with 302 redirections. Sites should avoid redirections from HTTP to HTTPS on a different host, as this prevents HSTS from being set.
 
=== Examples ===
 
<pre># Redirect all incoming http requests to the same site and URI on https, using nginx
server {
  listen 80;
 
  return 301 https://$host$request_uri;
}</pre>
 
<pre># Redirect for site.mozilla.org from http to https, using Apache
<VirtualHost *:80>
  ServerName site.mozilla.org
  Redirect permanent / https://site.mozilla.org/
</VirtualHost></pre>
 
 
== HTTP Public Key Pinning ==
 
[[Security/Risk management/Rapid Risk Assessment#RRA Risk table (5-10 minutes)|Maximum risk]] sites must enable the use of HTTP Public Key Pinning (HPKP). HPKP instructs a user agent to bind a site to specific root certificate authority, intermediate certificate authority, or end-entity public key. This prevents  certificate authorities from issuing unauthorized certificates for a given domain that would nevertheless be trusted by the browsers. These fradulent certificates would allow an active attacker to MitM and impersonate a website, intercepting credentials and other sensitive data.
 
Due to the risk of knocking yourself off the internet, HPKP must be implemented with extreme care. This includes having backup key pins, testing on a non-production domain, testing with <tt>Public-Key-Pins-Report-Only</tt> and then finally doing initial testing with a very short-lived <tt>max-age</tt> directive. Because of the risk of creating a self-denial-of-service and the very low risk of a fraudulent certificate being issued, it is <em>not recommended</em> for the majority websites to implement HPKP.
 
=== Directives ===
 
* <tt>max-age:</tt> how long the user agent the keys will be pinned; the site must use a cert that meets these pins until this time expires
* <tt>includeSubDomains:</tt> whether user agents should pin all subdomains to the same pins
 
Unlike with HSTS, what to set <tt>max-age</tt> is highly individualized to a given site.  A longer value is more secure, but screwing up your key pins will result in your site being unavailable for a longer period of time. Recommended values fall between 15 and 120 days.
 
=== Examples ===
 
<pre># Pin to DigiCert, Let's Encrypt, and the local public-key, including subdomains, for 15 days
Public-Key-Pins: max-age=1296000; includeSubDomains; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=";
  pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; pin-sha256="P0NdsLTMT6LSwXLuSEHNlvg4WxtWb5rIJhfZMyeXUE0="</pre>
 
=== See Also ===
 
* [https://noncombatant.org/2015/05/01/about-http-public-key-pinning/ About Public Key Pinning]
* [https://scotthelme.co.uk/hpkp-toolset/ The HPKP Toolset] - helpful tools for generating key pins
 
== Resource Loading ==
 
All resources &mdash; whether on the same origin or not &mdash; should be loaded over secure channels. Secure (HTTPS) websites that attempt to load active resources such as JavaScript insecurely will be blocked by browsers. As a result, users will experience degraded UIs and &ldquo;mixed content&rdquo; warnings. Attempts to load passive content (such as images) insecurely, although less risky, will still lead to degraded UIs and can allow active attackers to deface websites or phish users.
 
Despite the fact that modern browsers make it evident that websites are loading resources insecurely, these errors still occur with significant frequency. To prevent this from occuring, developers should verify that all resources are loaded securely prior to deployment.
 
=== Examples ===
 
<pre>&lt;!-- HTTPS is a fantastic way to load a JavaScript resource --&gt;
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script></pre>
 
<pre>&lt;!-- Attempts to load over HTTP will be blocked and will generate mixed content warnings --&gt;
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script></pre>
 
<pre>&lt;!-- Although passive content won't be blocked, it will still generate mixed content warnings --&gt;
<img src="http://very.badssl.com/image.jpg"></pre>
 
=== See Also ===
 
* [https://developer.mozilla.org/en-US/docs/Security/MixedContent MDN on Mixed Content]
 
 
= Content Security Policy =
 
Content Security Policy (CSP) is an HTTP header that allows site operators fine-grained control over where resources on their site can be loaded from. The use of this header is the best method to prevent cross-site scripting (XSS) vulnerabilities. Due to the difficulty in retrofitting CSP into existing websites, CSP is mandatory for all new websites and is strongly recommended for all existing high-risk sites.
 
The primary benefit of CSP comes from disabling the use of unsafe inline JavaScript. Inline JavaScript -- either reflected or stored -- means that improperly escaped user-inputs can generate code that is interpreted by the web browser as JavaScript. By using CSP to disable inline JavaScript, you can effectively eliminate almost all XSS attacks against your site.
 
Note that disabling inline JavaScript means that <em>all</em> JavaScript must be loaded from <tt>&lt;script&gt;</tt> src tags . Event handlers such as <em>onclick</em> used directly on a tag will fail to work, as will JavaScript inside <tt>&lt;script&gt;</tt> tags but not loaded via <tt>src</tt>. Furthermore, inline stylesheets using either <tt>&lt;style&gt;</tt> tags or the <tt>style</tt> attribute will also fail to load. As such, care must be taken when designing sites so that CSP becomes easier to implement.
 
== Implementation Notes ==
 
* Aiming for <tt>default-src: https:</tt> is a great first goal, as it disables inline code and requires https.
* For existing websites with large codebases that would require too much work to disable inline scripts, <tt>default-src: https: 'unsafe-inline'</tt> is still helpful, as it keeps resources from being accidentally loaded over http. However, it does not provide any XSS protection.
* It is recommended to start with a reasonably locked down policy such as <tt>default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'</tt> and then add in sources as revealed during testing.
* In lieu of the preferred HTTP header, pages can instead include a <tt>&lt;meta http-equiv="Content-Security-Policy" content="&hellip;"&gt;</tt> tag. If they do, it should be the first <tt>&lt;meta&gt;</tt> tag that appears inside <tt>&lt;head&gt;</tt>.
* Care needs to be taken with <tt>data:</tt> URIs, as these are unsafe inside <tt>script-src</tt> and <tt>object-src</tt> (or inherited from <tt>default-src</tt>).
* Similarly, the use of <tt>script-src 'self'</tt> can be unsafe for sites with JSONP endpoints. These sites should use a <tt>script-src</tt> that includes the path to their JavaScript source folder(s).
* Unless sites need the ability to execute plugins such as Flash or Silverlight, they should disable their execution with <tt>object-src 'none'</tt>.
* Sites should ideally use the <tt>report-uri</tt> directive, which POSTs JSON reports about CSP violations that do occur. This allows CSP violations to be caught and repaired quickly.
* Prior to implementation, it is recommended to use the <tt>Content-Security-Policy-Report-Only</tt> HTTP header, to see if any violations would have occured with that policy.
 
== Examples ==
 
<pre># Disable unsafe inline/eval, only allow loading of resources (images, fonts, scripts, etc.) over https
# Note that this does not provide any XSS protection
Content-Security-Policy: default-src https:</pre>
 
<pre>&lt;-- Do the same thing, but with a <meta> tag --&gt;
<meta http-equiv="Content-Security-Policy" content="default-src https:"></pre>
 
<pre># Disable the use of unsafe inline/eval, allow everything else except plugin execution
Content-Security-Policy: default-src *; object-src 'none'</pre>
 
<pre># Disable unsafe inline/eval, only load resources from same origin except also allow images from imgur
# Also disables the execution of plugins
Content-Security-Policy: default-src 'self'; img-src 'self' https://i.imgur.com; object-src 'none'</pre>
 
<pre># Disable unsafe inline/eval and plugins, only load scripts and stylesheets from same origin, fonts from google,
# and images from same origin and imgur. Sites should aim for policies like this.
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'</pre>
 
<pre># Pre-existing site that uses too much inline code to fix
# but wants to ensure resources are loaded only over https and disable plugins
Content-Security-Policy: default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'</pre>
 
<pre># Don't implement the above policy yet; instead just report violations that would have occured
Content-Security-Policy-Report-Only: default-src https:; report-uri /csp-violation-report-endpoint/</pre>
 
<pre># Disable the loading of any resources and disable framing, recommended for APIs to use
Content-Security-Policy: default-src 'none'; frame-ancestors 'none'</pre>
 
== See Also ==
 
* [http://www.html5rocks.com/en/tutorials/security/content-security-policy/ An Introduction to Content Security Policy]
* [http://www.cspplayground.com/ Content Security Policy Playground]
* [https://www.w3.org/TR/CSP2/ Content Security Policy Level 2 Standard]
* [[#X-Frame-Options|Using the frame-ancestors directive to prevent framing]]
 
= contribute.json =
 
<tt>contribute.json</tt> is a text file placed within the root directory of a website that describes what it is, where its source exists, what technologies it uses, and how to reach support and contribute.  <tt>contribute.json</tt> is a Mozilla standard used to describe all active Mozilla websites and projects.
 
Its existence can greatly speed up the process of bug triage, particularly for smaller websites with just a handful of maintainers. It further assists with helping security researchers find testable of websites and instructs them on where where in Bugzilla to file their bugs against. As such, <tt>contribute.json</tt> is mandatory for all Mozilla websites, and must be maintained as contributors join and depart projects.
 
Require subkeys include <tt>name</tt>, <tt>description</tt>, <tt>bugs</tt>, <tt>participate</tt> (particularly <tt>irc</tt> and <tt>irc-contacts</tt>), and <tt>urls</tt>.
 
== Examples ==
 
<p style="border: 1px solid #ddd; background-color: #f9f9f9; font-family: monospace, Courier; line-height: 1.3em; padding: 1em; white-space: pre;">{
    "<b>name</b>": "Bedrock",
    "<b>description</b>": "The app powering www.mozilla.org.",
    "repository": {
        "url": <nowiki>"https://github.com/mozilla/bedrock"</nowiki>,
        "license": "MPL2",
        "tests": <nowiki>"https://travis-ci.org/mozilla/bedrock/"</nowiki>
    },
    "<b>participate</b>": {
        "home": <nowiki>"https://wiki.mozilla.org/Webdev/GetInvolved/mozilla.org"</nowiki>,
        "docs": <nowiki>"http://bedrock.readthedocs.org/"</nowiki>,
        "mailing-list": <nowiki>"https://www.mozilla.org/about/forums/#dev-mozilla-org"</nowiki>,
        "<b>irc</b>": <nowiki>"irc://irc.mozilla.org/#www"</nowiki>,
        "<b>irc-contacts</b>": [
            "someperson1",
            "someperson2",
            "someperson3"
        ]
    },
    "<b>bugs</b>": {
        "list": <nowiki>"https://bugzilla.mozilla.org/describecomponents.cgi?product=www.mozilla.org"</nowiki>,
        "report": <nowiki>"https://bugzilla.mozilla.org/enter_bug.cgi?product=www.mozilla.org"</nowiki>,
        "mentored": <nowiki>"https://bugzilla.mozilla.org/buglist.cgi?f1=bug_mentor&o1=isnotempty
                      &query_format=advanced&bug_status=NEW&product=www.mozilla.org&list_id=10866041"</nowiki>
    },
    "<b>urls</b>": {
        "prod": <nowiki>"https://www.mozilla.org"</nowiki>,
        "stage": <nowiki>"https://www.allizom.org"</nowiki>,
        "dev": <nowiki>"https://www-dev.allizom.org"</nowiki>,
        "demo1": <nowiki>"https://www-demo1.allizom.org"</nowiki>,
    },
    "keywords": [
        "python",
        "less-css",
        "django",
        "html5",
        "jquery"
    ]
}
</p>
 
== See Also ==
 
* [https://www.contributejson.org/ The contribute.json Standard]
 
= Cookies =
 
All cookies should be created such that their access is as limited as possible. This can help minimize damage from cross-site scripting (XSS) vulnerabilities, as these cookies often contain session identifiers or other sensitive information.
 
== Directives ==
 
* <tt>Secure</tt>: All cookies must be set with the <tt>Secure</tt> flag, indicating that they should only be sent over HTTPS
* <tt>HttpOnly:</tt> Cookies that don't require access from JavaScript should be set with the <tt>HttpOnly</tt> flag
* Expiration: Cookies should expire as soon as is necessary: session identifiers in particular should expire quickly
** <tt>Expires:</tt> Sets an absolute expiration date for a given cookie
** <tt>Max-Age:</tt> Sets a relative expiration date for a given cookie (not supported by IE <8)
* <tt>Domain:</tt> Cookies should only be set with this if they need to be accessible on other domains, and should be set to the most restrictive domain possible
* <tt>Path:</tt> Cookies should be set to the most restrictive path possible, but for most applications this will be set to the root directory
 
== Experimental Directives ==
 
* Name: Cookie names may be either be prepended with either <tt>__Secure-</tt> or <tt>__Host-</tt> to prevent cookies from being overwritten by insecure sources
** Use <tt>__Host-</tt> for all cookies set to an individual host (no Domain parameter) and with no Path parameter
** Use <tt>__Secure-</tt> for all other cookies
 
== Examples ==
 
<pre># Session identifier cookie only accessible on this host that gets purged when the user closes their browser
Set-Cookie: MOZSESSIONID=980e5da39d4b472b9f504cac9; Path=/; Secure; HttpOnly</pre>
 
<pre># Session identifier for all mozilla.org sites that expires in 30 days using the experimental __Secure- prefix
Set-Cookie: __Secure-MOZSESSIONID=7307d70a86bd4ab5a00499762; Max-Age=2592000; Domain=mozilla.org; Path=/; Secure; HttpOnly</pre>
 
<pre># Sets a long-lived cookie for the current host, accessible by Javascript, when the user accepts the ToS
Set-Cookie: __Host-ACCEPTEDTOS=true; Expires=Fri, 31 Dec 9999 23:59:59 GMT; Path=/; Secure</pre>
 
== See Also ==
 
* [https://tools.ietf.org/html/rfc6265 RFC 6265 (HTTP Cookies)]
* [https://tools.ietf.org/html/draft-west-cookie-prefixes HTTP Cookie Prefixes (Experimental)]
 
 
= Cross-origin Resource Sharing =
 
<tt>Access-Control-Allow-Origin</tt> is an HTTP header that defines which foreign origins are allowed to access the content of pages on your domain via scripts using methods such as XMLHttpRequest.  <tt>crossdomain.xml</tt> and <tt>clientaccesspolicy.xml</tt> provide similar functionality, but for Flash and Silverlight-based applications, respectively.
 
These should not be present unless specifically needed. Use cases include content delivery networks (CDNs) that provide hosting for JavaScript/CSS libraries and public API endpoints. If present, they should be locked down to as few origins and resources as is needed for proper function. For example, if your server provides both a website and an API intended for XMLHttpRequest access on a remote websites, <em>only</em> the API resources should return the <tt>Access-Control-Allow-Origin</tt> header. Failure to do so will allow foreign origins to read the contents of any page on your origin.
 
== Examples ==
<pre># Allow any site to read the contents of this JavaScript library, so that subresource integrity works
Access-Control-Allow-Origin: *</pre>
 
<pre># Allow https://random-dashboard.mozilla.org to read the returned results of this API
Access-Control-Allow-Origin: https://random-dashboard.mozilla.org</pre>
 
<pre>&lt;!-- Allow Flash from https://random-dashboard.mozilla.org to read page contents --&gt;
<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></pre>
 
<pre>&lt;!-- The same thing, but for Silverlight--&gt;
<?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></pre>
 
== See Also ==
* [https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS MDN on HTTP access control (CORS)]
* [https://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html Adobe on Setting crossdomain.xml]
* [https://msdn.microsoft.com/library/cc197955%28v=vs.95%29.aspx Microsoft on Setting clientaccesspolicy.xml]
 
 
= CSRF Prevention =
 
Cross-site request forgeries are a class of attacks where unauthorized commands are transmitted to a website from a trusted user. Because they inherit the users cookies (and hence session information), they appear to be validly issued commands. A CSRF attack might like this:
 
<pre>&lt;!-- Attempt to delete a user's account --&gt;
<img src="https://accounts.mozilla.org/management/delete?confirm=true"></pre>
 
When a user visits a page with that HTML fragment, the browser will attempt to make a GET request to that URL. If the user is logged in, the browser will provide their session cookies and the account deletion attempt will be successful.
 
While there are a variety of mitigation strategies such as Origin/Referrer checking and challenge-response systems (such as [https://en.wikipedia.org/wiki/CAPTCHA CAPTCHA]), the most common and transparent method of CSRF mitigation is through the use of anti-CSRF tokens. Anti-CSRF tokens prevent CSRF attacks by requiring the existence of a secret, unique, and unpredictable token on all destructive changes. These tokens can be set for an entire user session, rotated on a regular basis, or be created uniquely for each request.
 
== Examples ==
 
<pre>&lt;!-- A secret anti-CSRF token, included in the form to delete an account --&gt;
<input type="hidden" name="csrftoken" value="1df93e1eafa42012f9a8aff062eeb1db0380b"></pre>
 
<pre># Server-side: set an anti-CSRF cookie that JavaScript must send as an X header
Set-Cookie: CSRFTOKEN=1df93e1eafa42012f9a8aff062eeb1db0380b; Path=/; Secure
 
// Client-side, have JavaScript add it as an X header to the XMLHttpRequest
var token = readCookie(CSRFTOKEN);                  // read the cookie
httpRequest.setRequestHeader('X-CSRF-Token', token); // add it as an X-CSRF-Token header</pre>
 
== See Also ==
 
* [https://en.wikipedia.org/wiki/Cross-site_request_forgery#Prevention Wikipedia on CRSF Attacks and Prevention]
* [https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet OWASP CSRF Prevention Cheat Sheet]
 
 
= Referrer Policy =
 
When a user navigates to a site via a hyperlink or a webpage includes an external resource, browsers inform these sites of the origin of the requests through the use of the HTTP <tt>Referer</tt> (sic) header. Although this can be useful for a variety of purposes, it can also place the privacy of users at risk.  HTTP Referrer Policy is an HTTP header and &lt;meta&gt; tag that allows sites to have fine-grained control over how browsers use the HTTP <tt>Referer</tt> header.  For example, if a page at https://example.com/page.html contains this file <pre>&lt;img src="https://not.example.com/image.jpg"&gt;</tt>, then the browser will send a request like this:
 
<pre>GET /image/jpg HTTP/1.1
Host: not.example.com
Referer: https://example.com/page.html
 
To reduce the exposure of this information, it is recommended that websites use HTTP Referrer Policy to either eliminate the Referer header entirely, or reduce the amount of information that it contains.
 
== Directives ==
 
<tt>no-referrer</tt>: never send the Referrer header
<tt>same-origin</tt>: send referrer, but only on requests to the same origin
<tt>strict-origin</tt>: send referrer to all origins, but only the URL sans path (e.g. https://example.com/)
<tt>strict-origin-when-cross-origin</tt>: send full referrer on same origin, URL sans path on foreign origin
 
== Notes ==
 
There are many additional options for referrer policies, but they do not protect user privacy in the same way as the options above. <tt>no-referrer-when-downgrade</tt> is the default behavior for all current browsers, and can be used when sites are concerned about breaking existing systems that rely on the full Referrer header for their operation.
 
Please note that support for Referrer Policy is still in its infancy. Chrome currently only supports <tt>no-referrer</tt> from the options above, and Firefox awaits full support with Firefox 52.
 
== Examples ==
 
<pre># On example.com, only send the Referer header when loading or linking to other example.com resources
Referrer-Policy: same-origin
 
# Only send the shortened referrer to a foreign origin, full referrer to a local host
Referrer-Policy: strict-origin-when-cross-origin
 
# Do the same, but with a meta tag
&lt;meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin"&gt;
 
# Do the same, but only for a single link
&lt;a href="https://mozilla.org/" referrerpolicy="strict-origin-when-cross-origin"&gt;</pre>
 
== See Also ==
* [https://w3c.github.io/webappsec-referrer-policy/#referrer-policy-same-origin Referrer Policy standard]
* [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy MDN on Referrer Policy]
 
 
= robots.txt =
 
<tt>robots.txt</tt> is a text file placed within the root directory of a site that tells robots (such as indexers employed by search engines) how to behave, by instructing them not to index certain paths on the website. This is particularly useful for reducing load on your website, though disabling the indexing of automatically generated content. It can also be helpful for preventing the pollution of search results, for resources that don't benefit from being searchable.
 
Sites may optionally use robots.txt, but should only use it for these purposes. It should not be used as a way to prevent the disclosure of private information or to hide portions of a website. Although this does prevent these sites from appearing in search engines, it does not prevent its discovery from attackers, as <tt>robots.txt</tt> is frequently used for reconnaisance.
 
== Examples ==
 
<pre># Stop all search engines from archiving this site
User-agent: *
Disallow: /</pre>
 
<pre># Using robots.txt to hide certain directories is a terrible idea
User-agent: *
Disallow: /secret/admin-interface</pre>
 
== See Also ==
 
* [http://www.robotstxt.org/robotstxt.html About robots.txt]
 
 
= Subresource Integrity =
 
Subresource integrity is a recent W3C standard that protects against attackers modifying the contents of JavaScript libraries hosted on content delivery networks (CDNs) in order to create vulnerabilities in all websites that make use of that hosted library.
 
For example, JavaScript code on jquery.org that is loaded from mozilla.org has access to the entire contents of everything of mozilla.org. If this resource was successfully attacked, it could modify download links, deface the site, steal credentials, cause denial-of-service attacks, and more.
 
Subresource integrity locks an external JavaScript resource to its known contents at a specific point in time. If the file is modified at any point thereafter, supporting web browsers will refuse to load it. As such, the use of subresource integrity is mandatory for all external JavaScript resources loaded from sources not hosted on Mozilla-controlled systems.
 
Note that CDNs must support the Cross Origin Resource Sharing (CORS) standard by setting the <tt>Access-Control-Allow-Origin</tt> header. Most CDNs already do this, but if the CDN you are loading does not support CORS, please contact Mozilla Information Security. We are happy to contact the CDN on your behalf.
 
== Directives ==
 
* <tt>integrity:</tt> a cryptographic hash of the file, prepended with the hash function used to generate it
* <tt>crossorigin:</tt> should be <tt>anonymous</tt> to inform browsers to send anonymous requests without cookies
 
== Examples ==
 
<pre>&lt;!-- Load jQuery 2.1.4 from their CDN --&gt;
<script src="https://code.jquery.com/jquery-2.1.4.min.js"
  integrity="sha384-R4/ztc4ZlRqWjqIuvf6RX5yb/v90qNGx6fS48N0tRxiGkqveZETq72KgDVJCp2TC"
  crossorigin="anonymous"></script></pre>
 
<pre>&lt;!-- Load AngularJS 1.4.8 from their CDN --&gt;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"
  integrity="sha384-r1y8TJcloKTvouxnYsi4PJAx+nHNr90ibsEn3zznzDzWBN9X3o3kbHLSgcIPtzAp"
  crossorigin="anonymous"></script></pre>
 
<pre># Generate the hash myself
$ curl -s https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js | \
    openssl dgst -sha384 -binary | \
    openssl base64 -A
 
r1y8TJcloKTvouxnYsi4PJAx+nHNr90ibsEn3zznzDzWBN9X3o3kbHLSgcIPtzAp</pre>
 
== See Also ==
 
* [https://www.srihash.org/ SRI Hash Generator] - generates <tt>&lt;script&gt;</tt> tags for you, and informs you if the CDN lacks CORS support
* [https://w3c.github.io/webappsec-subresource-integrity/ Subresource Integrity W3C Standard]
 
 
= X-Content-Type-Options =
 
<tt>X-Content-Type-Options</tt> is a header supported by Internet Explorer, Chrome and Firefox 50+ that tells it not to load scripts and stylesheets unless the server indicates the correct MIME type. Without this header, these browsers can incorrectly detect files as scripts and stylesheets, leading to XSS attacks. As such, all sites must set the <tt>X-Content-Type-Options</tt> header and the appropriate MIME types for files that they serve.
 
== Examples ==
 
<pre># Prevent browsers from incorrectly detecting non-scripts as scripts
X-Content-Type-Options: nosniff</pre>
 
== See Also ==
 
* [https://msdn.microsoft.com/en-us/library/gg622941%28v=vs.85%29.aspx Microsoft on Reducing MIME Type Security Risks]
 
= X-Frame-Options =
 
<tt>X-Frame-Options</tt> is an HTTP header that allows sites control over how your site may be framed within an iframe. Clickjacking is a practical attack that allows malicious sites to trick users into clicking links on your site even though they may appear to not be on your site at all. As such, the use of the <tt>X-Frame-Options</tt> header is mandatory for all new websites, and all existing websites are expected to add support for <tt>X-Frame-Options</tt> as soon as possible.
 
Note that <tt>X-Frame-Options</tt> has been superceded by the Content Security Policy's <tt>frame-ancestors</tt> directive, which allows considerably more granular control over the origins allowed to frame a site. As <tt>frame-ancestors</tt> is not yet supported in IE11 and older, Edge, Safari 9.1 (desktop), and Safari 9.2 (iOS), it is recommended that sites employ <tt>X-Frame-Options</tt> in addition to using CSP.
 
Sites that require the ability to be iframed must use either Content Security Policy and/or employ JavaScript defenses to prevent clickjacking from malicious origins.
 
== Directives ==
 
* <tt>DENY</tt>: disallow allow attempts to iframe site (recommended)
* <tt>SAMEORIGIN</tt>: allow the site to iframe itself
* <tt>ALLOW-FROM <em>uri</em></tt>: deprecated; instead use CSP's <tt>frame-ancestors</tt> directive
 
== Examples ==
 
<pre># Block site from being framed
X-Frame-Options: DENY</pre>
 
<pre># Do the same thing, but with Content Security Policy
Content-Security-Policy: frame-ancestors 'none'</pre>
 
<pre># Only allow my site to frame itself
X-Frame-Options: SAMEORIGIN</pre>
 
<pre># Do the same thing, but with Content Security Policy, and also allow frame-you.mozilla.org to frame the site
Content-Security-Policy: frame-ancestors 'self' https://frame-you.mozilla.org</pre>
 
== See Also ==
 
* [https://developer.mozilla.org/en-US/docs/Web/HTTP/X-Frame-Options MDN on X-Frame-Options]
* [https://www.owasp.org/index.php/Clickjacking_Defense_Cheat_Sheet OWASP Clickjacking Defense Cheat Sheet]
 
 
= X-XSS-Protection =
 
<tt>X-XSS-Protection</tt> is a feature of Internet Explorer and Chrome that stops pages from loading when they detect reflected cross-site scripting (XSS) attacks. Although these protections are largely unnecessary in modern browsers when sites implement a strong Content Security Policy that disables the use of inline JavaScript (<tt>'unsafe-inline'</tt>), they can still provide protections for users of older web browsers that don't yet support CSP.
 
New websites should use this header, but given the small risk of false positives, it is only recommended for existing sites. This header is unnecessary for APIs, which should instead simply return a restrictive Content Security Policy header.
 
== Examples ==
 
<pre># Block pages from loading when they detect reflected XSS attacks
X-XSS-Protection: 1; mode=block</pre>
</div>
 
 
= Version History =
 
{| class="wikitable" style="width: 100%;"
|-
! scope="col" style="width: 8em;" | Date
! scope="col" style="width: 6em;" | Editor
! Changes
|-
| style="padding-left: .5em; text-align: left;" | October, 2016
| align="center" | April
| style="padding-left: .5em;" | Added Referrer Policy
|-
| style="padding-left: .5em; text-align: left;" | October, 2016
| align="center" | April
| style="padding-left: .5em;" | Updates to CSP recommendations
|-
| style="padding-left: .5em; text-align: left;" | July, 2016
| align="center" | April
| style="padding-left: .5em;" | Updates to CSP for APIs, and CSP's deprecation of XFO, and XXSSP
|-
| style="padding-left: .5em; text-align: left;" | February, 2016
| align="center" | April
| style="padding-left: .5em;" | Initial document creation
|}

Revision as of 23:31, 27 October 2016

The goal of this document is to help operational teams with creating secure web applications. All Mozilla sites and deployments are expected to follow the recommendations below. Use of these recommendations by the public is strongly encouraged.

The Enterprise Information Security (EIS) team maintains this document as a reference guide to navigate the rapidly changing landscape of web security. Changes are reviewed and merged by the Infosec team, and broadcast to the various Operational teams.

Updates to this page should be submitted to the source repository on github.


STATUS: READY


Web Security Cheat Sheet

Guideline Security
Benefit
Implementation
Difficulty
Order Requirements Notes
HTTPS Maximum Medium Mandatory Sites should use HTTPS (or other secure protocols) for all communications
Public Key Pinning Low Maximum -- Mandatory for maximum risk sites only Not recommended for most sites
Redirections from HTTP Maximum Low 3 Mandatory Websites must redirect to HTTPS, API endpoints should disable HTTP entirely
Resource Loading Maximum Low 2 Mandatory for all websites Both passive and active resources should be loaded through protocols using TLS, such as HTTPS
Strict Transport Security High Low 4 Mandatory for all websites Minimum allowed time period of six months
TLS Configuration Medium Medium 1 Mandatory Use the most secure Mozilla TLS configuration for your user base, typically Intermediate
Content Security Policy High High 10 Mandatory for new websites
Recommended for existing websites
Disabling inline script is the greatest concern for CSP implementation
Cookies High Medium 7 Mandatory for all new websites
Recommended for existing websites
All cookies must be set with the Secure flag, and set as restrictively as possible
contribute.json Low Low 9 Mandatory for all new Mozilla websites
Recommended for existing Mozilla sites
Mozilla sites should serve contribute.json and keep contact information up-to-date
Cross-origin Resource Sharing High Low 11 Mandatory Origin sharing headers and files should not be present, except for specific use cases
Cross-site Request Forgery Tokenization High Unknown 6 Varies Mandatory for websites that allow destructive changes
Unnecessary for all other websites
Most application frameworks have built-in CSRF tokenization to ease implementation
Referrer Policy Low Unknown 6 Recommended for all websites Improves privacy for users, prevents leaking of internal URLs via Referer
robots.txt Low Low 13 Optional Websites that implement robots.txt must use it only for noted purposes
Subresource Integrity Medium Medium 14 Recommended Only for websites that load JavaScript or stylesheets from foreign origins
X-Content-Type-Options Low Low 8 Recommended for all websites Websites should verify that they are setting the proper MIME types for all resources
X-Frame-Options High Low 5 Mandatory for all websites Websites that don't use DENY or SAMEORIGIN must employ clickjacking defenses
X-XSS-Protection Low Medium 12 Mandatory for all new websites
Recommended for existing websites
Manual testing should be done for existing websites, prior to implementation
Suggested order that administrators implement the web security guidelines. It is based on a combination of the security impact and the ease of implementation from an operational and developmental perspective.


Transport Layer Security (TLS/SSL)

Transport Layer Security provides assurances about the confidentiality, authentication, and integrity of all communications both inside and outside of Mozilla. To protect our users and networked systems, the support and use of encrypted communications using TLS is mandatory for all systems.


HTTPS

Websites or API endpoints that only communicate with modern browsers and systems should use the Mozilla modern TLS configuration.

Websites intended for general public consumption should use the Mozilla intermediate TLS configuration.

Websites that require backwards compatibility with extremely old browsers and operating systems may use the Mozilla backwards compatible TLS configuration. This is not recommended, and use of this compatibility level should be noted in your risk assessment.

Compatibility

Configuration Oldest compatible clients
Modern Firefox 27, Chrome 22, Internet Explorer 11, Opera 14, Safari 7, Android 4.4, Java 8
Intermediate Firefox 1, Chrome 1, Internet Explorer 7, Opera 5, Safari 1, Internet Explorer 8 (XP), Android 2.3, Java 7
Backwards Compatible (Old) Internet Explorer 6 (XP), Java 6

See Also


HTTP Strict Transport Security

HTTP Strict Transport Security (HSTS) is an HTTP header that notifies user agents to only connect to a given site over HTTPS, even if the scheme chosen was HTTP. Browsers that have had HSTS set for a given site will transparently upgrade all requests to HTTPS. HSTS also tells the browser to treat TLS and certificate-related errors more strictly by disabling the ability for users to bypass the error page.

The header consists of one mandatory parameter (max-age) and two optional parameters (includeSubDomains and preload), separated by semicolons.

Directives

  • max-age: how long user agents will redirect to HTTPS, in seconds
  • includeSubDomains: whether user agents should upgrade requests on subdomains
  • preload: whether the site should be included in the HSTS preload list

max-age must be set to a minimum of six months (15768000), but longer periods such as one year (31536000) are recommended. Note that once this value is set, the site must continue to support HTTPS until the expiry time has been reached.

includeSubDomains notifies the browser that all subdomains of the current origin should also be upgraded via HSTS. For example, setting includeSubDomains on domain.mozilla.com will also set it on host1.domain.mozilla.com and host2.domain.mozilla.com. Extreme care is needed when setting the includeSubDomains flag, as it could disable sites on subdomains that don't yet have HTTPS enabled.

preload allows the website to be included in the HSTS preload list, upon submission. As a result, web browsers will do HTTPS upgrades to the site without ever having to receive the initial HSTS header. This prevents downgrade attacks upon first use and is recommended for all high risk websites. Note that being included in the HSTS preload list requires that includeSubDomains also be set.

Examples

# Only connect to this site via HTTPS for the next year (recommended)
Strict-Transport-Security: max-age=31536000
# Only connect to this site and subdomains via HTTPS for the next year and also include in the preload list
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

See Also


HTTP Redirections

Websites may continue to listen on port 80 (HTTP) so that users do not get connection errors when typing a URL into their address bar, as browsers currently connect via HTTP for their initial request. Sites that listen on port 80 should only redirect to the same resource on HTTPS. Once the redirection has occured, HSTS should ensure that all future attempts go to the site via HTTP are instead sent directly to the secure site. APIs or websites not intended for public consumption should disable the use of HTTP entirely.

Redirections should be done with the 301 redirects, unless they redirect to a different path, in which case they may be done with 302 redirections. Sites should avoid redirections from HTTP to HTTPS on a different host, as this prevents HSTS from being set.

Examples

# Redirect all incoming http requests to the same site and URI on https, using nginx
server {
  listen 80;

  return 301 https://$host$request_uri;
}
# Redirect for site.mozilla.org from http to https, using Apache
<VirtualHost *:80>
  ServerName site.mozilla.org
  Redirect permanent / https://site.mozilla.org/
</VirtualHost>


HTTP Public Key Pinning

Maximum risk sites must enable the use of HTTP Public Key Pinning (HPKP). HPKP instructs a user agent to bind a site to specific root certificate authority, intermediate certificate authority, or end-entity public key. This prevents certificate authorities from issuing unauthorized certificates for a given domain that would nevertheless be trusted by the browsers. These fradulent certificates would allow an active attacker to MitM and impersonate a website, intercepting credentials and other sensitive data.

Due to the risk of knocking yourself off the internet, HPKP must be implemented with extreme care. This includes having backup key pins, testing on a non-production domain, testing with Public-Key-Pins-Report-Only and then finally doing initial testing with a very short-lived max-age directive. Because of the risk of creating a self-denial-of-service and the very low risk of a fraudulent certificate being issued, it is not recommended for the majority websites to implement HPKP.

Directives

  • max-age: how long the user agent the keys will be pinned; the site must use a cert that meets these pins until this time expires
  • includeSubDomains: whether user agents should pin all subdomains to the same pins

Unlike with HSTS, what to set max-age is highly individualized to a given site. A longer value is more secure, but screwing up your key pins will result in your site being unavailable for a longer period of time. Recommended values fall between 15 and 120 days.

Examples

# Pin to DigiCert, Let's Encrypt, and the local public-key, including subdomains, for 15 days
Public-Key-Pins: max-age=1296000; includeSubDomains; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=";
  pin-sha256="YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; pin-sha256="P0NdsLTMT6LSwXLuSEHNlvg4WxtWb5rIJhfZMyeXUE0="

See Also

Resource Loading

All resources — whether on the same origin or not — should be loaded over secure channels. Secure (HTTPS) websites that attempt to load active resources such as JavaScript insecurely will be blocked by browsers. As a result, users will experience degraded UIs and “mixed content” warnings. Attempts to load passive content (such as images) insecurely, although less risky, will still lead to degraded UIs and can allow active attackers to deface websites or phish users.

Despite the fact that modern browsers make it evident that websites are loading resources insecurely, these errors still occur with significant frequency. To prevent this from occuring, developers should verify that all resources are loaded securely prior to deployment.

Examples

<!-- HTTPS is a fantastic way to load a JavaScript resource -->
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<!-- Attempts to load over HTTP will be blocked and will generate mixed content warnings -->
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<!-- Although passive content won't be blocked, it will still generate mixed content warnings -->
<img src="http://very.badssl.com/image.jpg">

See Also


Content Security Policy

Content Security Policy (CSP) is an HTTP header that allows site operators fine-grained control over where resources on their site can be loaded from. The use of this header is the best method to prevent cross-site scripting (XSS) vulnerabilities. Due to the difficulty in retrofitting CSP into existing websites, CSP is mandatory for all new websites and is strongly recommended for all existing high-risk sites.

The primary benefit of CSP comes from disabling the use of unsafe inline JavaScript. Inline JavaScript -- either reflected or stored -- means that improperly escaped user-inputs can generate code that is interpreted by the web browser as JavaScript. By using CSP to disable inline JavaScript, you can effectively eliminate almost all XSS attacks against your site.

Note that disabling inline JavaScript means that all JavaScript must be loaded from <script> src tags . Event handlers such as onclick used directly on a tag will fail to work, as will JavaScript inside <script> tags but not loaded via src. Furthermore, inline stylesheets using either <style> tags or the style attribute will also fail to load. As such, care must be taken when designing sites so that CSP becomes easier to implement.

Implementation Notes

  • Aiming for default-src: https: is a great first goal, as it disables inline code and requires https.
  • For existing websites with large codebases that would require too much work to disable inline scripts, default-src: https: 'unsafe-inline' is still helpful, as it keeps resources from being accidentally loaded over http. However, it does not provide any XSS protection.
  • It is recommended to start with a reasonably locked down policy such as default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self' and then add in sources as revealed during testing.
  • In lieu of the preferred HTTP header, pages can instead include a <meta http-equiv="Content-Security-Policy" content="…"> tag. If they do, it should be the first <meta> tag that appears inside <head>.
  • Care needs to be taken with data: URIs, as these are unsafe inside script-src and object-src (or inherited from default-src).
  • Similarly, the use of script-src 'self' can be unsafe for sites with JSONP endpoints. These sites should use a script-src that includes the path to their JavaScript source folder(s).
  • Unless sites need the ability to execute plugins such as Flash or Silverlight, they should disable their execution with object-src 'none'.
  • Sites should ideally use the report-uri directive, which POSTs JSON reports about CSP violations that do occur. This allows CSP violations to be caught and repaired quickly.
  • Prior to implementation, it is recommended to use the Content-Security-Policy-Report-Only HTTP header, to see if any violations would have occured with that policy.

Examples

# Disable unsafe inline/eval, only allow loading of resources (images, fonts, scripts, etc.) over https
# Note that this does not provide any XSS protection
Content-Security-Policy: default-src https:
<-- Do the same thing, but with a <meta> tag -->
<meta http-equiv="Content-Security-Policy" content="default-src https:">
# Disable the use of unsafe inline/eval, allow everything else except plugin execution
Content-Security-Policy: default-src *; object-src 'none'
# Disable unsafe inline/eval, only load resources from same origin except also allow images from imgur
# Also disables the execution of plugins
Content-Security-Policy: default-src 'self'; img-src 'self' https://i.imgur.com; object-src 'none'
# Disable unsafe inline/eval and plugins, only load scripts and stylesheets from same origin, fonts from google,
# and images from same origin and imgur. Sites should aim for policies like this.
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'
# Pre-existing site that uses too much inline code to fix
# but wants to ensure resources are loaded only over https and disable plugins
Content-Security-Policy: default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'
# Don't implement the above policy yet; instead just report violations that would have occured
Content-Security-Policy-Report-Only: default-src https:; report-uri /csp-violation-report-endpoint/
# Disable the loading of any resources and disable framing, recommended for APIs to use
Content-Security-Policy: default-src 'none'; frame-ancestors 'none'

See Also

contribute.json

contribute.json is a text file placed within the root directory of a website that describes what it is, where its source exists, what technologies it uses, and how to reach support and contribute. contribute.json is a Mozilla standard used to describe all active Mozilla websites and projects.

Its existence can greatly speed up the process of bug triage, particularly for smaller websites with just a handful of maintainers. It further assists with helping security researchers find testable of websites and instructs them on where where in Bugzilla to file their bugs against. As such, contribute.json is mandatory for all Mozilla websites, and must be maintained as contributors join and depart projects.

Require subkeys include name, description, bugs, participate (particularly irc and irc-contacts), and urls.

Examples

{ "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

Cookies

All cookies should be created such that their access is as limited as possible. This can help minimize damage from cross-site scripting (XSS) vulnerabilities, as these cookies often contain session identifiers or other sensitive information.

Directives

  • Secure: All cookies must be set with the Secure flag, indicating that they should only be sent over HTTPS
  • HttpOnly: Cookies that don't require access from JavaScript should be set with the HttpOnly flag
  • Expiration: Cookies should expire as soon as is necessary: session identifiers in particular should expire quickly
    • Expires: Sets an absolute expiration date for a given cookie
    • Max-Age: Sets a relative expiration date for a given cookie (not supported by IE <8)
  • Domain: Cookies should only be set with this if they need to be accessible on other domains, and should be set to the most restrictive domain possible
  • Path: Cookies should be set to the most restrictive path possible, but for most applications this will be set to the root directory

Experimental Directives

  • Name: Cookie names may be either be prepended with either __Secure- or __Host- to prevent cookies from being overwritten by insecure sources
    • Use __Host- for all cookies set to an individual host (no Domain parameter) and with no Path parameter
    • Use __Secure- for all other cookies

Examples

# Session identifier cookie only accessible on this host that gets purged when the user closes their browser
Set-Cookie: MOZSESSIONID=980e5da39d4b472b9f504cac9; Path=/; Secure; HttpOnly
# Session identifier for all mozilla.org sites that expires in 30 days using the experimental __Secure- prefix
Set-Cookie: __Secure-MOZSESSIONID=7307d70a86bd4ab5a00499762; Max-Age=2592000; Domain=mozilla.org; Path=/; Secure; HttpOnly
# Sets a long-lived cookie for the current host, accessible by Javascript, when the user accepts the ToS
Set-Cookie: __Host-ACCEPTEDTOS=true; Expires=Fri, 31 Dec 9999 23:59:59 GMT; Path=/; Secure

See Also


Cross-origin Resource Sharing

Access-Control-Allow-Origin is an HTTP header that defines which foreign origins are allowed to access the content of pages on your domain via scripts using methods such as XMLHttpRequest. crossdomain.xml and clientaccesspolicy.xml provide similar functionality, but for Flash and Silverlight-based applications, respectively.

These should not be present unless specifically needed. Use cases include content delivery networks (CDNs) that provide hosting for JavaScript/CSS libraries and public API endpoints. If present, they should be locked down to as few origins and resources as is needed for proper function. For example, if your server provides both a website and an API intended for XMLHttpRequest access on a remote websites, only the API resources should return the Access-Control-Allow-Origin header. Failure to do so will allow foreign origins to read the contents of any page on your origin.

Examples

# Allow any site to read the contents of this JavaScript library, so that subresource integrity works
Access-Control-Allow-Origin: *
# Allow https://random-dashboard.mozilla.org to read the returned results of this API
Access-Control-Allow-Origin: https://random-dashboard.mozilla.org
<!-- Allow Flash from https://random-dashboard.mozilla.org to read page contents -->
<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>
<!-- The same thing, but for 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


CSRF Prevention

Cross-site request forgeries are a class of attacks where unauthorized commands are transmitted to a website from a trusted user. Because they inherit the users cookies (and hence session information), they appear to be validly issued commands. A CSRF attack might like this:

<!-- Attempt to delete a user's account -->
<img src="https://accounts.mozilla.org/management/delete?confirm=true">

When a user visits a page with that HTML fragment, the browser will attempt to make a GET request to that URL. If the user is logged in, the browser will provide their session cookies and the account deletion attempt will be successful.

While there are a variety of mitigation strategies such as Origin/Referrer checking and challenge-response systems (such as CAPTCHA), the most common and transparent method of CSRF mitigation is through the use of anti-CSRF tokens. Anti-CSRF tokens prevent CSRF attacks by requiring the existence of a secret, unique, and unpredictable token on all destructive changes. These tokens can be set for an entire user session, rotated on a regular basis, or be created uniquely for each request.

Examples

<!-- A secret anti-CSRF token, included in the form to delete an account -->
<input type="hidden" name="csrftoken" value="1df93e1eafa42012f9a8aff062eeb1db0380b">
# Server-side: set an anti-CSRF cookie that JavaScript must send as an X header
Set-Cookie: CSRFTOKEN=1df93e1eafa42012f9a8aff062eeb1db0380b; Path=/; Secure

// Client-side, have JavaScript add it as an X header to the XMLHttpRequest
var token = readCookie(CSRFTOKEN);                   // read the cookie
httpRequest.setRequestHeader('X-CSRF-Token', token); // add it as an X-CSRF-Token header

See Also


Referrer Policy

When a user navigates to a site via a hyperlink or a webpage includes an external resource, browsers inform these sites of the origin of the requests through the use of the HTTP Referer (sic) header. Although this can be useful for a variety of purposes, it can also place the privacy of users at risk. HTTP Referrer Policy is an HTTP header and <meta> tag that allows sites to have fine-grained control over how browsers use the HTTP Referer header. For example, if a page at https://example.com/page.html contains this file
<img src="https://not.example.com/image.jpg"></tt>, then the browser will send a request like this:

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

To reduce the exposure of this information, it is recommended that websites use HTTP Referrer Policy to either eliminate the Referer header entirely, or reduce the amount of information that it contains.

== Directives ==

<tt>no-referrer</tt>: never send the Referrer header
<tt>same-origin</tt>: send referrer, but only on requests to the same origin
<tt>strict-origin</tt>: send referrer to all origins, but only the URL sans path (e.g. https://example.com/)
<tt>strict-origin-when-cross-origin</tt>: send full referrer on same origin, URL sans path on foreign origin

== Notes ==

There are many additional options for referrer policies, but they do not protect user privacy in the same way as the options above. <tt>no-referrer-when-downgrade</tt> is the default behavior for all current browsers, and can be used when sites are concerned about breaking existing systems that rely on the full Referrer header for their operation.

Please note that support for Referrer Policy is still in its infancy. Chrome currently only supports <tt>no-referrer</tt> from the options above, and Firefox awaits full support with Firefox 52.

== Examples ==

<pre># On example.com, only send the Referer header when loading or linking to other example.com resources
Referrer-Policy: same-origin

# Only send the shortened referrer to a foreign origin, full referrer to a local host
Referrer-Policy: strict-origin-when-cross-origin

# Do the same, but with a meta tag
<meta http-equiv="Referrer-Policy" content="strict-origin-when-cross-origin">

# Do the same, but only for a single link
<a href="https://mozilla.org/" referrerpolicy="strict-origin-when-cross-origin">

See Also


robots.txt

robots.txt is a text file placed within the root directory of a site that tells robots (such as indexers employed by search engines) how to behave, by instructing them not to index certain paths on the website. This is particularly useful for reducing load on your website, though disabling the indexing of automatically generated content. It can also be helpful for preventing the pollution of search results, for resources that don't benefit from being searchable.

Sites may optionally use robots.txt, but should only use it for these purposes. It should not be used as a way to prevent the disclosure of private information or to hide portions of a website. Although this does prevent these sites from appearing in search engines, it does not prevent its discovery from attackers, as robots.txt is frequently used for reconnaisance.

Examples

# Stop all search engines from archiving this site
User-agent: *
Disallow: /
# Using robots.txt to hide certain directories is a terrible idea
User-agent: *
Disallow: /secret/admin-interface

See Also


Subresource Integrity

Subresource integrity is a recent W3C standard that protects against attackers modifying the contents of JavaScript libraries hosted on content delivery networks (CDNs) in order to create vulnerabilities in all websites that make use of that hosted library.

For example, JavaScript code on jquery.org that is loaded from mozilla.org has access to the entire contents of everything of mozilla.org. If this resource was successfully attacked, it could modify download links, deface the site, steal credentials, cause denial-of-service attacks, and more.

Subresource integrity locks an external JavaScript resource to its known contents at a specific point in time. If the file is modified at any point thereafter, supporting web browsers will refuse to load it. As such, the use of subresource integrity is mandatory for all external JavaScript resources loaded from sources not hosted on Mozilla-controlled systems.

Note that CDNs must support the Cross Origin Resource Sharing (CORS) standard by setting the Access-Control-Allow-Origin header. Most CDNs already do this, but if the CDN you are loading does not support CORS, please contact Mozilla Information Security. We are happy to contact the CDN on your behalf.

Directives

  • integrity: a cryptographic hash of the file, prepended with the hash function used to generate it
  • crossorigin: should be anonymous to inform browsers to send anonymous requests without cookies

Examples

<!-- Load jQuery 2.1.4 from their CDN -->
<script src="https://code.jquery.com/jquery-2.1.4.min.js"
  integrity="sha384-R4/ztc4ZlRqWjqIuvf6RX5yb/v90qNGx6fS48N0tRxiGkqveZETq72KgDVJCp2TC"
  crossorigin="anonymous"></script>
<!-- Load AngularJS 1.4.8 from their CDN -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"
  integrity="sha384-r1y8TJcloKTvouxnYsi4PJAx+nHNr90ibsEn3zznzDzWBN9X3o3kbHLSgcIPtzAp"
  crossorigin="anonymous"></script>
# Generate the hash myself
$ 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


X-Content-Type-Options

X-Content-Type-Options is a header supported by Internet Explorer, Chrome and Firefox 50+ that tells it not to load scripts and stylesheets unless the server indicates the correct MIME type. Without this header, these browsers can incorrectly detect files as scripts and stylesheets, leading to XSS attacks. As such, all sites must set the X-Content-Type-Options header and the appropriate MIME types for files that they serve.

Examples

# Prevent browsers from incorrectly detecting non-scripts as scripts
X-Content-Type-Options: nosniff

See Also

X-Frame-Options

X-Frame-Options is an HTTP header that allows sites control over how your site may be framed within an iframe. Clickjacking is a practical attack that allows malicious sites to trick users into clicking links on your site even though they may appear to not be on your site at all. As such, the use of the X-Frame-Options header is mandatory for all new websites, and all existing websites are expected to add support for X-Frame-Options as soon as possible.

Note that X-Frame-Options has been superceded by the Content Security Policy's frame-ancestors directive, which allows considerably more granular control over the origins allowed to frame a site. As frame-ancestors is not yet supported in IE11 and older, Edge, Safari 9.1 (desktop), and Safari 9.2 (iOS), it is recommended that sites employ X-Frame-Options in addition to using CSP.

Sites that require the ability to be iframed must use either Content Security Policy and/or employ JavaScript defenses to prevent clickjacking from malicious origins.

Directives

  • DENY: disallow allow attempts to iframe site (recommended)
  • SAMEORIGIN: allow the site to iframe itself
  • ALLOW-FROM uri: deprecated; instead use CSP's frame-ancestors directive

Examples

# Block site from being framed
X-Frame-Options: DENY
# Do the same thing, but with Content Security Policy
Content-Security-Policy: frame-ancestors 'none'
# Only allow my site to frame itself
X-Frame-Options: SAMEORIGIN
# Do the same thing, but with Content Security Policy, and also allow frame-you.mozilla.org to frame the site
Content-Security-Policy: frame-ancestors 'self' https://frame-you.mozilla.org

See Also


X-XSS-Protection

X-XSS-Protection is a feature of Internet Explorer and Chrome that stops pages from loading when they detect reflected cross-site scripting (XSS) attacks. Although these protections are largely unnecessary in modern browsers when sites implement a strong Content Security Policy that disables the use of inline JavaScript ('unsafe-inline'), they can still provide protections for users of older web browsers that don't yet support CSP.

New websites should use this header, but given the small risk of false positives, it is only recommended for existing sites. This header is unnecessary for APIs, which should instead simply return a restrictive Content Security Policy header.

Examples

# Block pages from loading when they detect reflected XSS attacks
X-XSS-Protection: 1; mode=block


Version History

Date Editor Changes
October, 2016 April Added Referrer Policy
October, 2016 April Updates to CSP recommendations
July, 2016 April Updates to CSP for APIs, and CSP's deprecation of XFO, and XXSSP
February, 2016 April Initial document creation