The contract secret_vault::vault
attempts to provide a private vault where only the account owner can store and later retrieve their secret. However, the get_secret
function is declared as a #[view]
and takes an arbitrary address
parameter. Any user can call this function with the @owner
address, bypass the intended ownership restriction, and directly read the stored secret.
Additionally, because the secret is stored as plaintext in an on-chain resource, even if access control were correct, the information is still publicly visible to full nodes and indexers. This completely breaks the confidentiality guarantee of the module.
The function relies on an address argument rather than authenticating with a &signer
.
The assert!(caller == @owner, NOT_OWNER)
check is ineffective since any user can simply pass @owner
.
Secrets are stored unencrypted on-chain, so confidentiality is fundamentally unattainable.
The following demonstrates how a malicious actor can trivially bypass the intended access restriction:
Setup (Owner stores a secret): The legitimate user calls set_secret
to save their secret in the on-chain Vault
.
Attack (Malicious actor retrieves it): An attacker simply provides the owner’s public address as the caller
argument to get_secret
. Because there is no binding to the actual signer, the function will return the secret.
Alternative (Direct state inspection): Even without calling the function, anyone can fetch the resource data directly from the blockchain since it is stored in plaintext.
High severity: Any account can read the supposedly private data.
No actual secrecy is provided. Both on-chain and off-chain actors can trivially extract the stored value.
Intended functionality (“only the owner can see their secret”) is broken.
Severity: Critical
Likelihood: High (trivial to exploit, requires no special privileges).
Impact: Total loss of confidentiality, potential exposure of sensitive user data.
Change get_secret
to take &signer
and enforce signer authentication, not an arbitrary address
.
Do not rely on on-chain plaintext for secrets. Require client-side encryption before storing sensitive data. On-chain modules cannot guarantee confidentiality.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.