CVE-2026-50167 Overview
CVE-2026-50167 is an Insecure Direct Object Reference (IDOR) vulnerability [CWE-639] in Kurrier, a self-hosted workspace for email, calendar, contacts, and storage. Versions prior to 1.2.4 fail to enforce ownership checks on authenticated API requests for webhook and identity resources. An attacker with a valid API key can supply another account's resource identifiers to read and enumerate webhook and identity data belonging to other users. The issue affects GET and list endpoints under apps/worker/server/routes/api/kurrier/webhooks/ and apps/worker/server/routes/api/kurrier/identities/. Kurrier version 1.2.4 fixes the flaw by scoping API resources to the authenticated owner.
Critical Impact
Any authenticated Kurrier API key holder can enumerate and read webhook and identity metadata belonging to other tenants, exposing cross-user resource information.
Affected Products
- Kurrier self-hosted workspace prior to version 1.2.4
- Kurrier worker API routes handling webhooks (webhooks/[id].get.ts, webhooks/index.get.ts)
- Kurrier worker API routes handling identities (identities/[id].get.ts, identities/index.get.ts)
Discovery Timeline
- 2026-08-18 - CVE-2026-50167 published to NVD
- 2026-08-19 - Last updated in NVD database
Technical Details for CVE-2026-50167
Vulnerability Analysis
The vulnerability stems from missing ownership validation in Kurrier's worker API layer. Four route handlers accept authenticated requests with a valid API key but do not verify that the requested resource identifier belongs to the API key's owner. As a result, an attacker who knows or guesses another account's webhook or identity ID can retrieve that resource through the GET-by-ID endpoints. The list endpoints similarly return resources without filtering by owner scope, enabling enumeration of other tenants' data.
Anonymous requests and invalid API keys are correctly rejected. Cross-user modification (write) operations are also blocked. The exposure is limited to read and list actions on webhook and identity metadata, which may include sensitive configuration such as callback URLs, identity provider references, and account linkage details.
Root Cause
The worker route handlers called validateApiKey(event) to confirm the caller was authenticated but did not correlate the returned ownerId to the requested resource. Database queries in the affected handlers filtered by resource ID alone rather than by both ID and owner. This is a classic broken object-level authorization pattern.
Attack Vector
An attacker requires only a valid low-privileged Kurrier API key. Using that key, the attacker issues authenticated HTTPS requests to the vulnerable GET or list endpoints, supplying a target account's webhook or identity identifier. The server returns the resource data without checking tenant boundaries. No user interaction is required, and the attack is fully remote.
// Security patch in apps/worker/lib/api-helpers.ts - scope api resources by owner (#446)
import { H3Event, createError, readRawBody } from "h3";
-import { db, apiKeys, secretsMeta, getSecretAdmin } from "@db";
+import {db, apiKeys, secretsMeta, getSecretAdmin, identities} from "@db";
import { eq, and } from "drizzle-orm";
+import crypto from "node:crypto";
export function apiSuccess(data: any = null) {
return {
// Source: https://github.com/kurrier-org/kurrier/commit/22fad36fb1bc79e3038184ddd485fb235217475c
The patched send.post.ts handler illustrates the corrected pattern, where validateApiKey now returns an ownerId that is passed to a new validateIdentityOwnership helper:
// Security patch in apps/worker/server/routes/api/kurrier/email/send.post.ts
import {
apiSuccess,
- validateApiKey,
+ validateApiKey, validateIdentityOwnership,
validateJSONBody,
} from "../../../../../lib/api-helpers";
export default defineEventHandler(async (event) => {
- await validateApiKey(event);
+ const { ownerId } = await validateApiKey(event);
const { json } = await validateJSONBody(event);
// Source: https://github.com/kurrier-org/kurrier/commit/22fad36fb1bc79e3038184ddd485fb235217475c
Detection Methods for CVE-2026-50167
Indicators of Compromise
- Authenticated API requests to /api/kurrier/webhooks/[id] or /api/kurrier/identities/[id] where the resource ID does not belong to the requesting API key owner.
- High-volume sequential or enumerated GET requests to the webhooks or identities list and by-ID endpoints from a single API key.
- Access patterns where a single API key retrieves resources associated with multiple distinct owner IDs.
Detection Strategies
- Review Kurrier worker application logs for GET requests to the affected routes and correlate the authenticated API key owner with the returned resource owner.
- Alert on any API key that requests resource identifiers outside its historical baseline of owned resources.
- Search source repositories and deployments for Kurrier versions earlier than 1.2.4 to identify vulnerable installations.
Monitoring Recommendations
- Enable verbose request logging on the Kurrier worker service and forward logs to a centralized analytics platform for tenant-boundary auditing.
- Track per-API-key request rates and unique resource IDs accessed to detect enumeration behavior.
- Monitor for outbound traffic to unexpected webhook URLs that may indicate an attacker has enumerated and repurposed exposed webhook configurations.
How to Mitigate CVE-2026-50167
Immediate Actions Required
- Upgrade all Kurrier deployments to version 1.2.4 or later, which enforces owner-scoped queries on webhook and identity endpoints.
- Rotate all Kurrier API keys after upgrading to invalidate any keys that may have been used in enumeration attempts.
- Audit webhook and identity records for unexpected read access or modifications made prior to the upgrade.
Patch Information
The fix is available in Kurrier v1.2.4. The remediation is tracked in Pull Request #446 and applied in commit 22fad36. Full details are published in GitHub Security Advisory GHSA-f7h3-f5vh-3764.
Workarounds
- Restrict Kurrier API access to a trusted network segment until the upgrade is applied.
- Temporarily disable or revoke API keys that are not required for critical automation to reduce the attack surface.
- Place a reverse proxy in front of the worker service to log and rate-limit requests to /api/kurrier/webhooks/ and /api/kurrier/identities/ routes.
# Upgrade Kurrier to the patched version
git fetch --tags
git checkout v1.2.4
# Rebuild and redeploy the worker service
docker compose pull
docker compose up -d --force-recreate worker
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

