Issue Summary
- Vulnerability Type: Mass Assignment / Improper Input Handling (CWE-915)
- Affected Component: VisualizationResource.post (/api/visualizations/)
- Affected Version: Redash 1.0.0 -> 26.08.0-dev
- Severity: Low
Technical Description
The VisualizationResource.post endpoint handles updates to visualization objects by accepting a JSON payload and stripping only id and query_id using a blocklist approach:
kwargs.pop("id", None)
kwargs.pop("query_id", None)
The filtered payload is then passed directly to self.update_model(), which iteratively calls setattr(model, k, v) without validating whether k is a permissible model attribute:
def update_model(self, model, updates):
for k, v in updates.items():
setattr(model, k, v)
Because Python objects rely on dynamic attribute assignment, an attacker can supply arbitrary JSON keys to overwrite internal model state (e.g., __dict__, foreign keys, or privileged flags). Relying on a blocklist rather than an allowlist creates a Mass Assignment vulnerability.
Impact
An authenticated user with edit_query permissions can:
- Overwrite protected internal ORM attributes (e.g.,
__dict__, created_at, org_id).
- Cause database state corruption or bypass access controls by modifying unauthorized model fields.
- Potentially trigger Remote Code Execution (RCE) or denial of service depending on downstream object serialization or lifecycle hooks.
Full technical explanation is described here
Steps to Reproduce
- Authenticate as a user with edit_query permissions.
- Intercept or construct an HTTP POST request to /api/visualizations/<VISUALIZATION_ID>.
- Send a JSON body containing an unexpected internal property (e.g., {"
__dict__": {...}} or unintended foreign key attributes):
POST /api/visualizations/123 HTTP/1.1
Host: target.redash.local
Authorization: Bearer <API_TOKEN>
Content-Type: application/json
{
"name": "Updated Vis",
"type": "CHART",
"__dict__": {}
}
Observe that setattr modifies internal object properties, resulting in unvalidated model persistence upon models.db.session.commit().
This is a bug as users have a lot more access than they should have, leading to corrupted variables updating to the database.
An appropriate solution would be to create a whitelist by dynamically fetch the class variables (removing internal ones), and excluding the id, query_id fields
Technical details:
Checked on Redash version: 26.08.0-dev
Issue Summary
Technical Description
The VisualizationResource.post endpoint handles updates to visualization objects by accepting a JSON payload and stripping only id and query_id using a blocklist approach:
The filtered payload is then passed directly to self.update_model(), which iteratively calls setattr(model, k, v) without validating whether k is a permissible model attribute:
Because Python objects rely on dynamic attribute assignment, an attacker can supply arbitrary JSON keys to overwrite internal model state (e.g.,
__dict__, foreign keys, or privileged flags). Relying on a blocklist rather than an allowlist creates a Mass Assignment vulnerability.Impact
An authenticated user with edit_query permissions can:
__dict__, created_at, org_id).Full technical explanation is described here
Steps to Reproduce
__dict__": {...}} or unintended foreign key attributes):Observe that setattr modifies internal object properties, resulting in unvalidated model persistence upon models.db.session.commit().
This is a bug as users have a lot more access than they should have, leading to corrupted variables updating to the database.
An appropriate solution would be to create a whitelist by dynamically fetch the class variables (removing internal ones), and excluding the
id, query_idfieldsTechnical details:
Checked on Redash version: 26.08.0-dev