View Source SafeURL (SafeURL v0.1.0)
SafeURL
is library for mitigating Server Side Request
Forgery vulnerabilities in Elixir. Private/reserved IP
addresses are blacklisted by default, and users can add
additional CIDR ranges to blacklist, or alternatively
whitelist specific CIDR ranges to which the application is
allowed to make requests.
You can use allowed?/2
or validate/2
to check if a
URL is safe to call, or just call it directly via get/4
which will validate it automatically before calling, and
return an error if it is not.
Examples
iex> SafeURL.allowed?("https://includesecurity.com")
true
iex> SafeURL.validate("http://google.com/", schemes: ~w[https])
{:error, :restricted}
iex> SafeURL.validate("http://230.10.10.10/")
{:error, :restricted}
iex> SafeURL.validate("http://230.10.10.10/", blacklist_reserved: false)
:ok
iex> SafeURL.get("https://10.0.0.1/ssrf.txt")
{:error, :restricted}
iex> SafeURL.get("https://google.com/")
{:ok, %HTTPoison.Response{...}}
Options
SafeURL
can be configured to customize and override
validation behaviour by passing the following options:
:blacklist_reserved
- Blacklist reserved/private IP ranges. Defaults totrue
.:blacklist
- List of CIDR ranges to blacklist. This is additive with:blacklist_reserved
. Defaults to[]
.:whitelist
- List of CIDR ranges to whitelist. If specified, blacklists will be ignored. Defaults to[]
.:schemes
- List of allowed URL schemes. Defaults to["http, "https"]
.
If :blacklist_reserved
is true
and additional hosts/ranges
are supplied with :blacklist
, both of them are included in
the final blacklist to validate the address. If whitelisted
ranges are supplied with :whitelist
, all blacklists are
ignored and any hosts not explicitly declared in the whitelist
are rejected.
These options can be set globally in your config.exs
file:
config :safeurl,
blacklist_reserved: true,
blacklist: ~w[100.0.0.0/16],
schemes: ~w[https]
Or they can be passed to the function directly, overriding any global options if set:
iex> SafeURL.validate("http://10.0.0.1/", blacklist_reserved: false)
:ok
iex> SafeURL.validate("https://app.service/", whitelist: ~w[170.0.0.0/24])
:ok
iex> SafeURL.validate("https://app.service/", blacklist: ~w[170.0.0.0/24])
{:error, :restricted}
Link to this section Summary
Link to this section Functions
Specs
Validate a string URL against a blacklist or whitelist.
This method checks if a URL is safe to be called by looking at its scheme and resolved IP address, and matching it against reserved CIDR ranges, and any provided whitelist/blacklist.
Returns true
if the URL meets the requirements,
false
otherwise.
Examples
iex> SafeURL.allowed?("https://includesecurity.com")
true
iex> SafeURL.allowed?("http://10.0.0.1/")
false
iex> SafeURL.allowed?("http://10.0.0.1/", whitelist: ~w[10.0.0.0/8])
true
Options
See Options
section above.
Specs
get(binary(), Keyword.t(), HTTPoison.headers(), Keyword.t()) :: {:ok, HTTPoison.Response.t()} | {:error, :restricted}
Validate a URL and execute a GET request using HTTPoison
.
If the URL is safe, this function will execute the request using
HTTPoison
, returning the result directly. Otherwise, it will
return {:error, :restricted}
.
headers
and httpoison_options
will be passed directly to
HTTPoison
when the request is executed.
See allowed?/2
for more details on URL validation.
Examples
iex> SafeURL.get("https://10.0.0.1/ssrf.txt")
{:error, :restricted}
iex> SafeURL.get("https://google.com/")
{:ok, %HTTPoison.Response{...}}
iex> SafeURL.get("https://google.com/", schemes: ~w[ftp])
{:error, :restricted}
Options
See Options
section above.
Specs
Alternative method of validating a URL, returning atoms instead of booleans.
This calls allowed?/2
underneath to check if a URL is safe to
be called. If it is, it returns :ok
, otherwise
{:error, :restricted}
.
Examples
iex> SafeURL.validate("https://includesecurity.com")
:ok
iex> SafeURL.validate("http://10.0.0.1/")
{:error, :restricted}
iex> SafeURL.validate("http://10.0.0.1/", whitelist: ~w[10.0.0.0/8])
:ok
Options
See Options
section above.