{"id":2182,"date":"2017-01-25T01:34:18","date_gmt":"2017-01-25T09:34:18","guid":{"rendered":"https:\/\/blog.mozilla.org\/security\/?p=2182"},"modified":"2017-01-25T01:54:59","modified_gmt":"2017-01-25T09:54:59","slug":"setting-a-baseline-for-web-security-controls","status":"publish","type":"post","link":"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/","title":{"rendered":"Setting a Baseline for Web Security Controls"},"content":{"rendered":"<p>Securing modern web applications effectively is a complex process. However there are many straightforward security controls such as HTTP security headers which are very effective at blocking web common attacks.<\/p>\n<p>At Mozilla we provide <a href=\"https:\/\/wiki.mozilla.org\/Security\/Guidelines\/Web_Security\">Security Guidelines<\/a> as well as a <a href=\"https:\/\/wiki.mozilla.org\/Security\/CloudSec#Security_Checklist\">Checklist<\/a> of security controls for the developers of Firefox Services. Last year, we introduced the <a href=\"https:\/\/medium.com\/mozilla-tech\/promoting-security-best-practices-with-observatory-7b164a190425#.tfv7xdqhj\">Mozilla Observatory<\/a>, a hosted scanner to evaluate the security of websites and services. In this blog post, we present the ZAP Baseline scan designed to test the security controls of web applications in Continuous Integration and Continuous Deployment (CI\/CD).<\/p>\n<p>Verifying that the correct controls are in place across all of our applications can be challenging, especially in a CI\/CD environment. We run full vulnerability scans against our services on a regular basis, but these can take a long time to run and are not really adapted to fast release cycles.<\/p>\n<p>This is why we have introduced a &#8216;baseline&#8217; scan which runs very quickly and on every release of a service, but still gives us crucial feedback about the key security controls that we are concerned about. The baseline scans are included in the CI\/CD pipelines of Firefox services to inform developers of potential issues before they reach production environments. We also run it against all of those services every day to generate a dashboard of the overall security status of our services.<\/p>\n<p>This blog post presents the techniques we use to implement baseline scans in our infrastructure.<\/p>\n<h4>The ZAP Baseline Scan<\/h4>\n<p>Mozilla invests heavily in the development and support of security tools. The author of this blog post leads the <a href=\"https:\/\/www.owasp.org\/index.php\/ZAP\">OWASP Zed Attack Proxy<\/a> (ZAP) project,\u00a0 which we use to run baseline and vulnerability scans.<\/p>\n<p>The <a href=\"https:\/\/github.com\/zaproxy\/zaproxy\/wiki\/ZAP-Baseline-Scan\">ZAP baseline scan<\/a> is a quick, easy and highly configurable way to test the security controls you care about. The tests are non intrusive so they are safe to run against production applications.<br \/>\nYou don\u2019t need to have ZAP installed &#8211; the zap-baseline.py script uses Docker and is included in the 2 ZAP Docker images:<\/p>\n<ul>\n<li><a href=\"https:\/\/hub.docker.com\/r\/owasp\/zap2docker-stable\/\">https:\/\/hub.docker.com\/r\/owasp\/zap2docker-stable\/<\/a><\/li>\n<li><a href=\"https:\/\/hub.docker.com\/r\/owasp\/zap2docker-weekly\/\">https:\/\/hub.docker.com\/r\/owasp\/zap2docker-weekly\/ <\/a><\/li>\n<\/ul>\n<p>For our baseline scans we use the weekly docker image which has more options available &#8211; you can run the script with the -h flag to see all of them.<\/p>\n<p>The script zap-baseline.py uses the ZAP spider to explore the application, by default for just one minute. Spidering the application is important to verify that all pages, and not only the top one, implement the required security controls. This is particularly useful when web frameworks will handle some of the pages automatically without setting the headers.<br \/>\nThe script will then report all of the potential issues found.<\/p>\n<p>The baseline scan can be run against an application by just specifying its URL using the -t flag:<\/p>\n<p>docker run owasp\/zap2docker-weekly zap-baseline.py -t https:\/\/www.example.com<\/p>\n<pre>This will produce output like: \r\n\r\nTotal of 3 URLs\r\nPASS: Cookie No HttpOnly Flag [10010]\r\nPASS: Cookie Without Secure Flag [10011]\r\nPASS: Password Autocomplete in Browser [10012]\r\nPASS: Cross-Domain JavaScript Source File Inclusion [10017]\r\nPASS: Content-Type Header Missing [10019]\r\nPASS: Information Disclosure - Debug Error Messages [10023]\r\nPASS: Information Disclosure - Sensitive Informations in URL [10024]\r\nPASS: Information Disclosure - Sensitive Information in HTTP Referrer Header [10025]\r\nPASS: HTTP Parameter Override [10026]\r\nPASS: Information Disclosure - Suspicious Comments [10027]\r\nPASS: Viewstate Scanner [10032]\r\nPASS: Secure Pages Include Mixed Content [10040]\r\nPASS: Weak Authentication Method [10105]\r\nPASS: Absence of Anti-CSRF Tokens [10202]\r\nPASS: Private IP Disclosure [2]\r\nPASS: Session ID in URL Rewrite [3]\r\nPASS: Script Passive Scan Rules [50001]\r\nPASS: Insecure JSF ViewState [90001]\r\nPASS: Charset Mismatch [90011]\r\nPASS: Application Error Disclosure [90022]\r\nPASS: WSDL File Passive Scanner [90030]\r\nPASS: Loosely Scoped Cookie [90033]\r\nWARN: Incomplete or No Cache-control and Pragma HTTP Header Set [10015] x 1\r\n\u00a0\u00a0\u00a0 https:\/\/www.example.com\r\nWARN: Web Browser XSS Protection Not Enabled [10016] x 3\r\n\u00a0\u00a0\u00a0 https:\/\/www.example.com\r\n\u00a0\u00a0\u00a0 https:\/\/www.example.com\/robots.txt\r\n\u00a0\u00a0\u00a0 https:\/\/www.example.com\/sitemap.xml\r\nWARN: X-Frame-Options Header Not Set [10020] x 1\r\n\u00a0\u00a0\u00a0 https:\/\/www.example.com\r\nWARN: X-Content-Type-Options Header Missing [10021] x 1\r\n\u00a0\u00a0\u00a0 https:\/\/www.example.com\r\nFAIL-NEW: 0\u00a0\u00a0 \u00a0FAIL-INPROG: 0\u00a0\u00a0 \u00a0WARN-NEW: 4\u00a0\u00a0 \u00a0WARN-INPROG: 0\u00a0\u00a0 \u00a0INFO: 0\u00a0\u00a0 \u00a0IGNORE: 0\u00a0\u00a0 \u00a0PASS: 22<\/pre>\n<p>By default the output lists all of the passive scan rules applied and whether they passed or failed.<\/p>\n<p>You can change how the baseline handles different errors by specifying a rule configuration file via either the -c flag (for a local file) or the -u flag for a remote URL.<br \/>\nYou can also generate a default file using the \u2018g\u2019 option: <a href=\"https:\/\/github.com\/zaproxy\/community-scripts\/blob\/master\/api\/mass-baseline\/mass-baseline-default.conf\">https:\/\/github.com\/zaproxy\/community-scripts\/blob\/master\/api\/mass-baseline\/mass-baseline-default.conf<\/a><br \/>\nAs specified in the generated file header you can change any of the \u201cWARN\u201ds to \u201cIGNORE\u201d or \u201cFAIL\u201d.<\/p>\n<p>The script will exit with a 0 if there are no issues, 1 if there are any failures or 2 if there are just warnings. The return value can therefore be used in CI tools like Jenkins, CircleCI, TravisCI, etc. to fail a build step.<\/p>\n<p>For example, the configuration below shows how the baseline scan can run in CircleCI with every pull request:<\/p>\n<pre>test:\r\n\u00a0 override:\r\n\u00a0\u00a0\u00a0 # build and run an application container\r\n\u00a0\u00a0\u00a0 - docker build -t myrepo\/myapp\r\n\u00a0\u00a0\u00a0 - docker run myrepo\/myapp &amp;\r\n\u00a0\u00a0\u00a0 # retrieve the ZAP container\r\n\u00a0\u00a0\u00a0 - docker pull owasp\/zap2docker-weekly\r\n\u00a0\u00a0\u00a0 # run the baseline scan against the application\r\n\u00a0\u00a0\u00a0 - |\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 docker run -t owasp\/zap2docker-weekly zap-baseline.py \\\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 -t http:\/\/172.17.0.2:8080\/ -m 3 -i<\/pre>\n<h4>Scanning Multiple Sites<\/h4>\n<p>The baseline scan is a great way to check that a single site meets your base security requirements.<\/p>\n<p>In order to run the ZAP Baseline scan against a large number of websites, we have written a set of wrapper scripts specific to Mozilla. You can find\u00a0 generic versions of these scripts in the <a href=\"https:\/\/github.com\/zaproxy\/community-scripts\/tree\/master\/api\/mass-baseline\">ZAP community-scripts repository<\/a>.<\/p>\n<p>You will need to customize these scripts as detailed in the <a href=\"https:\/\/github.com\/zaproxy\/community-scripts\/blob\/master\/api\/mass-baseline\/README.md\">README<\/a>:<\/p>\n<ul>\n<li>Change the sites listed in mass-baseline.sh<\/li>\n<li>Change the relevant user and repo details in mass-baseline.sh<\/li>\n<li>Build a docker image<\/li>\n<li>Run the docker image, setting the credentials for your user<\/li>\n<\/ul>\n<p>These scripts will then generate a summary dashboard in your repo wiki:<\/p>\n<p><a href=\"https:\/\/blog.mozilla.org\/security\/files\/2017\/01\/Baseline-summary.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-2183 size-full\" src=\"https:\/\/blog.mozilla.org\/security\/files\/2017\/01\/Baseline-summary.png\" alt=\"Baseline-summary\" width=\"659\" height=\"299\" srcset=\"https:\/\/blog.mozilla.org\/security\/files\/2017\/01\/Baseline-summary.png 659w, https:\/\/blog.mozilla.org\/security\/files\/2017\/01\/Baseline-summary-252x114.png 252w, https:\/\/blog.mozilla.org\/security\/files\/2017\/01\/Baseline-summary-600x272.png 600w\" sizes=\"(max-width: 659px) 100vw, 659px\" \/><\/a><br \/>\nThe \u2018Status\u2019 badge is a link to a page containing the latest baseline results for the relevant application and the \u2018History\u2019 date links to a page which show all of the previous scans.<br \/>\nExample pages are included on the community scripts wiki: <a href=\"https:\/\/github.com\/zaproxy\/community-scripts\/wiki\/Baseline-Summary\">https:\/\/github.com\/zaproxy\/community-scripts\/wiki\/Baseline-Summary<\/a><\/p>\n<h4>Tuning<\/h4>\n<p>The baseline scan is highly configurable and allows you to fine tune the scanning to handle your applications more effectively.<br \/>\nYou can do things like:<\/p>\n<ul>\n<li>Increase the time spent spidering your application<\/li>\n<li>Use the Ajax Spider in addition to the standard ZAP spider to handle applications that make heavy use of JavaScript<\/li>\n<li>Include alpha passive scan rules as well as the beta and release quality ones used by default<\/li>\n<li>Ignore specific URLs or even ignore specific issues on those pages<\/li>\n<li>Link known issues to a bugtracker URL<\/li>\n<li>Specify any of the options supported on the ZAP command line<\/li>\n<\/ul>\n<p>For more details see the ZAP wiki: <a href=\"https:\/\/github.com\/zaproxy\/zaproxy\/wiki\/ZAP-Baseline-Scan\">https:\/\/github.com\/zaproxy\/zaproxy\/wiki\/ZAP-Baseline-Scan<\/a><\/p>\n<h4>Conclusion<\/h4>\n<p>The baseline scan gives us immediate feedback about the security controls in place across all of our web applications. The scans run on every commit so that we are immediately aware if there has been any regression. The dashboard allows us to track the state of our applications and the CI integration provides the ability to block a deployment if the baseline is not met.<\/p>\n<p>Integrating baseline scanning in CI\/CD helps us work more closely with developers and operators. We don\u2019t force our security tools onto DevOps processes, we integrate security into DevOps. The net effect is better collaboration between teams, and faster turnaround on fixing security issues.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Securing modern web applications effectively is a complex process. However there are many straightforward security controls such as HTTP security headers which are very effective at blocking web common attacks. &hellip; <a class=\"go\" href=\"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/\">Read more<\/a><\/p>\n","protected":false},"author":523,"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>Setting a Baseline for Web Security Controls - 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\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Simon Bennetts\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/\",\"url\":\"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/\",\"name\":\"Setting a Baseline for Web Security Controls - Mozilla Security Blog\",\"isPartOf\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/blog.mozilla.org\/security\/files\/2017\/01\/Baseline-summary.png\",\"datePublished\":\"2017-01-25T09:34:18+00:00\",\"dateModified\":\"2017-01-25T09:54:59+00:00\",\"author\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/e2ed1c7653cf96cbac609f05f8197420\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/#primaryimage\",\"url\":\"https:\/\/blog.mozilla.org\/security\/files\/2017\/01\/Baseline-summary.png\",\"contentUrl\":\"https:\/\/blog.mozilla.org\/security\/files\/2017\/01\/Baseline-summary.png\",\"width\":659,\"height\":299},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/blog.mozilla.org\/security\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Setting a Baseline for Web Security Controls\"}]},{\"@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\/e2ed1c7653cf96cbac609f05f8197420\",\"name\":\"Simon Bennetts\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/image\/e0a8997361dbe497c8817fa291282996\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e1ecdd76c9fe0ae3ef1397787a126148?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e1ecdd76c9fe0ae3ef1397787a126148?s=96&d=identicon&r=g\",\"caption\":\"Simon Bennetts\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Setting a Baseline for Web Security Controls - 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\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/","twitter_misc":{"Written by":"Simon Bennetts","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/","url":"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/","name":"Setting a Baseline for Web Security Controls - Mozilla Security Blog","isPartOf":{"@id":"https:\/\/blog.mozilla.org\/security\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/#primaryimage"},"image":{"@id":"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/#primaryimage"},"thumbnailUrl":"https:\/\/blog.mozilla.org\/security\/files\/2017\/01\/Baseline-summary.png","datePublished":"2017-01-25T09:34:18+00:00","dateModified":"2017-01-25T09:54:59+00:00","author":{"@id":"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/e2ed1c7653cf96cbac609f05f8197420"},"breadcrumb":{"@id":"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/#primaryimage","url":"https:\/\/blog.mozilla.org\/security\/files\/2017\/01\/Baseline-summary.png","contentUrl":"https:\/\/blog.mozilla.org\/security\/files\/2017\/01\/Baseline-summary.png","width":659,"height":299},{"@type":"BreadcrumbList","@id":"https:\/\/blog.mozilla.org\/security\/2017\/01\/25\/setting-a-baseline-for-web-security-controls\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blog.mozilla.org\/security\/"},{"@type":"ListItem","position":2,"name":"Setting a Baseline for Web Security Controls"}]},{"@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\/e2ed1c7653cf96cbac609f05f8197420","name":"Simon Bennetts","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blog.mozilla.org\/security\/#\/schema\/person\/image\/e0a8997361dbe497c8817fa291282996","url":"https:\/\/secure.gravatar.com\/avatar\/e1ecdd76c9fe0ae3ef1397787a126148?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e1ecdd76c9fe0ae3ef1397787a126148?s=96&d=identicon&r=g","caption":"Simon Bennetts"}}]}},"_links":{"self":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/posts\/2182"}],"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\/523"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/comments?post=2182"}],"version-history":[{"count":0,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/posts\/2182\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/media?parent=2182"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/categories?post=2182"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/tags?post=2182"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mozilla.org\/security\/wp-json\/wp\/v2\/coauthors?post=2182"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}