To evaluate the source code of the application and find the root cause of the vulnerability, we need to evaluate the /weather
endpoint, as /weather
is the endpoint allowing us to perform SSRF vulnerability.
To interactively attach the shell inside docker, use the following command:
docker exec -it ssrf /bin/bash
The source code of /weather
endpoint is as follows: (the source code is listed in main.py
file):
@app.route('/weather')
def fetch():
content = ""
# Get the 'url' parameter from the request
url = request.args.get('url')
country = request.args.get('country')
response = requests.get(url)
if response.status_code == 200:
try:
j = json.loads(response.text)
if "description" not in j and "wind" not in j:
raise ValueError("")
content = f"Temperature of {country}"
content += "\nDescription: " + j['description']
content += "\nWind:" + j['wind']
except Exception as e:
content = response.text
return render_template('search.html', content=content)
Bug
Provided
url
parameter is not checked or sanitised before rendering on the web page i.e. anyurl
which is accessible by the web server can be passed and rendered on the web page.
To mitigate the same, we can validate the url
parameter or just pass the country value from the website. Let’s try to mitigate using first approach, the SSRF safe source code is as follows:
from urllib.parse import urlparse
@app.route('/weather')
def fetch():
content = ""
# Get the 'url' parameter from the request
url = request.args.get('url')
country = request.args.get('country')
domain = urlparse(url).netloc
if domain != "goweather.xyz":
return render_template('search.html', content="Error")
response = requests.get(url)
if response.status_code == 200:
try:
j = json.loads(response.text)
if "description" not in j and "wind" not in j:
raise ValueError("")
content = f"Temperature of {country}"
content += "\nDescription: " + j['description']
content += "\nWind:" + j['wind']
except Exception as e:
content = response.text
return render_template('search.html', content=content)
Let’s verify that existence of the vulnerability by accessing the website hosted at http://127.0.0.1:80
.
http://127.0.0.1:5000/weather?url=http://127.0.0.1:80
We have successfully mitigated the SSRF vulnerability by validating the allowed domain name in the request parameters.
With this we are at the end of this series where we have learned about Server Side Request Forgery (SSRF) concept, a sample vulnerable application and it’s mitigation method.