
Démontre l'exploitation de SSRF via une divergence de parsing d'URL entre urllib.parse et requests, incluant un service vulnérable et un script d'exploitation PoC.
# vulnerable_service.py - Validates URL with urllib.parse, fetches with requests
from flask import Flask, request
import requests
import urllib.parse
app = Flask(__name__)
def is_allowed_url(url):
parsed = urllib.parse.urlparse(url)
# Only allow http://localhost and http://127.0.0.1
return parsed.hostname in ('localhost', '127.0.0.1')
@app.route('/fetch')
def fetch():
url = request.args.get('url')
if not is_allowed_url(url):
return "Blocked", 403
# Fetch with requests (different parser)
r = requests.get(url, timeout=5)
return r.text
if __name__ == '__main__':
app.run(port=5000)
Un service utilise urllib.parse.urlparse de Python pour valider les URL, mais les récupère ensuite avec la bibliothèque requests. Les divergences dans la façon dont les deux parseurs traitent les caractères spéciaux (comme @) permettent à un attaquant de contourner la liste blanche et d'accéder à des ressources internes.
urlparse considère que [email protected] a pour nom d'hôte localhost (la partie avant @ est le nom d'utilisateur), tandis que requests interprète l'hôte comme evil.com.pip install flask requests
python vulnerable_service.py
python exploit_ssrf_parser_diff.py