SECURITY WIN

Cloudreve Security Assessment

8 security vulnerabilities were identified across the platform, including a high-severity timing attack in HMAC signature validation. Other issues included plaintext database credentials appearing in logs, errors in lock token validation logic, insufficient salt entropy in password hashing, race conditions during node pool initialization, WOPI-related error information disclosure, and missing rate limiting on authentication endpoints. Five of these issues have since been remediated and merged into release 4.11.0.
January 202612 min read
Faizan
Cloudreve Timing Attack Information DisclosureAuthenticationRace Condition

Executive Summary

This security assessment was conducted using Kolega.dev's automated security remediation platform, which combines traditional security scanning (SAST, SCA, secrets detection) with proprietary AI-powered deep code analysis. Our two-tier detection approach identified vulnerabilities that standard tools miss, including complex logic flaws and cross-service injection vectors.

Our analysis of the Cloudreve repository identified 8 vulnerabilities through Kolega.dev Deep Code Scan (Tier 2) that warrant attention.

Vulnerability Overview

ID

Title

PR/Ticket

V1

Plaintext Database Credentials in Logs

Release 4.11.0

V2

HIGH: Timing Attack Vulnerability in HMAC Signature Validation

Release 4.11.0

V3

Lock Token Validation Logic Error in ConfirmUploadSession

Release 4.11.0

V4

Insufficient Salt Length for SHA256 Password Hashing

Release 4.11.0

V5

Race Condition in Node Pool Initialization

Release 4.11.0

V6

WOPI Error Information Disclosure in Response Headers

Release 4.11.0

V7

Sensitive Settings Logged in Console Output

Release 4.11.0

V8

Missing Rate Limiting on Authentication Endpoints

Release 4.11.0

Responsible Disclosure Timeline

Kolega.dev follows responsible disclosure practices. We coordinated privately through Cloudreve's official security reporting channel.

January 7 2026

Initial report sent to Cloudreve by email to support@cloudreve.org

January 12 2026

Response from Cloudreve confirming they 5 of the reported items were remediated and merged into release 4.11.0



Vulnerabilities Detail

V1: Plaintext Database Credentials in Logs

CWE: CWE-532 (Insertion of Sensitive Information into Log File)
Location: inventory/client.go:70

Description
Database credentials are logged in plaintext when establishing connections. The DatabaseURL is logged without sanitization, which could expose sensitive connection strings containing passwords.

Evidence
The entire DatabaseURL containing potentially sensitive credentials (user:password@host:port/db) is logged using l.Info(). If logs are exposed or accessible to unauthorized users, credentials are compromised.

Impact
An attacker with access to application logs could extract database credentials and directly access the database, bypassing all application-level security controls.

Remediation
Sanitize database URLs before logging. Implement a function to mask credentials in connection strings. Example: strip password from URL before logging, or log only the database host/name without user/password components.


V2: HIGH: Timing Attack Vulnerability in HMAC Signature Validation

CWE: CWE-208 (Observable Timing Discrepancy)
Location: pkg/auth/hmac.go:52

Description
The HMAC signature validation uses string comparison (!=) instead of constant-time comparison. The Check() function regenerates the signature and compares it using '!=' operator, which is vulnerable to timing attacks. An attacker can measure response times to determine correct signature bytes without knowing the secret key.

Evidence
Line 52 uses standard string comparison operator. This should use crypto/subtle.ConstantTimeCompare() to prevent timing-based side-channel attacks that leak information about valid signatures.

Impact
Attackers can forge valid HMAC signatures by: (1) Measuring response times for different signature inputs; (2) Identifying valid signature bytes through timing analysis; (3) Bypassing request signature validation for critical operations like upload callbacks, remote node communication, and OSS callbacks.

Remediation
Replace the string comparison with constant-time comparison: 'if subtle.ConstantTimeCompare([]byte(auth.Sign(body, expires)), []byte(sign)) != 1 { ... }'. Import 'crypto/subtle' and ensure all HMAC validations use constant-time comparison.


V3: Lock Token Validation Logic Error in ConfirmUploadSession

CWE: CWE-287 (Improper Authentication)
Location: pkg/filemanager/manager/upload.go:157-158

Description
Critical logic error in upload session lock token validation. The condition checks if session.LockToken == "" (empty), but then attempts to CONFIRM the lock using that empty token. This means the lock confirmation is only performed when NO lock token exists, which is backwards. If a lock token IS provided, the lock confirmation is completely skipped.

Evidence
The logic is inverted: it checks for EMPTY token and then tries to confirm using that empty token. This defeats the entire purpose of lock validation when tokens exist. The confirm should happen when token IS NOT empty (session.LockToken != "").

Impact
An attacker could potentially bypass lock protections during concurrent uploads, leading to race conditions, file corruption, or simultaneous writes to the same file. Multiple upload sessions could overwrite each other's chunks.

Remediation
Change the condition from if session.LockToken == "" to if session.LockToken != "" to correctly validate when a lock token exists. Verify the lock logic with proper test coverage for concurrent upload scenarios.


V4: Insufficient Salt Length for SHA256 Password Hashing

CWE: CWE-336 (Same Seed in Pseudo-Random Number Generator)
Location: inventory/user.go:601-616

Description
Passwords are hashed with a 16-character salt generated from RandStringRunes(16). While reasonable, it's using a custom random string generation which may not have cryptographically sufficient entropy.

Evidence
The salt is generated via util.RandStringRunes(16), which is a character-based random generator. Without seeing the implementation of RandStringRunes, it's unclear if it uses cryptographic randomness. SHA256 without a proper key derivation function (like PBKDF2, bcrypt, or scrypt) is weak for password hashing.

Impact
Weak salt generation could reduce the effective security to brute force attacks. A 16-character salt from a limited character set may have less than 96 bits of entropy, compared to the recommended 128+ bits.

Remediation
Use crypto/rand for salt generation, not a custom RandStringRunes. Generate at least 32 bytes of cryptographic randomness. Better yet, use bcrypt or PBKDF2 with recommended parameters (e.g., bcrypt cost factor of 12+).


V5: Race Condition in Node Pool Initialization

CWE: CWE-362 (Concurrent Execution using Shared Resource with Improper Synchronization)
Location: pkg/cluster/pool.go:114-143

Description
The weighted node pool's Get() function modifies the node's current weight without holding exclusive locks in the read-locked section. While the pool itself uses a lock, individual node items' current weight is modified inside the RLock section.

Evidence
RLock only prevents other writers, not concurrent readers. Multiple goroutines can execute Get() simultaneously and modify item.current.

Impact
Incorrect load balancing, potential node overload, and unpredictable behavior in multi-node deployments.

Remediation

  1. Use exclusive Lock() instead of RLock().

  2. Move weight modification outside the critical section.

  3. Use atomic operations for weight updates.

  4. Implement a locking mechanism per node item.


V6: WOPI Error Information Disclosure in Response Headers

CWE: CWE-209 (Information Exposure Through an Error Message)
Location: routers/controllers/wopi.go:17,30,41,80

Description
WOPI error responses directly expose full error messages in the X-WOPI-ServerError header without sanitization, potentially revealing internal system information.

Evidence
Error messages containing stack traces, database errors, or file system information are directly returned in the WOPI ServerError header. This applies to CheckFileInfo, GetFile, PutFile, and ModifyFile endpoints.

Impact
Attackers can gain information about the system architecture, database structure, and file paths to aid in crafting more targeted attacks.

Remediation
Sanitize error messages before returning them. Return generic error messages to clients and log detailed errors server-side. Use error codes instead of error text in responses.


V7: Sensitive Settings Logged in Console Output

CWE: CWE-532 (Insertion of Sensitive Information into Log File)
Location: pkg/conf/conf.go:177

Description
Configuration override values from environment variables are logged with the logger.Info call, potentially including sensitive configuration like database passwords or API keys.

Evidence
The exact configuration key and value are logged when environment variables override configuration. If an admin uses CR_CONF_Database.Password=secretpass, this appears in logs.

Impact
Sensitive configuration values (passwords, API keys, secrets) could be exposed in application logs if admins use environment variables to override configuration.

Remediation
Don't log the actual values of sensitive configuration keys. Instead, log only the key name with a masked value like '***'. Identify sensitive keys (Password, Secret, Token, Key) and mask them.


V8: Missing Rate Limiting on Authentication Endpoints

CWE: CWE-770 (Allocation of Resources Without Limits or Throttling)
Location: routers/router.go:287-310

Description
Authentication endpoints (login, 2FA, token refresh) lack rate limiting, enabling brute force attacks against user accounts.

Evidence

  1. No rate limiting middleware applied to /api/session/token endpoints.

  2. Login endpoint only protected by optional captcha, not rate limiting.

  3. Token refresh endpoint has no protection.

  4. 2FA endpoint can be brute forced if captcha is bypassed.

  5. No visible rate limiting in entire codebase for auth endpoints.

Impact
MEDIUM-HIGH: Brute force and credential stuffing attacks:

  1. Attackers can attempt unlimited password guesses

  2. 2FA codes can be brute forced (6 digits = 1 million possibilities)

  3. Account lockout not visible in code, enabling unlimited attempts

  4. Credential stuffing attacks from compromised password databases

  5. Email enumeration through login attempt timing

Remediation

  1. Implement rate limiting on login endpoint: max 5 attempts per 15 minutes per IP/username.

  2. Implement rate limiting on 2FA endpoint: max 10 attempts per 15 minutes per session.

  3. Use middleware like juju/ratelimit already available in pkg.

  4. Implement account lockout after N failed attempts.

  5. Add exponential backoff for failed attempts.

  6. Log all authentication attempts for monitoring.



Simple 3 click setup.

Deploy Kolega.dev.

Find and fix your technical debt.