Cross-Site Request Forgery - Elixir

Cross-Site Request Forgery - Elixir

Need

Prevent attackers from tricking authenticated users into executing actions without their consent.

Context

  • Usage of Elixir 1.13.0 for functional programming and building scalable applications
  • Usage of Plug for request management
  • Usage of Plug.CSRFProtection for protecting against CSRF attacks
  • Usage of cookie-based sessions for application authentication and state management

Description

Non compliant code

        defmodule VulnerableController do
  use Plug.Router

  plug :match
  plug :dispatch

  post "/change_password" do
    # Change password logic here
    User.change_password(conn.params["new_password"])
    send_resp(conn, 200, "Password changed successfully")
  end
end
        
        

The endpoint '/change_password' changes the password of a user based on the provided parameters. However, it does not validate the authenticity of the request, making it vulnerable to CSRF attacks. An attacker can create a malicious site that sends a POST request to this endpoint, changing the password without the user's knowledge or consent.

Steps

  • Import the Plug.CSRFProtection package in your controller.
  • Add a plug to the controller to use CSRF protection.
  • Ensure every form or action that modifies state on the server includes the CSRF token in the request.

Compliant code

        defmodule SecureController do
  use Plug.Router
  use Plug.CSRFProtection

  plug :match
  plug :dispatch
  plug :put_secure_browser_headers

  post "/change_password" do
    with :ok <- check_csrf_token(conn) do
      User.change_password(conn.params["new_password"])
      send_resp(conn, 200, "Password changed successfully")
    else
      _ -> send_resp(conn, 403, "Invalid CSRF token.")
    end
  end
end
        
        

This solution introduces CSRF protection by including Plug.CSRFProtection in the controller. This plug will automatically generate and validate CSRF tokens in the session. Any state-modifying operation will require a valid CSRF token, otherwise, a 'Invalid CSRF token.' message is returned to the client, thus preventing CSRF attacks.

References