OneUptime, Broken Access Control, CVE-2026-30920 (High)

Listen to this Post

The vulnerability, identified as CVE-2026-30920, resides in OneUptime’s GitHub App installation flow. The core issue is the application’s failure to validate the authenticity and authorization of the `state` parameter in the OAuth callback. The `state` parameter, which is simply a base64-encoded JSON string containing a `projectId` and userId, is not signed or cryptographically bound to the user’s session. When the callback endpoint `/api/github/auth/callback` receives this `state` along with an installation_id, it decodes the state, extracts the projectId, and directly updates the corresponding project’s database record with the new `installation_id` using a root-privileged database operation (isRoot: true). The server only checks for the presence of a `userId` in the decoded JSON, not its validity or whether the user is authorized to modify the specified project. This allows an attacker to craft a malicious `state` payload containing any target `projectId` (victim’s project UUID) and a dummy userId. When this is sent to the callback URL with an arbitrary `installation_id` (which could be the attacker’s own GitHub App installation or a bogus ID), the server overwrites the victim project’s GitHub App installation binding. Furthermore, subsequent vulnerable endpoints that handle repository enumeration and connection also lack proper authorization, allowing an attacker with a valid GitHub installation ID to list repositories and create `CodeRepository` records in any project, leading to unauthorized data binding and potential information disclosure .
Platform: OneUptime
Version: <10.0.19
Vulnerability: Access Control
Severity: High
date: 09 March 2026

Prediction: Already patched

What Undercode Say:

Analytics:

The vulnerability stems from trusting unsigned client-side data and missing server-side authorization checks.

Vulnerable Code Pattern (TypeScript/Node.js):

// INSECURE: Callback decodes unsigned state and uses projectId directly
const stateDecoded = JSON.parse(Buffer.from(state, 'base64').toString());
const projectId = stateDecoded.projectId;
// INSECURE: Updates project with root privileges without ownership check
await ProjectService.updateOneById({
id: new ObjectID(projectId),
data: { gitHubAppInstallationId: installationId },
props: { isRoot: true }, // Root privilege misused
});

The `UserAuthorization` middleware also fails to block unauthenticated requests to these endpoints .

Exploit:

Proof of Concept (PoC) to overwrite a victim project’s GitHub App installation:

1. Encode a malicious state payload with the victim's project ID.
STATE=$(printf '%s' '{"projectId":"<victim-project-uuid>","userId":"x"}' | base64 | tr -d '\n')
2. Send the request with the malicious state and an attacker-controlled installation_id.
curl -isk "https://<target-oneuptime-host>/api/github/auth/callback?installation_id=999999999&state=${STATE}"
3. Expected result: Server returns a 302 redirect to the victim's dashboard.
The victim's project now has its gitHubAppInstallationId set to 999999999.

This PoC demonstrates unauthorized modification of a project’s GitHub integration without any authentication .

Protection from this CVE:

  1. Immediate Upgrade: Update OneUptime to version `10.0.19` or later, which contains the fix for CVE-2026-30920 .
  2. Implement Signed State: The `state` parameter in OAuth flows must be a cryptographically signed, non-guessable token tied to the user’s current session to prevent tampering and replay attacks.
  3. Server-Side Authorization: Every API endpoint, especially those modifying resources, must rigorously verify that the authenticated user has explicit permissions to perform the action on the specified project ID.
  4. Validate Installation IDs: If an `installation_id` is provided, the server should verify that it is not only valid with GitHub but also belongs to the authenticated user or their organization before linking it to a project.

Impact:

  • Unauthorized Project Tampering: Attackers can overwrite any project’s GitHub App installation ID, effectively hijacking the integration .
  • Service Disruption: Setting a bogus installation ID can break the GitHub integration for the victim project, causing monitoring or deployment failures .
  • Data Exposure: With a valid GitHub installation ID, an attacker can enumerate all accessible repositories and link them to arbitrary OneUptime projects, potentially exposing repository metadata and secrets .
  • Privilege Escalation: The vulnerability allows a user with no valid account to perform actions that require root-level privileges on the project object .

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top