Introduction
Welcome folks, today we will learn about a famous server-side attack, known as server-side request forgery (SSRF). In today's digital era, having a strong grasp of application security is crucial, given the complex threats that can endanger both personal and organisational data. One such threat is Server-Side Request Forgery (SSRF). This article will help you explain SSRF in an easy-to-understand manner, highlight real-world examples, provide practical advice on how to defend against such vulnerabilities, and delve into attacks which SSRF enables.
What is SSRF and how it works:
It refers to a security issue where an attacker deceives a web application or API into initiating requests towards internal services. This can result in unauthorised access, exposure of sensitive data, compromise of systems, and execution of malicious code. Attackers manipulate inadequate input checks to direct applications to undesirable internet destinations, bypassing protections like firewalls or VPNs.
Working Of SSRF Attack:
In an SSRF attack, the attacker manipulates the server into making HTTP requests to internal systems or external servers. They create a specially crafted URL which the server accesses, then sends the results back to the attacker.This exposes sensitive information or grants the attacker access to these resources. Due to the server's inherent trust in client requests, the attacker can circumvent security protocols and access restricted areas.
Example of a Vulnerable Python Code Snippet for SSRF:
The Python code snippet mentioned is designed to fetch and return the content of a URL specified by the user. The vulnerability in this code is explained as follows:
from flask import request
import urllib
@app.route('/proxy')
def proxy():
url = request.args["url"]
return urllib.request.urlopen(url).read()
Types of risks Enabled by SSRF:
SSRF can open the door to a whole lot of attacks, depending on the character of the application and the environment:
Types of SSRF
Implications of SSRF via CVE-2023-24329 in Python
A URL parsing or SSRF vulnerability in the Python programming language before 3.11.4 was announced on February 17, 2023, and assigned the ID CVE-2023–24329. The urllib.parse module, which has functions for disassembling URLs into their component parts and reassembling them into whole URLs, is the source of the problem.
Vulnerable Code Snippet:
Coming to the vulnerability, here is the screenshot of the vulnerable code snippet attached below. The code snippet allows blocking certain urls based on their scheme and host.
def safe_url_opener(input_link):
block_schemes = ["file", "gopher", "expect", "php", "dict", "ftp", "glob", "data"]
block_host = ["instagram.com", "youtube.com", "tiktok.com"]
input_scheme = urlparse(input_link).scheme
print("Input scheme is", input_scheme)
input_hostname = urlparse(input_link).hostname
print("Input hostname is", input_hostname)
if input_scheme in block_schemes:
print(GREEN+"Input scheme is forbidden"+ENDC)
return
if input_hostname in block_host:
print(GREEN+"Input hostname is forbidden"+ENDC)
return
try:
target = urllib.request.urlopen(input_link)
content = target.read()
print(content)
except Exception as e:
print("Error:", e)
Exploitation:
To replicate the given vulnerability, we would be using the following git repo by H4R335HR.
As per given screenshot, when entering the following payload with extra space: https://youtube.com. The check is bypassed. This vulnerability has affected millions of python repositories which simply allowed an extra space to be neglected when entering the user-controlled input.
Remediation:
Given the severity of CVE-2023-24329, it is strongly advised that Python be updated to the most recent version as soon as feasible. The fix was released in the following versions:
Therefore, patching Python to one of these releases will fix the security flaw and stop its exploitation.
For example:
# Upgrade Python in Ubuntu/Debian
sudo apt update
sudo apt install python3.11
# Upgrade Python in RHEL/CentOS
sudo yum update python3
If updating the Python runtime is not practicable, the vulnerability report suggests using string.lstrip() as a workaround:
from urllib.parse import urlparse
import string
url = string.lstrip(url)
parsed = urlparse(url)
Python Code Example for Preventing SSRF Attacks
To effectively counter SSRF threats, organisations need to adopt a vigilant security stance with proactive measures. Here are some key strategies to enhance your systems' defence against SSRF attacks:
Here is a straightforward Python example demonstrating how to mitigate SSRF by validating URLs against a predefined whitelist.
The code snippet prevents SSRF attacks through the following mechanisms:
from flask import request
import urllib
DOMAINS_WHITELIST = ['domain1.com', 'domain2.com']
@app.route('/proxy')
def proxy():
url = request.args["url"]
if urllib.parse.urlparse(url).hostname in DOMAINS_WHITELIST:
return urllib.request.urlopen(url).read()
Conclusion
In conclusion, tackling Server-Side Request Forgery (SSRF) vulnerabilities is key to keeping web applications safe. SSRF can be tricky as it allows attackers to trick a server into performing actions without permission. To guard against such threats, strong input validation, using allowlists, and correctly setting up server request handlers are crucial. By staying informed and applying these proactive security measures, developers and administrators can protect their systems from the serious risks associated with SSRF attacks. Let's continue to evolve and strengthen our defences as we navigate the complex landscape of cybersecurity.