Security Releases for Phoenix

A minor vulnerability has been disclosed for applications redirecting to URLs provided by user input. Only applications passing user input to Phoenix.Controller.redirect/2 are affected. For example, code such as the following is vulnerable to this disclosure:

redirect(conn, to: params["redirect"])     

We have released new Phoenix versions v1.0.6, v1.1.8, v1.2.3, and v1.3.0-rc.1 which addresses this issue. If you are unable to upgrade, a fix to use in your own application can be found below.

Disclosure

From day one, the Phoenix team designed Phoenix.Controller.redirect/2 to protect against redirects allowing user input to redirect to an external URL where your application code otherwise assumes a local path redirect. This is why the :to option is used for “local” URL redirects and why you must pass the :external option to intentionally allow external URLs to be redirected to. It has been disclosed that carefully crafted user input may be treated by some browsers as an external URL. An attacker can use this vulnerability to aid in social engineering attacks. The most common use would be to create highly believable phishing attacks. For example, the following user input would pass local URL validation, but be treated by Chrome and Firefox as external URLs:

http://localhost:4000/?redirect=/\nexample.com

Not all browsers are affected, but latest Chrome and Firefox will issue a get request for example.com and successfully redirect externally.

  • Versions affected: v1.0.0, v1.0.1, v1.0.2, v1.0.3, v1.0.4, v1.1.0, v1.1.1, v1.1.2, v1.1.3, v1.1.4, v1.1.5, v1.1,6, v1.2.0, v1.2.1, v1.3.0-rc.0
  • Versions fixed: v1.0.5+, v1.1.7+, v1.2.3+, v1.3.0-rc.1+
  • Author: Jeff Dileo
  • Thanks to: Jeff Dileo and his colleagues at the NCC Security Advisory Group

Temporary Fix

If you are able to update via mix and hex, simply run mix deps.update phoenix to jump on the latest point release with this fix. Those unable to upgrade can add the following function and import to their controllers:

import Phoenix.Controller, except: [redirect: 2]

def redirect(conn, opts) do
  to = opts[:to]

  if to && String.contains?(to, "\\") ->
    raise ArgumentError, "unsafe characters detected for local redirect in URL #{inspect to}"
  else
    Phoenix.Controller.redirect(conn, opts)
  end
end

Thank You

I would like to thank the NCC Group for reporting this vulnerability and working with us to harden the Phoenix and Plug code-bases.

NCC Group is a global expert in cyber security and risk mitigation,
working with businesses to protect their brand, value and reputation
against the ever-evolving threat landscape. Our Security Consulting
services leverage our extensive knowledge of current security
vulnerabilities, penetration testing techniques and software development
best practices to enable organizations to secure their applications
against ever-present threats. At NCC Group we can boast unrivaled talent
and recognized world-class security expertise. Bringing together best in
class security consultancies iSEC Partners, Intrepidus Group, Matasano,
NCC Group and NGS we have created one of the largest, most respected
security consultancies in the world.

14 Likes