RTFM… just kidding! There is no manual for the CORS (Cross-Origin Resource Sharing) specification. I really had you going there, didn't I?
Don't worry, it's not your fault. After all, here is what a Google search provides:
Each of these sites contains a wealth of information about CORS, and each of them is far over the head of your average developer. Given the frequent questions that I receive from confused and frightened developers trying to understand these documents, I thought it might be helpful to boil CORS down into a couple simple examples.
Q. If I have static content that depends neither upon cookies nor user-specific URLs and/or parameters and I want to share my site's content with the web, what should I do?
Q. Well, that is great and all. But what if I want to let a foreign website interact with my site, as a logged-in user, allowing them to do anything they could as if they were on my site? I swear that I understand the risks that this entails and that I really trust this other site to not make any security mistakes such as falling victim to a cross-site scripting (XSS) attack.
Access-Control-Allow-Credentials means that the user's cookies (such as their session cookies) will be sent with the request
Access-Control-Allow-Origin is the whitelisted origin sent in the Origin header by the browser and not * nor blindly reflected
And these optional headers mean the following:
Access-Control-Allow-Methods is the list of allowed HTTP methods beyond GET, HEAD, and POST
Access-Control-Expose-Headers allows example.com to read the contents of the X-Poop-Emoji header (💩, obviously)
Access-Control-Max-Age allows example.com to make these requests without preflights for the next 300 seconds
Again, please be aware that you need to be very careful with Access-Control-Allow-Credentials. Even if you think you're safe by only allowing idempotent methods such as GET, that might be enough to steal an anti-CSRF token and let attackers go to town with CSRF attacks.
If you need additional documentation about other features in CORS, I highly recommend the frustratingly hard to locate CORS for Developers document by Brad Hill.
But that was six months ago. With the Mozilla Observatory being publicly released almost two months ago, I was curious as to whether significant improvement had been made around the internet. After all, in those two months, the Observatory has scanned approximately 1.3M sites, totalling over 2.5M scans.
With that in mind, I ran a new scan of the Alexa Top 1M at the end of October, and here is what I found:
I'll admit, I was a bit taken aback by the overall improvement across the top million sites, especially as some of these security technologies are almost a decade old.
When we did our initial scan of the top million six months ago, a stunning 97.6% of websites were given a failing grade from the Observatory. Have those results changed since then, given the improvements above?
While a decrease of 1.5% in failing grades might seem like only a small improvement, the latest Observatory scan contained 962,011 successful scans. With each percentage point representing nearly ten thousand sites, a drop from 97.6% to 96.09% represents approximately fifteen thousand top websites making significant improvements in their security.
I'm excited for the possibility of seeing further improvements as additional surveys are completed. Please share the Mozilla Observatory and help to make the internet a safer and more secure place for everyone!
Allows 'unsafe-inline' in neither script-src nor style-src
Allows 'unsafe-inline' in style-src only
Amongst sites that set cookies
Disallows foreign origins from reading the domain's contents within user's context
Redirects from HTTP to HTTPS on the same domain, which allows HSTS to be set
Redirects from HTTP to HTTPS, regardless of the final domain
Today was a huge leap forward for humankind, for it marks the day that Let's Encrypt now supports internationalized domain names. That means that you can now get certs with non-ASCII characters in them, which will be huge in helping Let's Encrypt improve HTTPS uptake in countries that use languages outside of the traditional ASCII character set.
How did I do this? First, you must transform unicode (in this case, the 👉👁 emoji) into what is called punycode. Punycode is simply a method of representing unicode characters in ASCII, the only characters supported by the domain name system (DNS). There are many ways to do it, including a simple tool at punycoder.com. For 👉👁, its punycode encoding is xn--mp8hpa.
I simply setup DNS for xn--mp8hpa.pokeinthe.io, updated my nginx configuration to include xn--mp8hpa.pokeinthe.io in its server_name parameter, and requested a cert using my favorite Let's Encrypt client (lego):
root@pokeinthe:~# /opt/go/bin/lego -d pokeinthe.io -d www.pokeinthe.io -d 'xn--mp8hpa.pokeinthe.io' --email 'firstname.lastname@example.org' --accept-tos -k ec384 --webroot /var/www/pokeinthe.io --path '/etc/lego' run
2016/10/21 17:30:02 [INFO][pokeinthe.io, www.pokeinthe.io, xn--ls8h.pokeinthe.io] acme: Obtaining bundled SAN certificate2016/10/21 17:30:03 [INFO][pokeinthe.io] acme: Authorization already valid; skipping challenge2016/10/21 17:30:03 [INFO][www.pokeinthe.io] acme: Authorization already valid; skipping challenge2016/10/21 17:30:03 [INFO][xn--ls8h.pokeinthe.io] acme: Could not find solver for: tls-sni-012016/10/21 17:30:03 [INFO][xn--ls8h.pokeinthe.io] acme: Trying to solve HTTP-012016/10/21 17:30:04 [INFO][xn--ls8h.pokeinthe.io] The server validated our request2016/10/21 17:30:04 [INFO][pokeinthe.io, www.pokeinthe.io, xn--ls8h.pokeinthe.io] acme: Validations succeeded; requesting certificates2016/10/21 17:30:04 [INFO] acme: Requesting issuer cert from https://acme-v01.api.letsencrypt.org/acme/issuer-cert2016/10/21 17:30:04 [INFO][pokeinthe.io] Server responded with a certificate.
It’s been over 25 years since Tim Berners-Lee created the first web browser, giving humanity the ability to easily access and transmit information with people both strange and familiar. And in the following 25 years of evolution, browser makers such as Mozilla, Microsoft, and Google have created numerous security technologies to protect both users and websites from bad actors from those whose goals are to steal user secrets, install malware, or otherwise ruin Berners-Lee’s vision of what the world wide web could be.
Unfortunately, due to their complexity, many of these technologies have struggled with adoption. Critical security technologies such as HTTPS are in use by only 40% of the world wide web, and adoption rates for other technologies only drop from there. Today, I (and Mozilla) am proud to release Observatory by Mozilla as a way to raise awareness of these security measure.
Observatory is a simple tool that allows site operators to quickly assess not just if they are using these technologies, but also helps them identify how well they’re being used. It uses a simple grading system to provide near instant feedback on site improvements as they are made. To assist developers and administrators, Observatory also provides links to quality documentation that demonstrates how these technologies work.
We’re All Failing
Just how bad is adoption? Well, the Observatory has been used to scan over 1.3 million websites so far, and 91% of them don’t take advantage of modern security advances. These aren’t tiny sites either; among these 1.3 million websites are some of the most popular websites in the world.
When nine out of 10 websites receive a failing grade, it’s clear that this is a problem for everyone. And by “everyone”, I’m including Mozilla — among our thousands of sites, a great deal of them fail to pass. We’re working very hard to fix them all! In fact, we’ve already used the Observatory to help improve many of our web sites, including addons.mozilla.org, bugzilla.mozilla.org, and mozillians.org.
We’re using the Observatory as a way to democratize website security best practices, and increase transparency around the application (or lack) of existing security features. We hope to help everyone make things better.
How and Why We Built Observatory
A little over a year ago, I was fortunate to be offered a job at Mozilla, helping to improve the security of their many websites. Finally, I would have an easy job where I could put my feet up and relax all day. After all, Mozilla makes Firefox — one of the world’s most popular web browsers — so it was a certainty in my mind that their websites would be locked down, secure, and fully taking advantage of all the security technologies that Mozilla had helped create.
With a future of easy work secured, I wrote a small scanning tool to examine Mozilla’s websites and report just how well we were doing. As it examined each new site, I realized with growing dismay that my future would indeed not be filled with relaxation but instead with many tiring hours of actual work. It turned out that Mozilla — Mozilla! — didn’t do a better job of keeping up with modern website security practices than any other company or group I had worked with before.
Closing the Knowledge Gap
For most security engineers, the next several months would be exclusively devoted to getting their own sites set up properly. Luckily, because I work for Mozilla, I was in a unique position. After all, Mozilla's mission isn’t simply to make a great web browser, but to improve the internet as a whole. I was encouraged to to work on my scanning tool and make it available for the world to use.
It turns out that knowledge of all these technologies was considerably more difficult to acquire than I had assumed - even for security professionals. In retrospect, it’s not surprising: these technologies are spread over dozens of standard documents and while individual articles may talk about them, there wasn’t one place to go for site operators to learn what each of the technologies do, how to implement them, and how important they were.
Guidelines and documentation are one thing: you can write documentation until you’re blue in the face, but if people aren’t interested in implementing them, adoption rates will still suffer. And so it was one day while working on a tool to test these same Mozilla sites that I struck upon an idea. A site called SSL Labs that tests website’s SSL/TLS configurations had done immeasurably good for the internet by gamifying the process of improving your server’s configuration. Faced with a public letter grade, users, organizations, and companies quickly moved towards improving their configuration.
Drawing upon their experiences, I went to work wrapping the Observatory in an easy-to-use website to make this knowledge available to more than just security professionals. Now anybody with a web browser, URL, and a bit of curiousity will be able to investigate the problems that their sites may have. By providing accessible and transparent results, every member of a development team - regardless of skill level and specialization - will be able to check the URLs that they own or depend on so that they can help push for better security practices that benefit all of us.
How does it work?
Just visit the site, enter a domain and click “scan me”. That’s it! You’ll get a report back. Below you can see the report for addons.mozilla.org, the website that Firefox users use to download new addons for their browser. It’s one of Mozilla’s most important websites, and served as an early test case for the Observatory.
When we first scanned it, addons.mozilla.org got an F, just like 91% of all websites. Assisted by the constant feedback of a slowly increasing grade and clear guidance on what needed fixing, the engineers on the addons team quickly improved their grade to an A+,
Testing (and Fixing) Made Easy
The Observatory performs a multitude of checks across roughly a dozen tests. You may not have heard of many of them, and that’s because their documentation is spread across thousands of articles, hundreds of websites, and dozens of specifications. In fact, despite some of these standards being old enough to have children (see Appendix below), their usage rate amongst the internet’s million most popular websites ranges from 30% for HTTPS all the way down to a depressingly low .005% for Content Security Policy.
Each test you run with the Observatory not only tells you how well you’ve implemented a given standard, but it links back to Mozilla’s single-page web security guidelines, which have descriptions, reasonings, and implementation examples for every test. You can use these guidelines in concert with Observatory scans to continuously improve and monitor the state of your website. For administrators who have lots of sites to test or developers who want to integrate it into their development process, we offer both an API and command-line tools.
We Can’t All Be Perfect
Of course, the results for the Observatory may not be perfectly accurate for your site -- after all, the security needs of a site like GitHub are a good deal more complicated than those of a personal blog. By encouraging the adoption of these standards even for low-risk sites, we hope to make developers, system administrators, and security professionals around the world comfortable and familiar with them. With their newfound knowledge and experience, we hope move from a 91% failure rate to a world with mostly passing grades, with more and more sites proudly displaying their A+ rating on the Observatory by Mozilla.
Want to help make the web a safer place? Let’s work together by testing your site today!
Appendix: A Brief History of Web Security Technologies
Secure HTTP (HTTPS)
Man-in-the-middle Network eavesdropping
MIME type confusion
2009 - 2011
Cross-site scripting (XSS) Session theft
2009 - 2011
2010 - 2015
Content Security Policy
HTTP Strict Transport Security
Man-in-the-middle Network eavesdropping
2013 - 2015
HTTP Public Key Pinning
2014 - 2016
Content Delivery Network (CDN) compromise
2015 - 2016
Cross-site reference forgery (CSRF)
2015 - 2016
Cookie overrides by untrusted sources
† Adoption rate amongst the Alexa top million websites as of April 2016.