Prevention of unauthorized server-side requests to arbitrary domains
def fetch_data
url = params[:url]
response = Net::HTTP.get(URI.parse(url))
render json: response
end
In the above code, we have a function
fetch_data
that fetches some data from a URL. This URL is taken from the request parameters, which means it is user-controlled data.
This function uses the Ruby's
Net::HTTP.get
method to send a GET request to the URL specified in the request parameters. The server then responds with the data from the requested URL.
The vulnerability here is that the application server can be tricked into making requests to arbitrary domains. This is a Server-Side Request Forgery (SSRF) vulnerability. An attacker could potentially use this to probe internal network resources, perform attacks against other external systems, or induce the server into interacting with other services within its private network.
The problem arises because the application does not validate or restrict the
url
parameter. It directly uses this parameter to make HTTP requests. As a result, an attacker can provide any URL, including
localhost
or private IP addresses, causing the server to make requests to any server, including itself or other servers in the internal network.
def fetch_data
url = params[:url]
uri = URI.parse(url)
# Validate the URL
raise "Invalid URL" unless uri.is_a?(URI::HTTP) || uri.is_a?(URI::HTTPS)
# Whitelist of allowed domains
allowed_domains = ["www.trusteddomain1.com", "www.trusteddomain2.com"]
domain = uri.host
# Check if the domain is in the whitelist
raise "Forbidden request" unless allowed_domains.include?(domain)
response = Net::HTTP.get(uri)
render json: response
rescue => e
# Log the error and return a 400 bad request status
logger.error "Error fetching data: #{e.message}"
render json: { error: "Bad request" }, status: :bad_request
end
The updated code includes several measures to prevent Server-Side Request Forgery (SSRF) attacks:
1. URL Validation: The
URI.parse
method is used to parse the URL and ensure it is a valid HTTP or HTTPS URL. If the URL is not valid, an exception is raised.
2. Domain Whitelisting: A whitelist of allowed domains is defined. The domain of the input URL is extracted and checked against this whitelist. If the domain is not in the whitelist, an exception is raised.
3. Error Handling: If any error occurs during the execution of the method (such as an invalid URL or a forbidden request), the error is logged and a 400 bad request status is returned to the client. This helps to detect and respond to SSRF attempts.
These measures help to ensure that the application's server only makes requests to valid and trusted domains, thereby mitigating the risk of SSRF attacks.