{"id":2140,"date":"2016-11-10T01:23:28","date_gmt":"2016-11-10T09:23:28","guid":{"rendered":"https:\/\/blog.mozilla.org\/security\/?p=2140"},"modified":"2016-11-10T06:00:01","modified_gmt":"2016-11-10T14:00:01","slug":"enforcing-content-security-by-default-within-firefox","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/","title":{"rendered":"Enforcing Content Security By Default within Firefox"},"content":{"rendered":"<div id=\"magicdomid68\" class=\"ace-line\"><span class=\"\">Before loading a URI, Firefox enforces numerous content security checks verifying that web content can not perform malicious actions. As a first line of defense for example, Firefox enforces the Same-Origin policy (SOP) which prevents malicious script on one origin from obtaining access to sensitive content on another origin. Firefox\u2019 content security checks also ensure that web content rendering on a user\u2019s desktop or mobile device can not access local files. Additionally Firefox supports and enforces: Cross-Origin Resource Sharing (CORS), Mixed Content Blocking, Content Security Policy (CSP), Subresource Integrity (SRI), and applies many more mitigation strategies to prevent web content from performing malicious actions. We refer the reader to <a href=\"https:\/\/observatory.mozilla.org\/\" target=\"_blank\">Mozilla\u2019s HTTP Observatory<\/a> <\/span><span class=\"\"> to find more information on the latest content security concepts and how to configure a site safely and securely. Worth mentioning is that over time not only the web evolves but also content security mechanisms necessary to ensure an end user\u2019s security and privacy and hence it&#8217;s vital to provide an API that new security features within a browser can rely on.<\/span><\/div>\n<div class=\"ace-line\">\n<p>&nbsp;<\/p>\n<p><strong><em>Enforcing Content Security Historically<\/em><\/strong><\/p>\n<\/div>\n<div id=\"magicdomid74\" class=\"ace-line\"><span class=\"\">The name of Firefox\u2019 layout engine is Gecko which reads web content, such as HTML, CSS, JavaScript, etc. and renders it on the user\u2019s screen. For loading resources over the internet, Firefox relies on the network library called Necko. Necko is a platform-independent API and provides functionality for several layers of networking, ranging from transport to presentation layers. For historical reasons, Necko was developed to be available as a standalone client. That separation also caused security checks to happen in Gecko rather than Necko and caused Necko to be agnostic about load context.<\/span><\/div>\n<div id=\"magicdomid12\" class=\"\"><\/div>\n<div id=\"magicdomid75\" class=\"ace-line\"><span class=\"\"><a href=\"https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_in_gecko.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-2143\" src=\"https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_in_gecko-252x149.png\" alt=\"opt_in_gecko\" width=\"400\" height=\"237\" srcset=\"https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_in_gecko-252x149.png 252w, https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_in_gecko-768x454.png 768w, https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_in_gecko-600x355.png 600w, https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_in_gecko.png 810w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/a><\/span><\/div>\n<div id=\"magicdomid76\" class=\"ace-line\"><span class=\"\">As illustrated, Gecko performs all content security checks before resources are requested over the network through Necko. The downside of this legacy architecture is, that all the different subsystems in Gecko need to perform their own security checks before resources are requested over the network. For example, <em>ImageLoader<\/em> as well as <em>ScriptLoader<\/em> have to opt into the relevant security checks before initiating a GET request of the image or script to be loaded, respectively. Even though systematic security checks were always performed, those security checks were sprinkled throughout the codebase. Over time, various specifications for dynamically loading content have proven that such a scattered security model is error-prone.<\/span><\/div>\n<p>&nbsp;<\/p>\n<div class=\"ace-line\">\n<p><strong><em>Enforcing Content Security By Default<\/em><\/strong><\/p>\n<\/div>\n<div id=\"magicdomid78\" class=\"ace-line\"><span class=\"\">Instead of opting into security checks wherever resource loads are initiated throughout the codebase, we refactored Firefox so content security checks are enforced by default.<\/span><\/div>\n<div id=\"magicdomid20\" class=\"\"><\/div>\n<div id=\"magicdomid79\" class=\"ace-line\"><span class=\"\"><a href=\"https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_out_gecko.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter wp-image-2142\" src=\"https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_out_gecko-252x149.png\" alt=\"opt_out_gecko\" width=\"400\" height=\"237\" srcset=\"https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_out_gecko-252x149.png 252w, https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_out_gecko-768x454.png 768w, https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_out_gecko-600x355.png 600w, https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_out_gecko.png 810w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/a><\/span><\/div>\n<div id=\"magicdomid81\" class=\"ace-line\"><span class=\"\">As illustrated, we revamped the security landscape of Firefox providing an API that centralizes all the security checks within Necko. Instead of performing ad hoc security checks for each network request within Gecko, our implementation enables Gecko to provide information about the load context so Necko can perform the relevant security checks in a centralized manner. Whenever data (script, css, image,&#8230;) is about to be requested from the network, our technique creates and attaches an immutable <em>loadinfo-object<\/em> to every network request which remains assigned to a network load throughout the whole loading process and allows Firefox to provide the same security guarantees for resource loads that encounter a server-side redirect.<\/span><\/div>\n<div id=\"magicdomid25\" class=\"\"><\/div>\n<div id=\"magicdomid82\" class=\"ace-line\"><span class=\"\">For an in-depth description of our implementation, which will be fully enforced within Firefox (v. 53), we refer the reader to our publication\u00a0<a href=\"https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/5589a101.pdf\">Enforcing Content Security By Default within Web Browsers<\/a> (DOI 10.1109\/SecDev.2016.8) which was presented at the\u00a0<a href=\"http:\/\/secdev.ieee.org\/\" target=\"_blank\">IEEE International Conference on Cybersecurity Development<\/a> <\/span><span class=\"\">on November 4th, 2016.<\/span><\/div>\n<div id=\"magicdomid27\" class=\"\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Before loading a URI, Firefox enforces numerous content security checks verifying that web content can not perform malicious actions. As a first line of defense for example, Firefox enforces the &hellip; <a class=\"go\" href=\"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/\">Read more<\/a><\/p>\n","protected":false},"author":960,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[69],"tags":[],"coauthors":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Enforcing Content Security By Default within Firefox - Mozilla Security Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Christoph Kerschbaumer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/\",\"url\":\"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/\",\"name\":\"Enforcing Content Security By Default within Firefox - Mozilla Security Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_in_gecko-252x149.png\",\"datePublished\":\"2016-11-10T09:23:28+00:00\",\"dateModified\":\"2016-11-10T14:00:01+00:00\",\"author\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/2aa58e904cdee9bfd7aef6290ccfba5b\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/#primaryimage\",\"url\":\"https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_in_gecko.png\",\"contentUrl\":\"https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_in_gecko.png\",\"width\":810,\"height\":479},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.mozilla.org\/security\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Enforcing Content Security By Default within Firefox\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/#website\",\"url\":\"https:\/\/blog.mozilla.org\/security\/\",\"name\":\"Mozilla Security Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.mozilla.org\/security\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/2aa58e904cdee9bfd7aef6290ccfba5b\",\"name\":\"Christoph Kerschbaumer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/image\/c2f32f82e57d2d276655d533c069c73d\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/34c427186fcdd42f4c9c57a8bd0bcd7b?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/34c427186fcdd42f4c9c57a8bd0bcd7b?s=96&d=identicon&r=g\",\"caption\":\"Christoph Kerschbaumer\"},\"description\":\"Manager, Security Engineering\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Enforcing Content Security By Default within Firefox - Mozilla Security Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/","twitter_misc":{"Written by":"Christoph Kerschbaumer","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/","url":"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/","name":"Enforcing Content Security By Default within Firefox - Mozilla Security Blog","isPartOf":{"@id":"https:\/\/blog.mozilla.org\/security\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/#primaryimage"},"image":{"@id":"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_in_gecko-252x149.png","datePublished":"2016-11-10T09:23:28+00:00","dateModified":"2016-11-10T14:00:01+00:00","author":{"@id":"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/2aa58e904cdee9bfd7aef6290ccfba5b"},"breadcrumb":{"@id":"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/#primaryimage","url":"https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_in_gecko.png","contentUrl":"https:\/\/blog.mozilla.org\/security\/files\/2016\/11\/opt_in_gecko.png","width":810,"height":479},{"@type":"BreadcrumbList","@id":"https:\/\/blog.mozilla.org\/security\/2016\/11\/10\/enforcing-content-security-by-default-within-firefox\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.mozilla.org\/security\/"},{"@type":"ListItem","position":2,"name":"Enforcing Content Security By Default within Firefox"}]},{"@type":"WebSite","@id":"https:\/\/blog.mozilla.org\/security\/#website","url":"https:\/\/blog.mozilla.org\/security\/","name":"Mozilla Security Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.mozilla.org\/security\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/2aa58e904cdee9bfd7aef6290ccfba5b","name":"Christoph Kerschbaumer","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/image\/c2f32f82e57d2d276655d533c069c73d","url":"https:\/\/secure.gravatar.com\/avatar\/34c427186fcdd42f4c9c57a8bd0bcd7b?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/34c427186fcdd42f4c9c57a8bd0bcd7b?s=96&d=identicon&r=g","caption":"Christoph Kerschbaumer"},"description":"Manager, Security Engineering"}]}},"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/posts\/2140"}],"collection":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/users\/960"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/comments?post=2140"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/posts\/2140\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/media?parent=2140"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/categories?post=2140"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/tags?post=2140"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/coauthors?post=2140"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}