-
Notifications
You must be signed in to change notification settings - Fork 73
Description
The VerifiedReport construction in dstack/kms/src/main_service.rs concatenates the report body and signature without a length delimiter, so a crafted report could shift bytes between the body and signature fields while preserving the concatenation.
Root Cause
The KMS signing function computes Keccak256(prefix + ":" + appid + message). While a colon delimiter separates prefix from appid, there is no delimiter or length prefix between appid and message. Since both are variable-length byte strings, different (appid, message) pairs can produce the same concatenation and therefore the same hash.
// crypto.rs:32-43
let hash = Keccak256::digest(&[prefix.as_bytes(), b":", app_id.as_bytes(), message].concat());Attack Path
- App A has
app_id = "abc"and signsmessage = "defGHI" - App B has
app_id = "abcdef"and signsmessage = "GHI" - Both produce
Keccak256("prefix:abcdefGHI")— identical hashes - App B's signature is valid for App A's (app_id, message) pair
- This enables cross-app signature forgery between apps whose app_ids share prefixes
Impact
Signature confusion between different apps. An attacker who controls one app can forge signatures that appear to come from a different app whose app_id is a prefix of the attacker's app_id (or vice versa). The practical impact depends on how signatures are verified downstream.
Suggested Fix
Add a delimiter or length prefix between app_id and message:
let hash = Keccak256::digest(
&[
prefix.as_bytes(),
b":",
&(app_id.len() as u32).to_be_bytes(),
app_id.as_bytes(),
message,
]
.concat(),
);Alternatively, use a structured encoding (e.g., RLP, SSZ, or CBOR) for the hash preimage.
Note: This issue was created automatically. The vulnerability report was generated by Claude and has not been verified by a human.