Server-Side Request Forgery (SSRF)
What does this mean ?
A Server-Side Request Forgery (SSRF) attack includes an attacker misusing server capabilities to access or manipulate resources. The attacker chooses an application that enables data imports from URLs or allows them to read data from URLs. URLs may be altered by either replacing them with new ones or messing with URL path traversal.
What can happen ?
A successful SSRF attack can frequently result in unauthorized activities or data access within the company, either within the susceptible application itself or on other back-end systems with which the program can connect. In rare cases, the SSRF vulnerability may allow an attacker to execute arbitrary commands.
An SSRF vulnerability that establishes connections to external third-party systems may result in malicious forward attacks that appear to be launched by the business hosting the vulnerable application.
Recommendation
- Whitelisting the IP addresses or DNS names that your application requires is a good way to avoid SSRF.
- To prevent response information from reaching the cybercriminal, ensure that the answer obtained matches what was expected.
- Allow just these URL types if your application relies entirely on HTTPS or HTTP to originate queries.
Sample Code
Vulnerable :
using System.IO;
using System.Net;
using Microsoft.AspNetCore.Mvc;
namespace WebApplicationDotNetCore.Controllers
{
public class MainController : Controller
{
public IViewResult Index()
{
return View();
}
public IViewResult ReadContentOfURL(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); // Vulnerable
}
}
}
Non Vulnerable :
using System.Linq;
using System.IO;
using System.Net;
using Microsoft.AspNetCore.Mvc;
namespace WebApplicationDotNetCore.Controllers
{
public class MainController : Controller
{
public IViewResult Index()
{
return View();
}
private readonly string[] acceptedList = { "www.abc.com", "abc.com" };
public IViewResult ReadContentOfURL(string url)
{
URI remoteUrl = new Uri(url);
string remoteHost = remoteUrl.Host;
if (!acceptedList.Contains(remoteHost))
{
return BadRequest();
}
}
}
}
Vulnerable :
private static String fetchRemoteObj(String loc) throws Exception {
URL url = new URL(loc);
URLConnection conn = url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String body = reader.lines().collect(Collectors.joining());
return body;
}
Non Vulnerable :
private static String fetchRemoteObject(String loc) throws Exception {
URL url = new URL(loc);
if (!url.getHost().endsWith(".abc.com") ||
!url.getProtocol().equals("http") &&
!url.getProtocol().equals("https")) {
throw new Exception("Forbidden source");
}
URLConnection conn = url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String body = reader.lines().collect(Collectors.joining());
return body;
}