ZenSite EMS / ZenGrid — zensite-manager Security Patch v1.1.0
Release Information
| Field | Value |
|---|---|
| Version | v1.1.0 |
| Release Date | 2026-07-06 |
| Release Type | Security Patch |
| Urgency | Critical — immediate deployment required |
| Component | zensite-manager |
| Advisories | METER-SA-2026-001, METER-SA-2026-002 |
Summary
This release remediates two Critical-severity findings discovered during the authorised external penetration test conducted by Tousif Khan (2–5 June 2026): a cross-tenant data read via unvalidated realm parameter (C1) and a stored XSS via map asset-marker label (C2). It also delivers the SDL process improvements triggered by those findings (GitLab issues #20–#24).
All active tenants on the SaaS platform (https://orb.met3r.com) are affected by both findings. Deployment is mandatory.
Security Fixes
| Finding | Advisory | CVSS 3.1 Base | Severity | Resolution |
|---|---|---|---|---|
C1 — Cross-tenant read via unvalidated ?realm= parameter (Summary / Load modules) | METER-SA-2026-001 | 7.7 (Environmental 8.3) | Critical-tier | Realm now derived exclusively from validated bearer token principal; ?realm= query parameter rejected as authoritative tenant selector |
C2 — Stored XSS via map asset-marker label (innerHTML sink) | METER-SA-2026-002 | 8.7 (Environmental 9.1) | Critical | Marker label render path replaced with lit-html text binding; Content-Security-Policy: script-src 'self' header added to all responses |
C1 — Cross-tenant realm bypass
The custom Summary and Load module controllers derived the operating realm from ?realm= (attacker-controlled) rather than from the Keycloak JWT principal claim used by the core API. An authenticated user in any tenant could read asset maps and weekly report PDFs belonging to a different tenant with a single parameter substitution.
Fix: realmFromPrincipal(SecurityContext) (identical to AssetResource) is now the only authoritative realm source in all Summary and Load controllers. A cross-tenant request returns HTTP 403 before any data retrieval. Regression test added to CI (cross-tenant-isolation job blocks MR on failure).
C2 — Stored XSS via map marker label
The map widget rendered asset-marker labels via markerEl.innerHTML = … + attributeValue + …. A user with asset-edit permission could store a JavaScript payload that executed in the authenticated session of every user viewing any shared dashboard containing the widget, including administrators. No CSP was present to block inline script execution.
Fix: Marker label render path replaced with html`<span>${attributeValue}</span>` (lit-html text binding). Content-Security-Policy header with script-src 'self' (no 'unsafe-inline') deployed on all responses, providing defence in depth.
SDL Process Improvements
| GitLab Issue | Document Updated | Change |
|---|---|---|
| #20 | Doc 03 — Threat Model | Added "custom module realm bypass" attack vector under cross-tenant threat category |
| #21 | Doc 05 — Secure Coding Standard | Added rule: realm/tenant identity MUST be derived from validated principal; query parameters MUST NOT serve as authoritative tenant selectors. Added rule: innerHTML / insertAdjacentHTML with untrusted data are BANNED; use lit-html text bindings |
| #22 | Doc 04 — Design Review Checklist | Added item: new API modules must verify realm derivation from principal before merge; UI widgets receiving shared-endpoint data must confirm output encoding |
| #23 | Doc 07 — Security Testing Strategy | Added mandatory CI test: cross-realm API call with valid foreign token must return 403 on all summary/** and load/** endpoints |
| #24 | — | Audit of all ?realm= consumers in zensite-manager completed; affected endpoints enumerated and remediated |
Affected Components
| Component | Notes |
|---|---|
| zensite-manager — Summary module | C1 fix applied |
| zensite-manager — Load module | C1 fix applied |
| zensite-manager — Map widget (Dashboard) | C2 fix applied |
| zensite-manager — HTTP response headers | CSP header added (all routes) |
No other ZenSite stack components (TICK Stack, IAM/SSO, Backend Services, Device Adapters) are changed in this release.
Update Instructions
SaaS platform (orb.met3r.com): update applied automatically. No customer action is required beyond acknowledging the notification email.
Self-hosted deployments: pull the updated container image and redeploy. Verify the following after deployment:
GET /api/{realm}/summary/getAssetsForDashboard?realm=<other-realm>with a valid token returns 403.- HTTP response for any page includes
Content-Security-Policyheader withscript-src 'self'and no'unsafe-inline'. - Map widget marker labels render literal text — no HTML execution — when label values contain angle brackets.
Risks of Not Applying
- C1 unpatched: any authenticated user can read asset data and report PDFs of any other tenant with a single URL parameter change.
- C2 unpatched: any user with asset-edit permission can execute arbitrary JavaScript in the authenticated session of every dashboard viewer, including administrators. Combined with C1 this creates a full cross-tenant escalation path.
Support
- Security issues: report@met3r.com
- General support: contact your METER account representative