Skip to main content
added 303 characters in body
Source Link
paj28
  • 34.7k
  • 10
  • 103
  • 139

This is the code I'm currently using:

if(!url.getProtocol().startsWith("http"))
    throw new Exception();
InetAddress inetAddress = InetAddress.getByName(url.getHost());
if(inetAddress.isAnyLocalAddress() || inetAddress.isLoopbackAddress() || inetAddress.isLinkLocalAddress())
    throw new Exception();
HttpURLConnection conn = (HttpURLConnection)(url.openConnection());
conn.setInstanceFollowRedirects(false);
conn.connect();
IOUtils.copy(conn.getInputStream(), out);

It enforces HTTP or HTTPS, forbids local addresses, and disables redirects. However, it still has the TOCTOU (time of check, time of use) flaw.

Edit (2022): The best solution these days is to use a library specifically designed to safely fetch untrusted URLs. For example, Advocate for Python. I don't have a link to a similar Java project to hand; if someone can add this, I would appreciate it!

This is the code I'm currently using:

if(!url.getProtocol().startsWith("http"))
    throw new Exception();
InetAddress inetAddress = InetAddress.getByName(url.getHost());
if(inetAddress.isAnyLocalAddress() || inetAddress.isLoopbackAddress() || inetAddress.isLinkLocalAddress())
    throw new Exception();
HttpURLConnection conn = (HttpURLConnection)(url.openConnection());
conn.setInstanceFollowRedirects(false);
conn.connect();
IOUtils.copy(conn.getInputStream(), out);

It enforces HTTP or HTTPS, forbids local addresses, and disables redirects. However, it still has the TOCTOU (time of check, time of use) flaw.

This is the code I'm currently using:

if(!url.getProtocol().startsWith("http"))
    throw new Exception();
InetAddress inetAddress = InetAddress.getByName(url.getHost());
if(inetAddress.isAnyLocalAddress() || inetAddress.isLoopbackAddress() || inetAddress.isLinkLocalAddress())
    throw new Exception();
HttpURLConnection conn = (HttpURLConnection)(url.openConnection());
conn.setInstanceFollowRedirects(false);
conn.connect();
IOUtils.copy(conn.getInputStream(), out);

It enforces HTTP or HTTPS, forbids local addresses, and disables redirects. However, it still has the TOCTOU (time of check, time of use) flaw.

Edit (2022): The best solution these days is to use a library specifically designed to safely fetch untrusted URLs. For example, Advocate for Python. I don't have a link to a similar Java project to hand; if someone can add this, I would appreciate it!

Bounty Ended with 50 reputation awarded by Anders
Source Link
paj28
  • 34.7k
  • 10
  • 103
  • 139

This is the code I'm currently using:

if(!url.getProtocol().startsWith("http"))
    throw new Exception();
InetAddress inetAddress = InetAddress.getByName(url.getHost());
if(inetAddress.isAnyLocalAddress() || inetAddress.isLoopbackAddress() || inetAddress.isLinkLocalAddress())
    throw new Exception();
HttpURLConnection conn = (HttpURLConnection)(url.openConnection());
conn.setInstanceFollowRedirects(false);
conn.connect();
IOUtils.copy(conn.getInputStream(), out);

It enforces HTTP or HTTPS, forbids local addresses, and disables redirects. However, it still has the TOCTOU (time of check, time of use) flaw.