Skip to content

Critical: RestrictedPython sandbox escape + command injection via script runner + SQLi x4 + SSRF + CSRF default-off (CWE-94, CWE-78, CWE-89, CWE-918) #7684

Description

@Proscan-one

Hi Redash team,

Found several issues, two of which are critical RCE vectors.

RestrictedPython sandbox escape (Critical)

In redash/query_runner/python.py at lines 317-319, raw getattr and setattr are assigned as the _getattr_/_setattr_ guards for RestrictedPython. This completely defeats the sandbox's security model — those guards are specifically what RestrictedPython relies on to prevent attribute access to dangerous objects.

Any user who can run Python queries can escape trivially: ().__class__.__bases__[0].__subclasses__() walks the class hierarchy to find os and call system(). Full RCE on the Redash server.

Command injection via script runner (Critical)

redash/query_runner/script.py:8-19 — when the script path is configured as *, the user's query text gets passed directly to subprocess.check_output(script, shell=True). Anything in the query box runs as a shell command on the server.

SQL injection in 4 query runners (High)

Four query runners interpolate user-controlled values into SQL without parameterization:

  • query_runner/__init__.py:283 — table names via % into select count(*)
  • query_runner/sqlite.py:45PRAGMA table_info("%s") with unescaped table name
  • query_runner/duckdb.py:90-96 — extension names via f-string into INSTALL/LOAD
  • query_runner/memsql_ds.py:76-93 — schema/table names via %

SSRF bypassing advocate protection (High)

query_runner/graphite.py:79-84 and several other runners (prometheus, clickhouse, elasticsearch) use raw requests.get() instead of the advocate-wrapped session. This bypasses the ENFORCE_PRIVATE_ADDRESS_BLOCK setting entirely — internal network access from any authenticated user.

CSRF disabled by default (High)

redash/settings/__init__.py:464ENFORCE_CSRF defaults to "false". The comment in the code acknowledges the risk but leaves it off. Any state-changing API call is vulnerable to cross-site request forgery out of the box.

The sandbox escape and command injection are the urgent ones — both give full server RCE to any user with query access.

— ProScan AppSec | proscan.one

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions