Prevention of unauthorized server-side requests to arbitrary domains
from django.http import HttpResponse
import requests
def get_external_data(request):
url = request.GET.get('url')
response = requests.get(url)
return HttpResponse(response.content)
In the above code, the
get_external_data
function is taking a URL from the request parameters and then using the
requests.get()
function to make a GET request to that URL. The response from this request is then returned to the user.
This is a classic case of Server-Side Request Forgery (SSRF) vulnerability. The application is taking an arbitrary URL from the user and making a request to that URL. This can be exploited by an attacker by providing a URL that points to an internal network resource that the server has access to but should not be exposed to the user. The server will fetch the content of that internal resource and send it back to the attacker.
For example, an attacker could provide a URL like
http://localhost:8000/admin
to access the Django admin panel or
http://169.254.169.254/latest/meta-data/
to access the metadata of an AWS EC2 instance, if the server is hosted on AWS.
This is a serious vulnerability as it allows an attacker to bypass firewalls and access internal network resources, which could lead to data exposure, data loss, or even remote code execution if the internal resource has a vulnerability that can be exploited through its HTTP interface.
from django.http import HttpResponse
import requests
# Define a list of trusted URLs
TRUSTED_URLS = ['http://trustedurl1.com', 'http://trustedurl2.com']
def get_external_data(request):
url = request.GET.get('url')
# Validate the URL
if url not in TRUSTED_URLS:
return HttpResponse('Invalid URL')
response = requests.get(url)
return HttpResponse(response.content)
The updated code includes a list of trusted URLs (
TRUSTED_URLS
). When a request is made to get external data, the URL provided in the request is checked against this list. If the URL is not in the list of trusted URLs, the function returns an HTTP response with the message 'Invalid URL'.
This way, we ensure that the server only makes requests to URLs that are known to be safe. This prevents Server-Side Request Forgery (SSRF) attacks, where an attacker could induce the server into making requests to an arbitrary domain.
This is a simple and effective way to prevent SSRF attacks, but it's not the only one. Other measures could include using a server-side proxy to make external requests, using a library or service that provides safe URL resolution and validation, or implementing a Content Security Policy (CSP) to limit the domains that the application can interact with.