Avoiding CSRF with Remix

Rate this content
Bookmark
This video talk explains how to avoid Cross-Site Request Forgery (CSRF) attacks using Remix. CSRF attacks involve tricking the user into performing unintended actions on a web application. The video covers the use of HTML form elements and the SameSite attribute on cookies to mitigate these attacks. Additionally, it discusses the token-based approach to CSRF protection, which includes generating a unique token for each session and form, transmitting it with the form, and securely validating it on the server side. The SameSite attribute helps by controlling whether cookies are sent with cross-site requests, but it is not enough on its own. The talk also covers the synchronize token pattern, which involves a four-step process for secure token validation. Finally, it emphasizes the importance of using timing-safe equals for token validation to prevent timing attacks. The video highlights the usage of secure random keys for generating CSRF tokens and explains how to use the 'random bytes' package from the crypto library.

From Author:

Remix 'Data Writes' go back to the basics of the web when it comes to form submissions. But therein lies a trap if you're not careful - Cross site request forgery (CSRF) can rear its head. In this session we'll explore what CSRF is. How it can be exploited and what you can do to make sure your Remix application isn't vulnerable.

This talk has been presented at React Summit 2022, check out the latest edition of this React Conference.

FAQ

CSRF stands for Cross-Site Request Forgery.

In a CSRF attack, the attacker tricks the user into accessing a URL that performs an action using the user's existing session.

Yes, CSRF attacks can be performed using GET requests, but they can also be executed using POST requests by embedding a URL in an iframe with hidden dimensions.

The SameSite attribute in cookies can be set to 'lax' or 'strict' to control whether the browser sends cookies for requests originating from another domain. 'Lax' allows cookies for GET requests from other domains, while 'Strict' does not allow cookies for any requests from other domains.

No, setting the SameSite attribute is not enough to prevent CSRF attacks because only 93% of browsers support it. A token-based approach, known as the synchronize token pattern, is recommended.

The synchronize token pattern is a four-step process to prevent CSRF attacks. It involves generating a unique token per session and form, transmitting it with the form, sending it back when the form is submitted, and securely validating it on the server side.

To generate a unique token for CSRF protection, create a secure random seed per session, combine it with a private key and an identifier, and create an HMAC digest of the combination. Transmit this token with the form and validate it on the server side.

Secure random keys for CSRF tokens can be generated using the 'random bytes' package from the crypto library.

Using timing-safe equals is important for CSRF token validation to avoid timing attacks, which can exploit the time it takes to compare two values and potentially reveal sensitive information.

You can contact the speaker via the GitHub Discord server for the conference or message them on Twitter.

Lee Rowlands
Lee Rowlands
7 min
10 Jun, 2022

Comments

Sign in or register to post your comment.

Video Transcription

Available in Español: Evitando CSRF con Remix

1. Introduction to CSRF and Remix

Short description:

Welcome to my session on avoiding CSRF with Remix. CSRF stands for Cross-Site Request Forgery, where the attacker tricks the user into accessing a URL to perform an action using their existing session. Even if using post, an exploit can be achieved with an iframe and a separate URL. Remix helps protect against CSRF by thinking about actions in terms of HTML form elements. To avoid CSRF with Remix, set the same site attribute on cookies and consider using a token in addition to the attribute.

Hi and welcome to my session on avoiding CSRF with Remix. This is a lightning talk, so we're going to go through this in a pretty whirlwind fashion. So let's start up by talking about what CSRF is. Like most security exploits, it's got an acronym and it stands for Cross-Site Request Forgery. And in this scenario, basically the attacker tricks the user into accessing the URL and then this URL will perform an action using their existing session.

So a simple example, or perhaps the worst example, is an image with a URL and that URL performs an action. So before you say, no, I want to write code like this, I've seen this in apps that I've audited, and obviously the first thing the user is doing wrong here is they're using get to perform some sort of action. But equally, this kind of exploit can be achieved even if it's using post. And we do that by having an iframe with a hidden height and width, and that embeds a separate URL. And in that URL we have the form, the post to that endpoint, and we have an onload function that submits it the second the form is loaded.

So let's talk about Remix a bit. Remix gets you thinking about actions in terms of the building blocks of the web, which is the HTML form element. And if you've been building apps with JavaScript, you've probably been using things like Fetch or Axios, and in these scenarios, of course, it protects you. Unless, of course, you're using access, allow origin, you know, star, and you're allowing credentials to come through. And in that case, you're in the same boat. So because we're submitting forms again via straight up, you know, multi-part form data, we need to think about Cross-Site Request Forgery.

So let's have a look at a simple Remix form example. We've got a primitive form here with a text field and a Submit button. We've got some sort of loader to check the user has got authenticated session because Cross-Site Request Forgery does require these to be logged in. You know, you're performing an action using their existing session that they didn't intend to do. And so we're not going to go into the details here, but yeah, the loader is making sure the user's got a session. We've then got an action in our component that does some sort of write to the database or similar. Something that performs some sort of action that, you know, can't be reversed. So how do you avoid Cross-Site Request Forgery with Remix in this scenario? Well, the first thing you should do is set the same site attribute on your cookies. So you can set that to lax, which will mean the browser will only send the cookies if it's a get request coming from another domain. Or you can set it to strict, which means it won't send any cookies for any requests that originate from another domain. So you might need to check whether you're using some sort of authentication flow that redirects to other sites as to which is the most appropriate for your site. But unfortunately, according to OWASP, this isn't enough and we shouldn't replace having a token. And the main reason for that is that only 93% of browsers support the same site attribute at this stage. We're almost there.

2. CSRF Token Generation and Validation

Short description:

The token-based approach involves a four-step process: generating a unique token per session and form, transmitting it with the form, sending it back when the user submits the form, and securely validating it on the server side. To generate the token, secure random keys are generated, including a hash salt and a private key. The token is transmitted with the loader and returned in the loader data, which can be accessed in the form. Validation is done by regenerating the token and comparing it to the submitted version. If they don't match, an error is thrown.

Your app might have higher depending on your user's browser mix. So the token-based approach is commonly called synchronize the token pattern and it's basically a four step process.

The first thing is you have to generate a unique token per session, per form. You have to transmit that with the form. You have to send it back when the user submits the form and then you have to securely validate it on the server side.

So we start by generating some secure random keys. We generate a hash salt and this is something that you shouldn't store in your database. It should be on disk or environment variables so that if your database is compromised even then the hash salt is not leaked. You should also have a private key and both of these you can generate using the random bytes package from the crypto.

So the first step is to generate a unique random seed per session and so we do this by checking if the seed already exists in the session. If it does we use that. If it doesn't, we generate a new seed using again the random bytes function and we store that in the session. Then we need to generate a unique token for per session and identifier and in this scenario the identifier would be something unique for that form or operation and this prevents the same token being valid for two different operations and prevents token reuse.

So to do this we would take that hash, so we take our private key, we also take the seed and we combine the three together and we create a HMAC digest of that, which is basically a hash. It gives us a nice unique token. We have to transmit that token with the loader. The first thing we do is we generate the token and we return it in our loader data and that means we can then get that back in our form by using the route data. So we get our CRSF token from there and we transmit that in the form in our hidden field.

We then need to validate the code, so if we write a nice little utility function for validating it will regenerate the token based on the unique identifier and session and then it will compare the two using timing safe equals against the version that was submitted with the form. We use timing safe equals here to avoid timing attacks.

So how do we use this utility function? In our action, we can just call validate CRSF token using the value from the submitted form and if the two don't match then we throw an error.

That's a whirlwind tour of CSRF validation for Remix. If you've got any questions, please contact me via the GitHub Discord server for this conference or you can message me on Twitter.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Building Better Websites with Remix
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a web framework built on React Router that focuses on web fundamentals, accessibility, performance, and flexibility. It delivers real HTML and SEO benefits, and allows for automatic updating of meta tags and styles. It provides features like login functionality, session management, and error handling. Remix is a server-rendered framework that can enhance sites with JavaScript but doesn't require it for basic functionality. It aims to create quality HTML-driven documents and is flexible for use with different web technologies and stacks.
Don't Solve Problems, Eliminate Them
React Advanced Conference 2021React Advanced Conference 2021
39 min
Don't Solve Problems, Eliminate Them
Top Content
Kent C. Dodds discusses the concept of problem elimination rather than just problem-solving. He introduces the idea of a problem tree and the importance of avoiding creating solutions prematurely. Kent uses examples like Tesla's electric engine and Remix framework to illustrate the benefits of problem elimination. He emphasizes the value of trade-offs and taking the easier path, as well as the need to constantly re-evaluate and change approaches to eliminate problems.
Scaling Up with Remix and Micro Frontends
Remix Conf Europe 2022Remix Conf Europe 2022
23 min
Scaling Up with Remix and Micro Frontends
Top Content
This talk discusses the usage of Microfrontends in Remix and introduces the Tiny Frontend library. Kazoo, a used car buying platform, follows a domain-driven design approach and encountered issues with granular slicing. Tiny Frontend aims to solve the slicing problem and promotes type safety and compatibility of shared dependencies. The speaker demonstrates how Tiny Frontend works with server-side rendering and how Remix can consume and update components without redeploying the app. The talk also explores the usage of micro frontends and the future support for Webpack Module Federation in Remix.
Full Stack Components
Remix Conf Europe 2022Remix Conf Europe 2022
37 min
Full Stack Components
Top Content
RemixConf EU discussed full stack components and their benefits, such as marrying the backend and UI in the same file. The talk demonstrated the implementation of a combo box with search functionality using Remix and the Downshift library. It also highlighted the ease of creating resource routes in Remix and the importance of code organization and maintainability in full stack components. The speaker expressed gratitude towards the audience and discussed the future of Remix, including its acquisition by Shopify and the potential for collaboration with Hydrogen.
Remix Flat Routes – An Evolution in Routing
Remix Conf Europe 2022Remix Conf Europe 2022
16 min
Remix Flat Routes – An Evolution in Routing
Top Content
Remix Flat Routes is a new convention that aims to make it easier to see and organize the routes in your app. It allows for the co-location of support files with routes, decreases refactor and redesign friction, and helps apps migrate to Remix. Flat Folders convention supports co-location and allows importing assets as relative imports. To migrate existing apps to Flat Routes, use the Remix Flat Routes package's migration tool.
It's a Jungle Out There: What's Really Going on Inside Your Node_Modules Folder
Node Congress 2022Node Congress 2022
26 min
It's a Jungle Out There: What's Really Going on Inside Your Node_Modules Folder
Top Content
The talk discusses the importance of supply chain security in the open source ecosystem, highlighting the risks of relying on open source code without proper code review. It explores the trend of supply chain attacks and the need for a new approach to detect and block malicious dependencies. The talk also introduces Socket, a tool that assesses the security of packages and provides automation and analysis to protect against malware and supply chain attacks. It emphasizes the need to prioritize security in software development and offers insights into potential solutions such as realms and Deno's command line flags.

Workshops on related topic

Remix Fundamentals
React Summit 2022React Summit 2022
136 min
Remix Fundamentals
Top Content
Featured WorkshopFree
Kent C. Dodds
Kent C. Dodds
Building modern web applications is riddled with complexity And that's only if you bother to deal with the problems
Tired of wiring up onSubmit to backend APIs and making sure your client-side cache stays up-to-date? Wouldn't it be cool to be able to use the global nature of CSS to your benefit, rather than find tools or conventions to avoid or work around it? And how would you like nested layouts with intelligent and performance optimized data management that just works™?
Remix solves some of these problems, and completely eliminates the rest. You don't even have to think about server cache management or global CSS namespace clashes. It's not that Remix has APIs to avoid these problems, they simply don't exist when you're using Remix. Oh, and you don't need that huge complex graphql client when you're using Remix. They've got you covered. Ready to build faster apps faster?
At the end of this workshop, you'll know how to:- Create Remix Routes- Style Remix applications- Load data in Remix loaders- Mutate data with forms and actions
Back to the Roots With Remix
React Summit 2023React Summit 2023
106 min
Back to the Roots With Remix
Featured Workshop
Alex Korzhikov
Pavlik Kiselev
2 authors
The modern web would be different without rich client-side applications supported by powerful frameworks: React, Angular, Vue, Lit, and many others. These frameworks rely on client-side JavaScript, which is their core. However, there are other approaches to rendering. One of them (quite old, by the way) is server-side rendering entirely without JavaScript. Let's find out if this is a good idea and how Remix can help us with it?
Prerequisites- Good understanding of JavaScript or TypeScript- It would help to have experience with React, Redux, Node.js and writing FrontEnd and BackEnd applications- Preinstall Node.js, npm- We prefer to use VSCode, but also cloud IDEs such as codesandbox (other IDEs are also ok)
How to Solve Real-World Problems with Remix
Remix Conf Europe 2022Remix Conf Europe 2022
195 min
How to Solve Real-World Problems with Remix
Featured Workshop
Michael Carter
Michael Carter
- Errors? How to render and log your server and client errorsa - When to return errors vs throwb - Setup logging service like Sentry, LogRocket, and Bugsnag- Forms? How to validate and handle multi-page formsa - Use zod to validate form data in your actionb - Step through multi-page forms without losing data- Stuck? How to patch bugs or missing features in Remix so you can move ona - Use patch-package to quickly fix your Remix installb - Show tool for managing multiple patches and cherry-pick open PRs- Users? How to handle multi-tenant apps with Prismaa - Determine tenant by host or by userb - Multiple database or single database/multiple schemasc - Ensures tenant data always separate from others
Build and Launch a personal blog using Remix and Vercel
Remix Conf Europe 2022Remix Conf Europe 2022
156 min
Build and Launch a personal blog using Remix and Vercel
Featured Workshop
Robert Pop
Robert Pop
In this workshop we will learn how to build a personal blog from scratch using Remix, TailwindCSS. The blog will be hosted on Vercel and all the content will be dynamically served from a separate GitHub repository. We will be using HTTP Caching for the blog posts.
What we want to achieve at the end of the workshop is to have a list of our blog posts displayed on the deployed version of the website, the ability to filter them and to read them individually.
Table of contents: - Setup a Remix Project with a predefined stack- Install additional dependencies- Read content from GiHub- Display Content from GitHub- Parse the content and load it within our app using mdx-bundler- Create separate blog post page to have them displayed standalone- Add filters on the initial list of blog posts
0 to Auth in an hour with ReactJS
React Summit 2023React Summit 2023
56 min
0 to Auth in an hour with ReactJS
WorkshopFree
Kevin Gao
Kevin Gao
Passwordless authentication may seem complex, but it is simple to add it to any app using the right tool. There are multiple alternatives that are much better than passwords to identify and authenticate your users - including SSO, SAML, OAuth, Magic Links, One-Time Passwords, and Authenticator Apps.
While addressing security aspects and avoiding common pitfalls, we will enhance a full-stack JS application (Node.js backend + React frontend) to authenticate users with OAuth (social login) and One Time Passwords (email), including:- User authentication - Managing user interactions, returning session / refresh JWTs- Session management and validation - Storing the session securely for subsequent client requests, validating / refreshing sessions- Basic Authorization - extracting and validating claims from the session token JWT and handling authorization in backend flows
At the end of the workshop, we will also touch other approaches of authentication implementation with Descope - using frontend or backend SDKs.
Building High-Performance Online Stores with Shopify Hydrogen and Remix
React Advanced Conference 2023React Advanced Conference 2023
104 min
Building High-Performance Online Stores with Shopify Hydrogen and Remix
WorkshopFree
Alexandra Spalato
Alexandra Spalato
I. Introduction- Overview of Shopify Hydrogen and Remix- Importance of headless e-commerce and its impact on the industry
II. Setting up Shopify Hydrogen- Installing and setting up Hydrogen with Remix- Setting up the project structure and components
III. Creating Collections and Products- Creating collections and products using Hydrogen’s React components- Implementing a Shopping Cart- Building a shopping cart using Hydrogen’s built-in components
VI. Building the home page with Storyblok- Cloning the space and explaining how it works- Implementing Storyblok in the repo- Creating the Blok components- Creating the Shopify components- Implementing personalisation