Normal behavior:
The get_secret
function should only allow the rightful owner of a Vault
resource to retrieve their own secret, while preventing access by unauthorized accounts.
Specific issue:
The function hardcodes @owner
as the retrieval address, but set_secret
stores the Vault
resource under the caller’s address. This mismatch means:
Non-owners cannot retrieve their own secret (because their data is never read).
Any account can pass @owner
into the get_secret
parameter to retrieve the owner’s secret without authorization.
Additionally, the caller
parameter in get_secret
is not tied to a signer, so the assert!(caller == @owner, NOT_OWNER);
check is meaningless.
Likelihood:
Always reproducible — any account can retrieve the @owner
's secret by calling get_secret(@owner)
.
Non-owners will always fail to retrieve their own secrets due to the hardcoded storage address.
Impact:
Confidential information in the owner’s Vault
is exposed to all accounts.
Legitimate users are denied access to their own data.
Access control enforcement is completely bypassed.
This test demonstrates that an arbitrary account (bob
) can bypass access control by simply passing the hardcoded @owner
value into get_secret
. This allows them to retrieve sensitive data without owning the Vault
. The test passes, proving the vulnerability.
The fix ensures that the function reads from the address provided by the signer, not a hardcoded named address. This prevents arbitrary accounts from retrieving another account’s secret.
If you want absolute access control, tie caller
to a &signer
argument, so only the transaction signer can retrieve their own secret. Alternatively, store an owner: address
field inside Vault
and verify it against the signer’s address.
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.