From 5ef0efbc6cf1092a431ca5823f6ac6ed91161f61 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Thu, 27 Oct 2016 04:09:25 -0700 Subject: [PATCH 1/2] Rename SafeCurl.scala to SafeURL.scala The examples weren't working for me unless I did this --- src/com/includesecurity/safeurl/{SafeCurl.scala => SafeURL.scala} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/com/includesecurity/safeurl/{SafeCurl.scala => SafeURL.scala} (100%) diff --git a/src/com/includesecurity/safeurl/SafeCurl.scala b/src/com/includesecurity/safeurl/SafeURL.scala similarity index 100% rename from src/com/includesecurity/safeurl/SafeCurl.scala rename to src/com/includesecurity/safeurl/SafeURL.scala From 37c59ba1e875a9dbff3acab0bb1235707fdb3da3 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Thu, 27 Oct 2016 04:10:07 -0700 Subject: [PATCH 2/2] Filter IPv6 addresses by default We can't safely support IPv6 with our default blacklist since even hosts on the intranet will usually have globally-routable addresses. Add a flag to disable IPv6 support and enable it by default. Since we handle this in `resolve()` by filtering IPv6 addresses and raising a `UnknownHostException` when all addresses were IPv6 we maintain API compatibility with previous versions of SafeURL. --- .../includesecurity/safeurl/Configuration.scala | 3 +++ src/com/includesecurity/safeurl/SafeURL.scala | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/com/includesecurity/safeurl/Configuration.scala b/src/com/includesecurity/safeurl/Configuration.scala index c9c3352..4abcd4a 100644 --- a/src/com/includesecurity/safeurl/Configuration.scala +++ b/src/com/includesecurity/safeurl/Configuration.scala @@ -53,6 +53,9 @@ class Configuration { /** Do secure redirects, revalidate each redirect location first. */ var secureRedirects: Boolean = true + /** Support IPv6, disabled by default since the default blacklist relies on NAT for security */ + var supportIPv6: Boolean = false + /** The maximum number of redirects SaveCurl will follow. */ var maxRedirects: Int = 20 diff --git a/src/com/includesecurity/safeurl/SafeURL.scala b/src/com/includesecurity/safeurl/SafeURL.scala index e4f60b1..8b9fbe4 100644 --- a/src/com/includesecurity/safeurl/SafeURL.scala +++ b/src/com/includesecurity/safeurl/SafeURL.scala @@ -92,8 +92,18 @@ object SafeURL { * @param host hostname or IP address to resolve * @return an array of IP addresses the hostname/IP resolves to */ - private def resolve(host: String): Array[String] = { - InetAddress.getAllByName(host) map (_.getHostAddress) + private def resolve(host: String, cfg: Configuration = defaultConfiguration): Array[String] = { + var hosts = InetAddress.getAllByName(host) + if (!cfg.supportIPv6) { + val v4Hosts = hosts filter (_.isInstanceOf[Inet4Address]) + if (v4Hosts.isEmpty && !hosts.isEmpty) { + // Treat IPv6-only results as if there was a lookup error, + // doesn't seem to be a way to force an IPv4-only lookup. + throw new UnknownHostException(host + ": Name or service not known"); + } + hosts = v4Hosts + } + hosts map (_.getHostAddress) } /** Check if the given IP address lies within the subnet given in CIDR notation. @@ -259,7 +269,7 @@ object SafeURL { } // Validate the IP - val ips = resolve(host) + val ips = resolve(host, cfg) for (ip <- ips) { // Note: Doing it this way means that when IP whitelisting is active, // every IP a given hostname resolves to must be in the whitelist.