Skip to content

VisualizationResource mass assignment #7781

Description

@HomiGrotas

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

  1. Authenticate as a user with edit_query permissions.
  2. Intercept or construct an HTTP POST request to /api/visualizations/<VISUALIZATION_ID>.
  3. 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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions