Whoogle Search Cross-site Scripting vulnerability
Description
Whoogle Search is a self-hosted metasearch engine. In versions 0.8.3 and prior, the element method in app/routes.py does not validate the user-controlled src_type and element_url variables and passes them to the send method which sends a GET request on lines 339-343 in requests.py. The returned contents of the URL are then passed to and reflected back to the user in the send_file function on line 484, together with the user-controlled src_type, which allows the attacker to control the HTTP response content type leading to a cross-site scripting vulnerability. An attacker could craft a special URL to point to a malicious website and send the link to a victim. The fact that the link would contain a trusted domain (e.g. from one of public Whoogle instances) could be used to trick the user into clicking the link. The malicious website could, for example, be a copy of a real website, meant to steal a person’s credentials to the website, or trick that person in another way. Version 0.8.4 contains a patch for this issue.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
whoogle-searchPyPI | < 0.8.4 | 0.8.4 |
Affected products
1- Range: < 0.8.4
Patches
13a2e0b262e4aValidate urls in `element` and `window` endpoints
1 file changed · +26 −7
app/routes.py+26 −7 modified@@ -4,8 +4,10 @@ import json import os import pickle +import re import urllib.parse as urlparse import uuid +import validators from datetime import datetime, timedelta from functools import wraps @@ -420,13 +422,18 @@ def config(): config_disabled = ( app.config['CONFIG_DISABLE'] or not valid_user_session(session)) + + name = '' + if 'name' in request.args: + name = os.path.normpath(request.args.get('name')) + if not re.match(r'^[A-Za-z0-9_.+-]+$', name): + return make_response('Invalid config name', 400) + if request.method == 'GET': return json.dumps(g.user_config.__dict__) elif request.method == 'PUT' and not config_disabled: - if 'name' in request.args: - config_pkl = os.path.join( - app.config['CONFIG_PATH'], - request.args.get('name')) + if name: + config_pkl = os.path.join(app.config['CONFIG_PATH'], name) session['config'] = (pickle.load(open(config_pkl, 'rb')) if os.path.exists(config_pkl) else session['config']) @@ -444,7 +451,7 @@ def config(): config_data, open(os.path.join( app.config['CONFIG_PATH'], - request.args.get('name')), 'wb')) + name), 'wb')) session['config'] = config_data return redirect(config_data['url']) @@ -463,6 +470,8 @@ def imgres(): @session_required @auth_required def element(): + empty_gif = base64.b64decode( + 'R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==') element_url = src_url = request.args.get('url') if element_url.startswith('gAAAAA'): try: @@ -475,6 +484,11 @@ def element(): src_type = request.args.get('type') + # Ensure requested element is from a valid domain + domain = urlparse.urlparse(src_url).netloc + if not validators.domain(domain): + return send_file(io.BytesIO(empty_gif), mimetype='image/gif') + try: file_data = g.user_request.send(base_url=src_url).content tmp_mem = io.BytesIO() @@ -485,8 +499,6 @@ def element(): except exceptions.RequestException: pass - empty_gif = base64.b64decode( - 'R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==') return send_file(io.BytesIO(empty_gif), mimetype='image/gif') @@ -504,6 +516,13 @@ def window(): root_url=request.url_root, config=g.user_config) target = urlparse.urlparse(target_url) + + # Ensure requested URL has a valid domain + if not validators.domain(target.netloc): + return render_template( + 'error.html', + error_message='Invalid location'), 400 + host_url = f'{target.scheme}://{target.netloc}' get_body = g.user_request.send(base_url=target_url).text
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
12- github.com/advisories/GHSA-phg6-44m7-hx3hghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-22417ghsaADVISORY
- securitylab.github.com/advisories/GHSL-2023-186_GHSL-2023-189_benbusby_whoogle-searchghsaADVISORY
- github.com/benbusby/whoogle-search/blob/92e8ede24e9277a5440d403f75877209f1269884/app/request.pyghsax_refsource_MISCWEB
- github.com/benbusby/whoogle-search/blob/92e8ede24e9277a5440d403f75877209f1269884/app/routes.pyghsax_refsource_MISCWEB
- github.com/benbusby/whoogle-search/blob/92e8ede24e9277a5440d403f75877209f1269884/app/routes.pyghsax_refsource_MISCWEB
- github.com/benbusby/whoogle-search/blob/92e8ede24e9277a5440d403f75877209f1269884/app/routes.pyghsax_refsource_MISCWEB
- github.com/benbusby/whoogle-search/blob/92e8ede24e9277a5440d403f75877209f1269884/app/routes.pyghsax_refsource_MISCWEB
- github.com/benbusby/whoogle-search/blob/92e8ede24e9277a5440d403f75877209f1269884/app/routes.pyghsax_refsource_MISCWEB
- github.com/benbusby/whoogle-search/commit/3a2e0b262e4a076a20416b45e6b6f23fd265aedaghsax_refsource_MISCWEB
- github.com/pypa/advisory-database/tree/main/vulns/whoogle-search/PYSEC-2024-19.yamlghsaWEB
- securitylab.github.com/advisories/GHSL-2023-186_GHSL-2023-189_benbusby_whoogle-search/mitrex_refsource_CONFIRM
News mentions
0No linked articles in our index yet.