Cross-origin resource sharing (CORS) is a security relaxation measure that needs to be implemented in some APIs in order to let web browsers access them. However, when CORS is enabled by a back-end developer some security analysis needs to be done in order to ensure you’re not relaxing your server security too much. The problem usually arises when you allow resource sharing for every resource rather than for just specific ones.
We’ll take a look at some of the security risks of implementing CORS. First, it’s important to get a basic understanding of what CORS is, how it works, and how you can use security relaxation measures without leaving yourself vulnerable.
What is CORS?
The first step in understanding CORS is knowing how some security features of web browsers work. By default, web browsers do not allow AJAX requests to servers other than the site you’re visiting. This is called the same-origin policy and it’s an important part of the web security model. In fact, the same-origin policy is deployed to over a billion devices all over the world and has proven to have a solid track record in terms of exploitation.
Having said that, there are ways to bypass the same-origin policy and CORS is one of the most common methods of relaxing server security. CORS will allow you to specify who or what can access your endpoint on the server side. So when will you need to implement CORS?
Well, let’s say you’re a mail-sending service and you have a website called yourwebsite.com.
Your website may allow users to log in and configure a set of options. After a bit, the user chooses to send an e-mail and this triggers an AJAX request to yourwebsite.com/send. So far so good.
Now imagine your mail-sending API is in api.yourwebsite.com. This is where it gets a little trickier because the same-origin policy will block the AJAX request. You want to enable AJAX requests from yourwebsite.com and one way to do that is using CORS.
A Security Risk
Continuing with the example, now, let’s look at another scenario:
In your mail-sending API, api.yourwebsite.com, you decided to let everyone access your API instead of only yourwebsite.com. Is this harmful?
Well, it depends on how you implemented the authentication for mail sending. If you are using authentication based on session cookies, you probably shouldn’t allow CORS requests by everyone. A malicious website can issue e-mail sending requests to api.yoursebsite.com via an AJAX request without the specific permission of your user.
If the user has valid session cookies in their browser, they will be used to authenticate on api.yoursebsite.com and that would lead to unwanted e-mail sending. In most cases, dangerous requests will be “preflighted,” which means the domain needs to be approved before they can even send a request. This will prevent any malicious activities from happening.
One of the reasons a request might be preflighted is because they used a method other than GET, HEAD or POST. Another reason is that a request uses a custom HTTP header, such as ‘My-Custom-Header: foo’.
Is CORS a Bad Thing?
As with superpowers, it’s all about knowing how to use it. Therefore, CORS is not necessarily a bad thing. We’ve seen in many cases that CORS has legitimate use, and this is why it was invented and made a web standard in the first place. However, you need to be aware of the CORS configuration you set up in your server and the side effects this has on security.
What Do I Need to Take into Account?
Basically, you need to distinguish:
- Who has a legitimate need to access? Maybe it’s only a specific website or a small set of websites that need access. If so, list them. To put it in another way, you add specific websites to a “white list” of accepted domains.
- Do all endpoints need to be exposed? Take a look at your different endpoints and you might see different legitimate use cases for them that require different CORS configurations.
- What are the side effects for data providing endpoints? Some endpoints, typically the GET verb endpoints, will provide data but not alter anything in the state of your server (won’t alter the authentication state or the stored data). For these endpoints, analyze if the data you are providing is confidential and if the allowed CORS origins have a legitimate reason to ask for it.
- And the effects for data altering endpoints? Other endpoints, typically the POST/DELETE/PUT verb endpoints, will provide data but also alter the state of your server. In this case, the risk is higher since CORS could be used to trigger unintended actions, such as modify user data, alter login details, send e-mails, etc.
- What about 3rd party services? If you need to provide an API to 3rd parties, it’s good that you implement authorization it in a way that requires user consent. For example, OAuth allows you authorize third party websites and applications and requires explicit consent of the user.
As you can see from the examples we covered, it is possible that your back-end server actually needs CORS in order to operate properly. Maybe even you want to open some of your server data to anyone who wants to use it in the world, but do not fall into the trap of copy-pasting an “Access-Control-Allow-Origin” headers from somewhere else. It’s better to think twice about the needs for your client and what potentially malicious use of your API endpoint can be done.
At Mobile Jazz, we have a strong security background and can help you to improve and secure your website or mobile app. If you’d like to know more, get in touch.