Skip to content

Admin token comparison not constant-time #560

Closed as not planned
Closed as not planned

Description

@pbeza

The admin token comparison in dstack/kms/src/main_service.rs uses a standard byte-equality check rather than a constant-time comparison, leaking information about the token's value through response timing differences.

Root Cause

The KMS admin token verification uses a standard != comparison on hash bytes:

// main_service.rs:139-144
if provided_hash != expected_hash {
    return Err(Error::Unauthorized);
}

Standard byte comparison short-circuits on the first non-matching byte, creating a timing side-channel. An attacker can measure response times to determine how many leading bytes of the hash match, progressively recovering the admin token hash byte-by-byte.

Attack Path

  1. Attacker has network access to the KMS admin endpoint
  2. Attacker sends requests with different admin token values
  3. Attacker measures response times — longer times indicate more matching prefix bytes
  4. By iterating through possible byte values and observing timing differences, attacker recovers the admin token hash
  5. Attacker can now authenticate as admin and access all admin endpoints (including remove_cache with path traversal, a related finding)

Impact

The admin token can be recovered through timing analysis. While this requires many requests and precise timing measurements, it is a well-understood attack against non-constant-time comparisons. Compromising the admin token gives access to all admin endpoints.

Suggested Fix

Use constant-time comparison:

use subtle::ConstantTimeEq;

if !bool::from(provided_hash.ct_eq(&expected_hash)) {
    return Err(Error::Unauthorized);
}

The subtle crate provides constant-time operations specifically designed to prevent timing side-channels. ConstantTimeEq::ct_eq returns a Choice type; use bool::from() to convert it.


Note: This issue was created automatically. The vulnerability report was generated by Claude and has not been verified by a human.

Activity

  1. kvinwang commented on Mar 25, 2026

    @kvinwang
    Collaborator

    Thanks for reporting this.

    We reviewed the admin token verification in kms/src/main_service.rs. The service does not compare the raw admin token string; instead it computes a SHA-256 digest of the presented token and compares that digest against the configured admin_token_hash.

    This means any timing differences in the equality check apply only to the 256-bit hash value, not to the original secret token. Given that the admin token is intended to be a high-entropy random value and only its hash is stored, learning partial information about the digest via timing does not provide a practical way to recover or brute-force the underlying token.

    Because of this, we do not consider the current implementation to introduce a meaningful side-channel for admin token compromise, and we do not plan to change this comparison at the moment. If we ever change the format (for example, truncate the hash or store lower-entropy values), we will revisit this and switch to an explicit constant-time comparison helper.

  2. h4x3rotab commented on Jun 30, 2026

    @h4x3rotab
    Contributor

    Maintainer triage update: this is recorded in the public security report table: https://github.com/Dstack-TEE/dstack/blob/master/docs/security/public-security-reports.md#public-reports-and-findings

    Disposition: not a production vulnerability. The comparison is over a SHA-256 digest of a high-entropy token, not the raw token. No code fix is planned for this report under the documented production threat model.

    Closing as not planned.

  3. added
    securitySecurity-related issue, report, or hardening work
    security: reportPublic security report or already-public security finding
    security: not-production-vulnDoes not compromise supported production deployments under the documented threat model
    on Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    securitySecurity-related issue, report, or hardening worksecurity: not-production-vulnDoes not compromise supported production deployments under the documented threat modelsecurity: reportPublic security report or already-public security finding

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions