Introduction

Welcome to the third lesson of the "Securing your REST API application with TypeScript" course! In our previous lessons, we explored the basics of Cross-Origin Resource Sharing (CORS) and how to handle preflight requests. Now, we will focus on a crucial aspect of web security: enabling and customizing CORS with credentials for cross-origin cookie authentication. This lesson will guide you through the process of securely sharing cookies across different origins, which is essential for maintaining session state and authenticating users in a web application. Let's dive in! 🌟

Understanding Cookies and Web Authentication

Cookies play a vital role in web authentication by storing session information that allows users to remain logged in as they navigate a website. They are small pieces of data sent from a server and stored on a user's device. In cross-origin scenarios, sharing cookies becomes challenging due to security restrictions. Understanding how cookies work and their role in authentication is crucial for implementing secure cross-origin communication.

Cross-Origin Cookie Authentication: Concept and Implementation

Cross-origin cookie authentication refers to the process of using cookies for authentication when making requests between different origins (domains, ports, or protocols). By default, browsers don't send cookies in cross-origin requests due to security concerns such as:

  • Cross-Site Request Forgery (CSRF): Without proper restrictions, malicious sites could make requests to your API using the user's cookies, potentially performing unauthorized actions.
  • Information leakage: Cookies might contain sensitive information that shouldn't be accessible to third-party sites.
  • Privacy implications: User tracking across multiple domains could violate privacy expectations.

To enable cross-origin cookie sharing while addressing these security concerns, we need to configure both server and client sides:

  1. Server-side CORS configuration:

    • Setting credentials: true tells the server to include credentials in CORS responses
    • Using a specific origin instead of wildcard * ensures cookies are only shared with trusted domains
  2. Client-side fetch configuration:

    • Using credentials: 'include' explicitly instructs the browser to send cookies with cross-origin requests
  3. Proper cookie attributes:

    • SameSite=None allows cross-origin cookie sharing (overriding the default security protection)
    • Secure ensures cookies are only sent over HTTPS, preventing interception
    • HttpOnly prevents client-side JavaScript from accessing the cookie, protecting against XSS attacks
Pros and Cons of CORS with Credentials

Understanding when to enable CORS with credentials requires weighing its benefits against security implications:

Pros:

  • Session continuity: Enables session persistence across different domains or subdomains when a user navigates between them
  • Centralized authentication: Allows a dedicated authentication service to manage sessions for multiple applications
  • Familiar patterns: Maintains cookie-based authentication that developers and systems already understand
  • Seamless UX: Users don't need to re-authenticate when moving between related applications

Common Use Cases:

  • Microservice architectures where services run on different domains but need shared authentication
  • Single sign-on (SSO) systems where logging into one application should authenticate across multiple sites
  • API gateways that need to validate authentication before routing to multiple backend services
  • Frontend applications deployed on CDNs separate from their backend APIs (e.g., React app on Netlify communicating with API on Heroku)

Cons:

  • Increased attack surface: Enabling cross-origin cookies creates additional security considerations
  • Configuration complexity: Requires precise setup of CORS and cookie settings to avoid vulnerabilities
  • Browser compatibility: Some browser security features may limit functionality
  • Debugging challenges: Cross-origin cookie issues can be difficult to troubleshoot
CORS Credentials: Enabling Secure Cross-Origin Cookie Sharing

To securely share cookies across origins, we need to enable CORS with credentials. This involves configuring the server to allow cookies to be sent and received. The credentials option in CORS configurations is key to this process. Let's see how to set it up:

Code Logic Explained:

  • We import the cors middleware and CorsOptions type from the cors package
  • We define a function that takes an Express router as input
  • We create a CORS configuration object with several key settings:
    • origin: Specifies exactly which domain can access our resources. A specific origin must be used because wildcard * doesn't work with credentials
    • credentials: true: This crucial setting tells the server to include the Access-Control-Allow-Credentials: true header in responses
    • methods: Defines which HTTP methods are allowed for cross-origin requests
    • allowedHeaders: Specifies which headers can be included in requests
  • Finally, we apply this CORS configuration to our Express router
Setting a Session Cookie

In a real-world application, you would typically set a session cookie when a user logs in. Here's a more realistic example:

Cookie Attributes Explained:

  • sessionId=${sessionId}: The actual cookie with a dynamically generated UUID
  • HttpOnly: Prevents JavaScript from accessing the cookie, protecting against XSS attacks
  • Max-Age=3600: Sets the cookie to expire in one hour (3600 seconds)
  • SameSite=None: Required for cross-origin cookie sharing - tells the browser it's OK to send this cookie in cross-site requests
  • Secure: Ensures the cookie is only sent over HTTPS connections, required when using SameSite=None
  • Path=/: Makes the cookie available across your entire domain
Checking the Session Cookie

Instead of complex cookie parsing code, here's a more straightforward approach to verify sessions:

How to test this in practice:

Using curl from the command line:

Mitigating Security Risks

To mitigate security risks associated with cross-origin cookie authentication, it's essential to follow best practices:

  • Always specify a non-wildcard origin in CORS configurations.
  • Use secure cookie attributes like HttpOnly, Secure, and SameSite.
  • Consider alternative authentication methods, such as token-based authentication, to enhance security.

By implementing these practices, you can significantly reduce the risk of unauthorized access and protect your application from potential attacks.

Conclusion and Next Steps

In this lesson, we explored the importance of enabling and customizing CORS with credentials for secure cross-origin cookie authentication. We examined the concepts, pros and cons, and common use cases for this approach. As you move forward, practice implementing these concepts in your projects to reinforce your understanding. In the next lesson, we'll continue to enhance the security of your TypeScript REST API. Keep up the great work! 🚀

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal