Skip to content

security(dashboards): scope copied widgets to the copier's app access (24.05) - #7857

Open
ar2rsawseen wants to merge 1 commit into
release.24.05from
backport/dashboards-copy-widget-app-scope-2405
Open

security(dashboards): scope copied widgets to the copier's app access (24.05)#7857
ar2rsawseen wants to merge 1 commit into
release.24.05from
backport/dashboards-copy-widget-app-scope-2405

Conversation

@ar2rsawseen

@ar2rsawseen ar2rsawseen commented Jul 29, 2026

Copy link
Copy Markdown
Member

Backport of the master fix in #7858 to release.24.05.

Not a clean cherry-pick: this branch never received the January 2026 pentest fix (c27fd19e2d0), so plugins/dashboards/api/api.js imported only validateUser and had no widget app filtering at all. The guard is therefore introduced here rather than replaced, which makes this branch the more exposed of the two targets.

What changes

Dashboard permissions are intentionally separate from app permissions, so a dashboard may be shared with a user who cannot read the apps its widgets reference. Copying such a dashboard, however, made the copier the owner of the copied widgets, and owners have edit rights — so a view-only recipient could rewrite a borrowed widget's query and read more of that app than the dashboard owner chose to show them.

  • Copying a dashboard now skips any widget referencing an app the copier cannot read. Widgets with no apps, such as notes, still copy.
  • add-widget validates the widget's app ids against the creator's access and rejects unauthorized ones rather than silently stripping them.
  • Widget app lists are normalized to a real array of 24-character hex ids, so a value that is array-like but not an Array cannot be stored and then read back through .length/[i] by fetchWidgetApps and the /dashboard/data handlers.
  • update-widget keeps the apps a widget already references — the dashboard owner delegated that by granting edit access — but checks app ids being newly added against the editor's own access.

Tests

plugins/dashboards/tests.js gains four cases, identical to the master branch: the copy chain, the array-like injection, add-widget for an unreadable app, and a positive case confirming copy still works for a user who can read the apps.

Verified locally: npx eslint plugins/dashboards/ and node --check pass. The plugin suite itself runs in CI (test-api-plugins).

Note for reviewers

The CHANGELOG entry went under the current 24.05.51 heading rather than being appended to the 24.05.50 "backport of #7535" Security Fixes block, since this is a separate fix. Happy to consolidate if you prefer.

🤖 Generated with Claude Code

Backport of the master fix. This branch never received the January 2026 pentest
fix (c27fd19), so it had no widget app filtering at all - dashboards/api.js
imported only validateUser. On this branch the issue is therefore reachable
without any sharing or copying: any authenticated member could create their own
dashboard, add a widget with apps set to an arbitrary app id, and read that
app's analytics through /o/dashboard/data.

Dashboard permissions are intentionally separate from app permissions, so a
dashboard may be shared with a user who cannot read the apps its widgets point
at. Copying such a dashboard, however, made the copier the OWNER of the copied
widgets, and owners have edit rights, letting a view-only recipient rewrite a
borrowed widget's query and read more of that app than the dashboard owner chose
to show them.

Changes, matching master:

- Copying a dashboard skips any widget referencing an app the copier cannot
  read. Widgets with no apps, such as notes, still copy.
- add-widget validates the widget's app ids against the creator's access and
  rejects unauthorized ones instead of storing them.
- Widget app lists are normalized to a real array of 24 character hex ids, so an
  array-like value such as {length: 1, "0": "<app id>"} cannot be stored and
  then read back through .length/[i] by fetchWidgetApps and the /dashboard/data
  handlers.
- update-widget keeps the apps a widget already references, since the dashboard
  owner delegated that by granting edit access, but checks app ids being newly
  added against the editor's own access.

Regression tests cover the reported copy chain, the array-like injection, adding
a widget for an unreadable app, and that copying still works for a user who can
read the apps.

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 29, 2026 19:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants