View Source SafeURL (SafeURL v1.0.0)
SafeURL
is library for mitigating Server Side Request
Forgery vulnerabilities in Elixir. Private/reserved IP
addresses are blocked by default, and users can add
additional CIDR ranges to the blocklist, or alternatively
allow 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.
Examples
iex> SafeURL.allowed?("https://includesecurity.com")
true
iex> SafeURL.validate("http://google.com/", schemes: ~w[https])
{:error, :unsafe_scheme}
iex> SafeURL.validate("http://230.10.10.10/")
{:error, :unsafe_reserved}
iex> SafeURL.validate("http://230.10.10.10/", block_reserved: false)
:ok
# If HTTPoison is available:
iex> SafeURL.HTTPoison.get("https://10.0.0.1/ssrf.txt")
{:error, :unsafe_reserved}
iex> SafeURL.HTTPoison.get("https://google.com/")
{:ok, %HTTPoison.Response{...}}
Options
SafeURL
can be configured to customize and override
validation behaviour by passing the following options:
:block_reserved
- Block reserved/private IP ranges. Defaults totrue
.:blocklist
- List of CIDR ranges to block. This is additive with:block_reserved
. Defaults to[]
.:allowlist
- List of CIDR ranges to allow. If specified, blocklist will be ignored. Defaults to[]
.:schemes
- List of allowed URL schemes. Defaults to["http, "https"]
.:dns_module
- Any module that implements theSafeURL.DNSResolver
behaviour. Defaults toDNS
from the:dns
package.:detailed_error
- Return specific error if validation fails. If set tofalse
,validate/2
will return{:error, :restricted}
regardless of the reason. Defaults totrue
.
If :block_reserved
is true
and additional hosts/ranges
are supplied with :blocklist
, both of them are included in
the final blocklist to validate the address. If allowed
ranges are supplied with :allowlist
, all blocklists are
ignored and any hosts not explicitly declared in the allowlist
are rejected.
These options can be set globally in your config.exs
file:
config :safeurl,
block_reserved: true,
blocklist: ~w[100.0.0.0/16],
schemes: ~w[https],
dns_module: MyCustomDNSResolver
Or they can be passed to the function directly, overriding any global options if set:
iex> SafeURL.validate("http://10.0.0.1/", block_reserved: false)
:ok
iex> SafeURL.validate("https://app.service/", allowlist: ~w[170.0.0.0/24])
:ok
iex> SafeURL.validate("https://app.service/", blocklist: ~w[170.0.0.0/24])
{:error, :unsafe_blocklist}
Summary
Functions
Validate a string URL against a blocklist or allowlist.
Alternative method of validating a URL, returning result tuple instead of booleans.
Types
Functions
Validate a string URL against a blocklist or allowlist.
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 allowlist/blocklist.
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/", allowlist: ~w[10.0.0.0/8])
true
Options
See Options
section above.
Alternative method of validating a URL, returning result tuple 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 an error tuple with a
specific reason. If :detailed_error
is set to false
, the error is always
{:error, :restricted}
.
Examples
iex> SafeURL.validate("https://includesecurity.com")
:ok
iex> SafeURL.validate("http://10.0.0.1/")
{:error, :unsafe_reserved}
iex> SafeURL.validate("http://10.0.0.1/", allowlist: ~w[10.0.0.0/8])
:ok
Options
See Options
section above.