What is CORS and how do we deal with it?
Before we begin, I would like to acknowledge the source of this content:
Cross-Origin Resource Sharing (CORS) is an HTTP-header-based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources.
CORS (Cross-Origin Resource Sharing) is an HTTP header-based mechanism.
It allows a server to specify other origins (domain, scheme, or port) from which the browser should allow loading resources, other than its own.
- By default, browsers apply the Same-Origin Policy for security reasons.
- This policy allows communication only if the protocol, host, and port number of the resources are the same.
However, since it is not feasible to strictly enforce this policy, a mechanism based on HTTP headers, called CORS, is provided to allow safe access to resources located elsewhere.
Browsers filter HTTP communication between resources originating from different places based on this CORS policy.
CORS Policy is Enforced by the Browser
It does not apply to server-to-server communication.
While it is possible for a server to block specific origins, the CORS policy itself is a mechanism implemented in the browser to protect users.
The CORS policy is determined by the server, but its enforcement is handled by the browser.
CORS: A Security Mechanism That Eases Development Rather Than Protecting Users
Since the Same-Origin Policy is applied by default in browsers, CORS allows developers to bypass SOP and communicate with other domains.
Client (Frontend)
HTTP requests may include credentials.
Credentials refer to cookies, authorization headers, or TLS client certificates.
The
credentials
property can take three values: "omit", "same-site", or "include."- omit: Do not include credentials in the request.
- same-site: The default value, credentials are included only for the same site.
- include: Include credentials even for different sites.
Example code:
fetch('<https://example.com/hello>', { method: 'GET', credentials: 'include' }) axios.get('<https://example.com/hello>', { withCredentials: true })
Server (Backend)
- The server needs to specify which origins, methods, and headers are allowed.
- Credentials must also be allowed.
Preflight Request
- Before sending the actual request, the browser internally sends a preflight request using the OPTIONS method to ask the server if it is safe to send the request based on CORS.
- In certain cases, defined as simple requests, a preflight request is not sent, but it is important to know that preflight requests exist.
- Many web frameworks handle the OPTIONS method through CORS middleware, but if not, you must handle the OPTIONS method directly.
Example code:
w.Header().Set("Access-Control-Allow-Origin", "<https://example.com>") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Authorization, Origin") w.Header().Set("Access-Control-Allow-Credentials", "true")
Access-Control-Allow-Origin
- Specifies the allowed origin.
- Setting it to
null
is prohibited, meaning it is not allowed.
Access-Control-Allow-Methods
- Specifies the allowed methods.
- Multiple methods can be allowed by separating them with commas.
Access-Control-Allow-Headers
- Specifies the headers that will be included in the actual request after the preflight request.
Access-Control-Allow-Credentials
- Determines whether the credentials set by the client should be exposed to the client-side code when included in the request.
- If any of Origin, Methods, or Headers is set to the wildcard (
), credentials will not be allowed.