logo

Database

Server-side Request Forgery (SSRF)

Need

To prevent unauthorized network requests performed by the server due to user input manipulation

Context

• Usage of Elixir (v1.11+) for building scalable and fault-tolerant applications

• Usage of Plug.Adapters.Cowboy2.Http module for handling HTTP requests in Elixir

• Usage of httpc module for making HTTP requests

Description

1. Non compliant code

defmodule MyAppWeb.PageController do
  use MyAppWeb, :controller

  def external_request(conn, %{"url" => url} = _params) do
    {:ok, response} = :httpc.request(url)
    text(response)
  end
end

In this insecure code, the Elixir/Phoenix application accepts a URL from user input and makes a HTTP request to it using the :httpc.request function. This is a server-side request forgery (SSRF) vulnerability, as a malicious user could manipulate the input to make the server perform unauthorized requests.

2. Steps

• Don't allow user input to dictate the server's network requests directly.

• If user input must be used to make network requests, implement strict input validation and only allow requests to approved domains.

• Consider using a safe-list of approved domains that the server can make requests to.

3. Secure code example

defmodule MyAppWeb.PageController do
  use MyAppWeb, :controller

  def external_request(conn, %{"url" => url} = _params) do
    if validate_url(url) do
      {:ok, response} = :httpc.request(url)
      text(response)
      send_resp(conn, 400, "Invalid URL")...

In this secure code, the application still accepts a URL from user input. However, it now validates the input with a validate_url function, which checks if the input is part of a list of approved domains. This mitigates the SSRF vulnerability by preventing the server from making requests to unapproved domains.