CVE-2025-5874
Redash <=10.1.0/25.1.0 getattr Handler in python.py allows sandbox escape.
- CVSS 1.2
- CWE-264
- Design Defects
- Remote
A vulnerability was found in Redash up to 10.1.0/25.1.0. It has been rated as critical. This issue affects the function run_query of the file /query_runner/python.py of the component getattr Handler. The manipulation leads to sandbox issue. The exploit has been disclosed to the public and may be used. The vendor was contacted early about this disclosure but did not respond in any way.
- CWE
- CWE-264
- CVSS base score
- 1.2
- Published
- 2025-06-09
- OWASP
- A08 Software and Data Integrity Failures
- Orthogonal defect classification
- Algorithm
- Code defect classification
- Incorrect Functionality
- Category
- Design Defects
- Subcategory
- Insecure Parsing or Deserialization
- Accessibility scope
- Remote
- Impact
- Arbitrary Code Execution
- Affected component
- Python
- Fixed by upgrading
- Yes
Solution
Upgrade to a version later than 10.1.0/25.1.0. Check for official Redash security advisories for patched versions.
Vulnerable code sample
import json
import traceback
from redash.query_runner import *
from redash.utils import json_dumps
class Python(BaseQueryRunner):
@classmethod
def configuration_schema(cls):
"""Vulnerable function that demonstrates the security issue."""
return {
"type": "object",
"properties": {
"pythonVersion": {
"type": "string",
"title": "Python Version",
"default": "3"
}
},
"required": ["pythonVersion"]
}
@classmethod
def type(cls):
"""Vulnerable function that demonstrates the security issue."""
return "python"
def run_query(self, query, user):
"""Vulnerable function that demonstrates the security issue."""
try:
globals_context = {
"data": None,
"json": json,
"json_dumps": json_dumps,
"user": user,
"getattr": getattr
}
# Simulate the vulnerable scenario using `getattr` to access potentially unsafe attributes.
# This is a simplified example; the actual vulnerability in Redash might have involved a more complex interaction.
try:
# This is an example, the actual vulnerability was in how getattr was handled
# and allowed access to unintended or restricted attributes/functions.
result = eval(query, globals_context)
except Exception as e:
return None, str(e)
if isinstance(result, (dict, list)):
columns = []
if isinstance(result, dict):
if result:
columns = [{"name": key, "type": "string"} for key in result.keys()]:
elif isinstance(result, list) and result:
first_element = result[0]
if isinstance(first_element, dict):
columns = [{"name": key, "type": "string"} for key in first_element.keys()]:
data = {'rows': result, 'columns': columns}
json_data = json_dumps(data)
return json_data, None
else:
return None, "Query result must be a list or a dict."
except Exception:
return None, traceback.format_exc()Patched code sample
# Disclaimer: This code is a simplified example to illustrate the principles
# of mitigating the vulnerability described in CVE-2025-5874.
# It may not be an exact representation of the actual Redash codebase or vulnerability.
# It is intended for educational purposes only and should not be used in
# production environments without thorough review and adaptation.
import ast
import builtins
import inspect
import io
import sys
import types
def secure_run_query(query, allowed_modules=None, allowed_functions=None):
"""
Securely executes a Python query within a restricted environment.
Args:
query (str): The Python query string to execute.
allowed_modules (list, optional): A list of allowed modules. Defaults to None.
allowed_functions (list, optional): A list of allowed built-in functions. Defaults to None.
Returns:
tuple: A tuple containing (result, error) where result is the output
of the query (as a string) and error is any exception raised.
"""
if allowed_modules is None:
allowed_modules = [] # Explicitly define a safe default
if allowed_functions is None:
allowed_functions = []
# Whitelist approach: Only allow what's explicitly permitted.
# This is safer than trying to blacklist dangerous items.
safe_builtins = {
name: getattr(builtins, name)
for name in allowed_functions
if hasattr(builtins, name)
}
# Custom namespace for the execution environment.
safe_globals = {
'__builtins__': safe_builtins # Restrict built-in functions
}
for module_name in allowed_modules:
try:
module = __import__(module_name)
safe_globals[module_name] = module
except ImportError as e:
return None, f"Error importing module {module_name}: {e}"
# Redirect standard output to capture the query's result.
old_stdout = sys.stdout
redirected_output = io.StringIO()
sys.stdout = redirected_output
try:
# Compile the query using ast to check for syntax errors.
code = compile(query, '<string>', 'exec')
# Execute the query within the safe namespace.
exec(code, safe_globals) # nosec
result = redirected_output.getvalue()
except Exception as e:
result = None
return None, str(e) # Capture and return the error.
finally:
# Restore standard output.
sys.stdout = old_stdout
return result, NonePayload
import os
os.system('touch /tmp/pwned')
Cite this entry
@misc{vaitp:cve20255874,
title = {{Redash <=10.1.0/25.1.0 getattr Handler in python.py allows sandbox escape.
}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2025},
note = {VAITP Python Vulnerability Dataset, entry CVE-2025-5874},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2025-5874/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
