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.