logo

Stored Cross-Site Scripting (XSS) - Elixir


Need

Prevent persistent injection of malicious scripts into application fields


Context

  1. Usage of Elixir 1.13.0 for building scalable and fault-tolerant applications
  2. Usage of Ecto for database query and manipulation
  3. Usage of Phoenix.HTML for building HTML
  4. Usage of application state management for dynamic content generation

Description

Insecure Code Example

defmodule VulnerableController do
  use MyWeb, :controller

  def create(conn, %{"message" => message_params}) do
    %Message{} |> Message.changeset(message_params) |> Repo.insert()
    redirect(conn, to: message_path(conn, :index))
  end

  def index(conn, _params) do
    messages = Repo.all(Message)
    render(conn, "index.html", messages: messages)
  end
end

This vulnerable code saves user-provided messages directly to the database without sanitizing the input first. Then it uses this data to generate dynamic content on the index page. An attacker can store a malicious script in the message, which will be executed by the user's browser when the index page is loaded.

Steps

  1. Use the functions provided by the Phoenix.HTML package to sanitize user input before storing it in the database.
  2. Replace raw database data with the 'h' function from Phoenix.HTML when generating dynamic content.

Secure Code Example

defmodule SecureController do
  use MyWeb, :controller
  use Phoenix.HTML

  def create(conn, %{"message" => message_params}) do
    sanitized_params = %{"content" => h(message_params["content"])}
    %Message{} |> Message.changeset(sanitized_params) |> Repo.insert()
    redirect(conn, to: message_path(conn, :index))
  end

  def index(conn, _params) do
    messages = Repo.all(Message)
    render(conn, "index.html", messages: messages)
  end
end

The secure code uses the 'h' function from the Phoenix.HTML package to sanitize user-provided input before saving it to the database. This ensures that any HTML special characters in the input are escaped, preventing them from being interpreted as part of the HTML markup. This mitigates the stored XSS vulnerability by preventing scripts from being stored and later executed in the user's browser.


References

  • 010 - Stored Cross-Site Scripting (XSS)

  • Last updated

    2023/09/18