Misconfigured CORS
Evan Johnson
Why being secure isn’t getting easier
About Me
My name is Evan
I’m a software engineer.
I’m work on security at Cloudflare
I love golang.
How would you secure the internet?
The internet is not a series of castles
The internet is not a series of castles
Same-Origin Policy
Cross Origin Resource Sharing
CORS is driven by the Origin header
Based on origin header, the server is supposed to make decisions
about what CORS header to display
Access-Control-Allow-Origin: *
Is not the same as reflecting the origin header. * means no cookies
Cross Origin Resource Sharing Appropriately
Cross Origin Resource Sharing Appropriately
Reflecting all Origin headers
As Access-Control-Allow-Origin WITH Access-Control-Allow-
Credentials: true
Would be really bad.
Does anyone do this?
Why?
It basically turns off Same-Origin policy…
Which is like ... one of the worst security problems to
have.
Cross Origin Resource Sharing Problem
Testing for Bad CORS
Testing for bad cors
āžœ ~ curl https://streamable.com -H "Origin: https://evil.com" -I
HTTP/1.1 200 OK
Date: Tue, 27 Sep 2016 03:39:01 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 34969
Connection: keep-alive
Server: nginx
Vary: Accept-Encoding
Set-Cookie: session=D2V05A0PVBFAXGCW7NJFGCPF; Domain=.streamable.com;
Expires=Sat, 13-Feb-2044 03:39:01 GMT; Path=/
Access-Control-Allow-Origin: https://evil.com
Access-Control-Allow-Credentials: true
Exploit Proof of Concept
$.ajax({
url:"https://streamable.com/ajax/me",
success: function( data ) {
document.write("Your stream key is " + data['stream_key']);
},
xhrFields: {
withCredentials: true
}
});
How widespread is this problem?
How do I know?
I scanned the Alexa 1M for websites that:
ā— Access-Control-Allow-Origin: <myevilsite.com>
ā— Access-Control-Allow-Credentials: true
ā— I followed redirects
ā— I checked both http and https
1,514 sites with this problem config
The code - https://github.com/ejcx/badcors-massscan
ā— Written in go
ā— Heavy use of concurrency patterns
ā— Making it public after this talk, and making the results and all the sites
public.
The code -
The code -
What do you do when you find a thousand
vulnerable websites?
Started tracking these misconfigurations at their src
ā— I started looking for the libraries that people were using to cause this
behavior.
ā— I reported this to
ā—‹ SAILS JS
ā—‹ Rack CORS
ā—‹ (some go library rs/cors.go or something)
ā—‹ More to come.
CORS, the source
CORS, the source
So…. What’s this about?
Complexity
Complexity in CORS
Cross origin resource sharing could be way easier.
ā— The authors clearly wanted to prevent people from this type of
behavior.
ā— That’s why ā€œ*ā€ and ā€œAllow-Credentials: trueā€ is not allowed.
ā— Why make it possible at all.
ā— Why do you need 6 different response headers
ā— Reminds me of OpenSSL
CORS is not alone...
ā— CSP
ā— SRI
ā— HPKP
ā— Credential management
ā— HSTS
Content Security Policy
ā— A new ā€œhotā€ http response header
ā— CSP is still a mess. Has 3 headers.
ā— It is growing in complexity BY THE GOSH DARN DAY
Content Security Policy
Sub-Resource Integrity
ā— Load only expected assets. SRI dictates that you can only load things
sub resources that match a hash that is baked in to the DOM.
ā— This is nice, but SRI is confusing. Who should use SRI. When is it no
tnecessary? The spec is not clear.
HTTP Public Key Pinning
ā— There are probably a bakers dozen of websites where this is useful
ā— Securityheaders.io tries to make you want to turn on HPKP
ā— Huge operational burden
ā— Disaster.
ā— Complex.
HPKP
Credential Management
ā— In your browser NOW! Be afraid
ā— Allows websites to log you in using the browser password manager
HTTP Strict Transport Security
ā— Very normal header to set now’a’days.
ā— It is not easy. Beware of ā€œincludeSubdomains
ā— https://twitter.com/bcrypt/status/781969754806366208
What about usable security?
Who remembers OpenSSL?
anyone? anyone?
Why not go the way of TLS1.3
It should be easy to make a castle,
so where do we go from here?
Demand simplicity
ā— Web specifications are hard. Why are they not easy?
ā— Cross Origin Resource Sharing needs a full rewrite.
ā— There are three different Content Security Policy headers....
ā— Some browsers still don’t support it.
ā— Some browsers still don’t support SRI.
WHAT A MESS! Web Specs should be easy!
Come help us save the web
This stuff is all too hard.

Misconfigured CORS, Why being secure isn't getting easier. AppSec USA 2016

  • 1.
    Misconfigured CORS Evan Johnson Whybeing secure isn’t getting easier
  • 2.
    About Me My nameis Evan I’m a software engineer. I’m work on security at Cloudflare I love golang.
  • 3.
    How would yousecure the internet?
  • 4.
    The internet isnot a series of castles
  • 5.
    The internet isnot a series of castles
  • 6.
  • 7.
  • 8.
    CORS is drivenby the Origin header Based on origin header, the server is supposed to make decisions about what CORS header to display
  • 9.
    Access-Control-Allow-Origin: * Is notthe same as reflecting the origin header. * means no cookies
  • 10.
    Cross Origin ResourceSharing Appropriately
  • 11.
    Cross Origin ResourceSharing Appropriately
  • 12.
    Reflecting all Originheaders As Access-Control-Allow-Origin WITH Access-Control-Allow- Credentials: true Would be really bad. Does anyone do this?
  • 13.
    Why? It basically turnsoff Same-Origin policy… Which is like ... one of the worst security problems to have.
  • 14.
    Cross Origin ResourceSharing Problem
  • 15.
  • 16.
    Testing for badcors āžœ ~ curl https://streamable.com -H "Origin: https://evil.com" -I HTTP/1.1 200 OK Date: Tue, 27 Sep 2016 03:39:01 GMT Content-Type: text/html; charset=utf-8 Content-Length: 34969 Connection: keep-alive Server: nginx Vary: Accept-Encoding Set-Cookie: session=D2V05A0PVBFAXGCW7NJFGCPF; Domain=.streamable.com; Expires=Sat, 13-Feb-2044 03:39:01 GMT; Path=/ Access-Control-Allow-Origin: https://evil.com Access-Control-Allow-Credentials: true
  • 17.
    Exploit Proof ofConcept $.ajax({ url:"https://streamable.com/ajax/me", success: function( data ) { document.write("Your stream key is " + data['stream_key']); }, xhrFields: { withCredentials: true } });
  • 18.
    How widespread isthis problem?
  • 19.
    How do Iknow? I scanned the Alexa 1M for websites that: ā— Access-Control-Allow-Origin: <myevilsite.com> ā— Access-Control-Allow-Credentials: true ā— I followed redirects ā— I checked both http and https
  • 20.
    1,514 sites withthis problem config
  • 21.
    The code -https://github.com/ejcx/badcors-massscan ā— Written in go ā— Heavy use of concurrency patterns ā— Making it public after this talk, and making the results and all the sites public.
  • 22.
  • 23.
  • 24.
    What do youdo when you find a thousand vulnerable websites?
  • 25.
    Started tracking thesemisconfigurations at their src ā— I started looking for the libraries that people were using to cause this behavior. ā— I reported this to ā—‹ SAILS JS ā—‹ Rack CORS ā—‹ (some go library rs/cors.go or something) ā—‹ More to come.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
    Cross origin resourcesharing could be way easier. ā— The authors clearly wanted to prevent people from this type of behavior. ā— That’s why ā€œ*ā€ and ā€œAllow-Credentials: trueā€ is not allowed. ā— Why make it possible at all. ā— Why do you need 6 different response headers ā— Reminds me of OpenSSL
  • 32.
    CORS is notalone... ā— CSP ā— SRI ā— HPKP ā— Credential management ā— HSTS
  • 33.
    Content Security Policy ā—A new ā€œhotā€ http response header ā— CSP is still a mess. Has 3 headers. ā— It is growing in complexity BY THE GOSH DARN DAY
  • 34.
  • 35.
    Sub-Resource Integrity ā— Loadonly expected assets. SRI dictates that you can only load things sub resources that match a hash that is baked in to the DOM. ā— This is nice, but SRI is confusing. Who should use SRI. When is it no tnecessary? The spec is not clear.
  • 36.
    HTTP Public KeyPinning ā— There are probably a bakers dozen of websites where this is useful ā— Securityheaders.io tries to make you want to turn on HPKP ā— Huge operational burden ā— Disaster. ā— Complex.
  • 37.
  • 38.
    Credential Management ā— Inyour browser NOW! Be afraid ā— Allows websites to log you in using the browser password manager
  • 39.
    HTTP Strict TransportSecurity ā— Very normal header to set now’a’days. ā— It is not easy. Beware of ā€œincludeSubdomains ā— https://twitter.com/bcrypt/status/781969754806366208
  • 40.
  • 41.
  • 42.
    Why not gothe way of TLS1.3
  • 43.
    It should beeasy to make a castle, so where do we go from here?
  • 44.
    Demand simplicity ā— Webspecifications are hard. Why are they not easy? ā— Cross Origin Resource Sharing needs a full rewrite. ā— There are three different Content Security Policy headers.... ā— Some browsers still don’t support it. ā— Some browsers still don’t support SRI. WHAT A MESS! Web Specs should be easy!
  • 45.
    Come help ussave the web This stuff is all too hard.

Editor's Notes

  • #2Ā Welcome to my talk. My talk is called misconfigured cors. Why being secure isn’t getting easier. For this talk we will be thinking about the internet as a whole, based off of a specific vulnerability I found. I am going to look at a really nasty vulnerability I found in a lot of websites, with the point of looking at the internet as a whole. There’s some tech talk in here about how I looked for the vuln at a pretty large scale, too, which is pretty cool.
  • #3Ā Cloudflare. I work on product security at cloudflare. Cloudflare is a giant network CDN that proxies a huge percentage of all web traffic. We pretty much operate only on port 443 and port 80, as a web company.
  • #4Ā I’ll start out this talk with a question. ā€œHow would you secure the internetā€. This is a lofty and idealistic goal. The internet will never be ā€œsecureā€. There are core limitations baked in to the very fabric of the net. BGP hijacking. DNS. Even in TLS there are many security risks and each CA that is baked in to your trust store, or a signed intermediate, has the ability to man in the middle the encrypted encrypted channels of everyone. This is something we talk about at work regularly. Not, ā€œhow can we make the internet as bullet proof as Luke Cageā€, but how can we have an impact for a lot of web properties. When you are thinking about the internet as a whole, don’t get stuck thinking about your own little bubble. Everyone using the internet, for the most part, stays within their little bubble. NYTimes, Hacker News, Google, Amazon. Everyone’s bubble is different and there are massively popular sites that you have never heard of. Go take a look at the alexa 1m, start at like site number 200,000, read like 1000 of the sites on there and I guarantee you probably will not have heard of more than 3 of them. I think it’s really utilitarian to say ā€œif we can raise the average security of a million websites 5% (whatever 5% means), the impact would be pretty large. A lot of the popular small sites are sites with 0 security budget. Maybe they don’t even have software developer budget, or they have a contract developer they know who they hire a few hours a week. It’s easy to think small, about individual websites. It’s harder to think bigger. About the entire web. This talk is about details, micro-scale, but the point of the talk is macro-scale. So. Let’s start with this:
  • #5Ā  Ideally, this is what we could compare the security someone’s website to. Companies that are growing, making money, and committed to the web might build something like this. This might be a Google, Amazon, Apple, Etc. Castles are mature. They are built on a solid foundation. The details of the castle might not be as pretty on the inside, and there might be a lot of hacks or problems that they solved to build it, but for the most part they are very solid Ideally, all websites are castles, but that isn’t always easy for people. Devs make mistakes. People install wordpress plugins. Eventually, a lot of websites end up looking more like this….
  • #6Ā This: is your average site in the alexa 1 million, and not only from a security perspective. Also from a usability perspective and more. We care mostly about application security, but from a usability perspective, from a loading speed perspective, the image of a bounce house is what a lot of companies look like. I’m not sure if you’ve read the blog post by Maciej C, the guy who runs pinboard, called ā€œThe web obesity crisisā€. Let’s stick to just talking about security though. You have a few companies with huge security budgets. Companies like Google, Facebook, Microsoft who were the pioneers of the bug bounty thing. Started this ā€œhall of fameā€ thing years ago. They had such large security budgets they were paying people they didn’t even know for security work! Besides that, you pretty much have bounce houses surrounding these castles, like an old medieval city. These inflatable castles are sites that do not have dedicated security teams. They are mom-and-pop sites, bloggers with their own wordpress dedicated server on dreamhost, installing plugins and doing all sorts of garbage just trying to make things work. It is not easy for these people to be secure. Lets talk tech now. This ā€œhow do you improve the security of the webā€ question is the question I want you to keep in the back of your mind as I talk about this problem. Alright next, let’s talk about the lynchpin of all web security.
  • #7Ā Same-Origin policy is the foundation that all web security is built on. I think most people should be familiar with this idea, but the idea is that scripts from one website cannot access data of a different origin. I’m sure most web people are familiar with this already. It dictates that example1.com here, requesting example2.com will be blocked by default. It’s fundamental. If this wasn’t the case, you would sign on to your online banking, go to a website, and they would have ajax that fetched all your banking information with your browser. Cross origin resource sharing is a way for a website to share things with other websites. This is normally blocked. Here is an example of CORS. You have example1.com making a request to example2.com with ajax. We don’t really have to talk about what is being requested. We just know that by default, this is blocked.
  • #8Ā Here is an example of cross origin resource sharing. Same Origin policy might not be wanted in all situations. Sometimes there is a reason for for the two sites to communicate cross origin. Here is an example of CORS with a pretty normal configuration that a lot of CDNs have. Javascript from example.com is consuming the example-api.com API over AJAX. You see example-api has the Access-Control-Allow-Origin * header. This means any website can consume it! This header has a lot of baggage to learn about it. But we have a very small set of things we care about, for purposes of this talk. For the purpose of this talk, you don’t need to know a ton about CORS. I’m going to give you a quick 2 slide run down of CORS. I’m going to show you two different HTTP requests, and talk about the difference between the CORS policies.
  • #9Ā This means no cookies can be sent! This is fundamentally different than
  • #10Ā If you want to allow cookies to be sent cross origin, you there ā€˜*’ means no cookies can never be sent to the along with the cross origin request.
  • #11Ā Here’s a real HTTP request that has a CORS turned on. This allows a website to fetch this javascript page dynamically, and not have to hard code a script source tag. This is really common for javascript CDNs.
  • #12Ā Here is another CORS example. This is fastly.com, one of cloudflare’s competitors actually. Here you see a different CORS response. Instead of * there is a hostname here. If you notice which hostname, it’s the one from the Origin header we sent.
  • #13Ā If you want to allow cookies to be sent cross origin, you there ā€˜*’ means no cookies can never be sent to the along with the cross origin request.
  • #14Ā How big of a problem is this? To put it in english….
  • #15Ā Here is an example of why CORS reflecting all origins with access control allow credentials true could be exploited. A user would go to evil.com, and evil would request something from your bank. This slide is bad because your bank is returning lat long information and not bank data, but it should be returning bank data.
  • #16Ā Okay. so it’s really easy to do with curl. This is good for testing a single individual site.
  • #17Ā Here’s a proof of concept. It was fixed last night at like 11pm, and I didn’t create a new one…. This is a real HTTP request that I sent a couple weeks ago.
  • #18Ā Streamable is vulnerable. Here’s an example of how simple it is to exploit this. We are thinking about the internet at a wide scale. Not one site.
  • #19Ā This problem is ā€œYOOGEā€ around the net.
  • #20Ā This problem is really big. There are some really weird edge cases to search for here, but I kept it really simple.
  • #21Ā This is a lot of sites. It is important to remember, though, that not all of these sites are ā€œproblematicā€. There is no problem for sites that are serving static content. Only sites that are taking user data. Doing per user things. Setting per user cookies. This brings up a new problem to solve for me. The disclosue problem. To scan for this, I wrote go code.
  • #22Ā This will be open source soon. Github.com/ejcx/hw. Im working on some legal issues we had with some really big companies
  • #23Ā This is the basic go routine. This is opening a bunch of files and reading lines from them, and finally passing them to a channel.
  • #24Ā This is the code to create n worker ā€œthreadsā€. It’s really neat. I create a lot of workers that all read from the channel s, that contains site names, and scans them
  • #25Ā What do you do when you find over 1000 vulnerable websites? How do you triage this? Report it on hackerone? Bugcrowd and hackerone do not have anything close to the type of industry penetration that I can actually reliably look companies up on this. Some of the companies are really big. Really hard to get in contact with the proper channels Some companies are startups. I look for these and get pretty instant responses back (from CEOs awake at 3am looking at their emails.). This isn’t something I can get a CVE for. It is very general and up to individuals who are misunderstanding CORS, not someone rolling out a vulnerable software version. There is no patch for this. What did I do?
  • #26Ā So. After finding >1000+ websites with this undesirable behavior I decided that… ā€œDevs do not make repeated mistakes like thisā€. SAILSJS fixed it immediately. RackCORS is a DEAD PROJECT. DO NOT USE IT. None of the problems were as funny to me as this.
  • #27Ā This is an answer on stackoverflow that introduces this vulnerability Im talking about today. We have a top answer on stackoverflow that is just plain old awful. This in the picture only has 106 upvotes, but today is has over 130. But… there is something nice
  • #28Ā This is one of the comments on that stackoverflow answer. They PERFECTLY explain the risk that the answer provides. It is very ugly but this person, Jules, does it perfectly in just a few sentences. Jules is a god damn hero.
  • #29Ā So…. What is this all about? What is the point of me finding this problem? What was the problem, anyways, can I actually blame the people writing the libraries that? Who is the real person that we can throw under the bus? What is the root cause of this? So. The real person to throw under the bus is……..
  • #30Ā Complexity. Complexity is the real issue here. Complexity is the root of all security evil. Complexity makes things hard which means things are
  • #31Ā CORS is so complex, it is one RFC with 3 HTTP Request Headers 6 HTTP Response Headers. This is ALL TO ALLOW A SITE LIKE www.yoursite.com to communicate with api.yousite.com It’s really just sad. 6 Response headers, all with their own rules and more.
  • #32Ā Most people who implemented the libraries did not realize that * was a real CORS policy.
  • #33Ā Regarding complexity. CORS is not alone. Theres are some of the ā€œexciting and hot wordsā€ on the menu in 2016. CSP, content security policy. SRI, sub resource integrity. HPKP, http public key pinning. Credential management which provides js APIs for websites to access the password store in a user’s browser, and HSTS. HSTS is very surprising to be up here…. They all have a lot of baggage This is a lot of complexity to learn.
  • #34Ā CSP is very complicated. It is one of my bones to pick. It is super popular as a ā€œhotā€ thingg to add to your website if you are an appsec person. It isn’t just one header it is X-WebKit-CSP Content-Security-Policy X-Content-Security-Policy This is a lot of headers. It used to be a pretty simple Idea but it is slowly growing out of control. The idea of Content Security Policy is to provide an HTTP response header that restricts what resources the page can load. It’s a great header because, at a big company, it really forces the marketing and front end team to engage with the security team more often, once a CSP header exists. But besides that. Lots of things are being thrown on top of CSP.
  • #35Ā CSP is so complicated that Mike West actually produced a spec where content security policy is a compile time target for CSP rules. You write something, that compiles to CSP .CSP is so god damn complicated. If you’re unfamiliar with who mike west is, he is a ā€œCSP authorā€. He works on CSP and decides the future of it
  • #36Ā SRI stands for sub resource integrity.
  • #37Ā HTTP Public Key pinning is an amazing header. HPKP means that clients who receive a valid HPKP header can ONLY talk to the HTTPS site that produces the public key signatures found in the HPKP header. This leads to a lot of operational issues.
  • #38Ā HTTP Public Key pinning is an amazing header. HPKP means that clients who receive a valid HPKP header can ONLY talk to the HTTPS site that produces the public key signatures found in the HPKP header. This leads to a lot of operational issues.
  • #39Ā This is a new RFC and webappsec spec. Brand new. It is a way for websites to request passwords and log you in from the password manager that chrome has. In my opinion, it is something chrome is going to double down on and try to put lastpass and other similar password managers out of business.
  • #40Ā HSTS doesn’t get enough credit as a tough security header. It is one of the most common security headers, and it causes an unbelievable amount of operational issues. It is very tough. People think of HSTS as kind of a necessity these days. But it’s actually not that easy. Google chrome expects you to have ā€œinclude subdomainsā€ set to true, so all subdomains are also supporting HTTPS. This is not usually the case This is a picture of uber having to get themselves removed from the HSTS preload list. Tough stuff. They added include subdomains, broke their site, and had to get themselves removed. That’s very sad.
  • #41Ā Usable security. Web Application Security RFCs are not for web application security experts, they should be for average developers. WebAppSec specs are consumed by the web. They are immediately consumed by weirdo’s like me, but they are eventually consumed by regular, non security, developers. They should be written with them in mind. This is what I want and this will have a big impact in helping people not make mistakes and allow session stealing on their website. There is nobody making sure that the people making webappsec specs, The people making CSP, HSTS, HPKP, are making something that can actually be consumed by the outside world. Their work is consumed by millions of dev, and their work is a contract that some new feature will exist in the years to come in browsers, so they need more eyes.
  • #42Ā Who remembers OpenSSL? Does anyone use OpenSSL? I don’t think they do… I’m only kidding
  • #43Ā TLS was plagued with numerous problems over the years. Numerous really neat vulnerabilities. Some were only possible to find using formal methodologies, and some were more obviou, like heartbleed. I really like what tls1.3 authors did recently. Im not a tls expert by any means, fair warning. The TLS people limited decisions of people who would be using it. There are only a few supported ciphersuites. This is a huge win. Don’t give people the opportunity to be insecure, because they will take it.
  • #46Ā Welcome to my talk