Server-Side Request Forgery in Java
Vulnerable Example
The following represents one of a number of possible methods to fetch remote resources from a Java web application:
private static String fetchRemoteObject(String location) throws Exception {
URL url = new URL(location);
URLConnection connection = url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String body = reader.lines().collect(Collectors.joining());
return body;
}
There are at least two issues with this snippet of code:
-
A
java.net.URL
can represent many more schemes than just HTTP; for example, it can be used to fetch the local file by employing thefile://
protocol; -
No restriction whatsoever is enforced to include or exclude domains; this could be exploited to fetch internal resources, e.g., those that reside in
localhost
or in the internal network.
Prevention
Fetching a user-provided URL is quite a sensitive operation, especially if said user will eventually be able to read the response. In those cases, an allow list approach is advisable, i.e., only certain protocols/domains/paths/etc. are allowed to be requested; all other cases are to be rejected. The above code can be hardened by only allowing HTTP/S resources coming from specific subdomains:
private static String fetchRemoteObject(String location) throws Exception {
URL url = new URL(location);
if (!url.getHost().endsWith(".example.com") ||
!url.getProtocol().equals("http") &&
!url.getProtocol().equals("https")) {
throw new Exception("Forbidden remote source");
}
URLConnection connection = url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String body = reader.lines().collect(Collectors.joining());
return body;
}
References
OWASP - Server Side Request Forgery Acunetix - What is Server Side Request Forgery Dzone: The Server Side Request Forgery Vulnerability and How to Prevent It