Rust CSRF Protection
Guide: Examples and
How to Enable It

stackhawk

StackHawk|September 14, 2021

Rust CSRF explained: what it means, faulty code example, cargos that prevent it, and most importantly how to enable protection for Rust apps.

Cross-site request forgery (CSRF) attacks are elaborate schemes by hackers to carry out a wide range of forgery requests within unsuspecting users' online accounts. These requests can be financial transactions, stealthy account coup d'état campaigns, or even just the deletion of sensitive data. With so many people invested in cryptocurrency (often built on the Rust-lang Ethereum client), the threat of Rust CSRF attacks can cost millions of dollars at a time.

This post explores how liable Rust applications are to CSRF attacks and includes attack examples, vulnerability analysis, and prevention advice. Let's get started by clarifying the concept before we turn our focus to remedies.

Rust CSRF: The Concept

Although Rust has a lot of robustness built into its syntax and methods, whenever you use it on the back end of web applications, it falls victim to CSRF attacks. This is because, by design, this breed of attack takes advantage of HTTP requests and the fact that any new tab of an application you open once you log in inherits the same session variables. This holds even when you click a link to the signed-in app via a different source (usually SMS or email).

Typically, here's how the con plays out:

  1. A hacker crafts a malicious request targeting users of one particular Rust application.

  2. They then send out an SMS communication to a user list scrapped from the same application.

  3. Once a user clicks a link to the target application, a communication laced with the payload ensues.

  4. Upon opening said email leading to the browser, the request executes with no extra effort from the legitimate user.

Because the requests are executed after the user has logged in, they're thus a form of forgery. Some attacks will ask the user to log in with a valid password before the request takes shape. This cuts the typical process by a step and makes it more potent. For size, CSRF bounties cash out anywhere between $3,000 to $25,000, depending on the severity and the discovery company's profile.

CSRF in Action

CSRF relies on HTTP requests, which implies that it targets web applications. For Rust, that means either you're building your web apps with a framework, or some areas behind the interface have the raw language elements. Either way, here are a few examples of CSRF attacks in action.

HTTP URL Targeting

This happens when an attacker realizes that the link in the browser contains state-altering values. State, in this scenario, can be something as simple as a profile's preferences, or even sensitive data like bank transaction requests.

HTTPS://mywebsite.com/user/846329/session_id:3756320/&auth846329=true/%action=update/user_profile/lang=sp/

The fact that this link is directly telling the server what to do is one hint that changes can be effected from the front end through forgery. In such a case, the hacker will take their time studying the processes and nomenclature on the back end. So much that when they have a working request, the server takes it as a genuine instance from the source code. In this case, that'd be an easy injection into the link, resulting in one like this:

HTTPS://mywebsite.com/user/846329/session_id:3756320/&auth846329=true/%action=update/user_profile/tansfer_amount=5000/%check=true/receipient_account=627384/sendPoP=false

At this point, this may start to sound a little like Rust XSS. However, there is a huge difference. You'll be keen to know that the code injected here is targeting parts of the application that the user will not see—in particular, state on the database side. XSS, on the other hand, aims to plant content on the page that the user is currently viewing.

Form Variables Manipulation

Let's assume you decide to use one of the frameworks we alluded to earlier (we'll look at Rocket) to create a Rust web application. On that front, the easiest implementation of a form that collects user input and then posts it to action would look like this:

use rocket::request::Form;
use rocket::http::RawStr;

#[derive(FromForm)]
struct UserInput<'f> {
    // The raw, undecoded value. You _probably_ want `String` instead.
    value: &'f RawStr
}

#[post("/submit", data = "<user_input>")]
fn submit_task(user_input: Form<UserInput>) -> String {
    format!("Your value: {}", user_input.value)
}
//code from the open source installation instance of Rocket: A Rust framework

Here the default RawStr struct is part of how data is handled. This means there are plenty of creative ways a hacker can penetrate the process. For instance, since the collector form is visible, more values can be suggested to it to pass commands to the back ends. By nature, the RawStr struct doesn't sanitize any inputs, making the planning stage of an attack much easier. One can create a matrix of allowable input, which adds up to an elaborate learning process of an account's possible states.

Deleting an account (that has such a form as the conveyor belt of state-altering variables) would be as easy as passing an extra assignment with the user input.

#[post("/submit", data = "<user_input>"/account_active=0)]

With these two demonstrations in mind, let's quickly look at some preventive measures for Rust CSRF.

Rust CSRF Prevention

When it comes to protecting your rust applications from CSRF attacks, you're better off using cargos from the official Rust library.

These present themselves as cargos and sometimes specific libraries depending on what you need to secure. With that said, let's assume you absolutely had to craft your own Rust CSRF fix. In this case, it would take some studying of the vulnerability.

Sticking to our examples, the URL vulnerability can be solved by either coding in patches on your own or applying site-wide middleware. Let's explore both implementations below.

How to Enable Rust CSRF Protection

Best practice would have you explore the various Rust cargos available as patches for the possibility of a CSRF attack. However, if you insist, you can add some logic to your code so that the example loopholes don't catch you unaware.

To start with, the URL forgery loophole can be sealed by encrypting variables in the URL. This means the cookies, tokens, and any other framework-generated variables go through authenticity checks before they make it to the server. You can achieve this by deploying the csrf crate into your project.

Here's a look at a simple implementation of this library (from its documentation).

Rust CSRF Protection Guide - Picture 1 image

Rust csrf cargo implementation.

Long story short, the csrf library generates a cookie-token pair that should match every authentication attempt later passed to the server.

When looking at the form manipulation vulnerability, your best bet is to experiment with a couple of cargo options that provide a blanket solution to CSRF. A particularly effective solution is the Rust iron_csrf library.

In addition to HTTP request protection, the iron_crsf checks all CRUD processes emanating from forms and APIs in Rust applications. It effectively sanitizes all POST, PATCH, PUT, DELETE, and other verbs you might think to implement within your Rust application.

Add Automated Security Testing to Your Pipeline for Free

Conclusion: Catch CSRF During CI

So far we've been assuming that your application is already in production. We then examined just how an unassuming URL can be the doorway for hackers to run malicious requests on your server. Unsanitized forms and APIs are also common gateways for hackers to carry out CSRF attacks on rust applications. The patches we explored act as remediating measures to already active risks, with the iron_csrf middleware being capable of covering most vulnerability points.

Have it known that hackers aim to make the most from any vulnerability. As such, it's best to put up preventive measures to cancel out vulnerabilities before they go into production.

This is where scanning software comes in handy as part of your continuous integration (CI) check. StackHawk automatically checks for newly introduced sources of vulnerabilities in your code. This happens as your team adds new features through version control. StackHawk gives you a chance to rectify CSRF doorways before they mature into breaches.

This post was written by Taurai Mutimutema. Taurai is a systems analyst with a knack for writing, which was probably sparked by the need to document technical processes during code and implementation sessions. He enjoys learning new technology and talks about tech even more than he writes.


StackHawk  |  September 14, 2021