Secret Vault on Aptos

First Flight #46
Beginner FriendlyWallet
100 EXP
View results
Submission Details
Impact: low
Likelihood: high
Invalid

Incorrect Error Code Returns HTTP 400 Instead of 403 for Permission Denied

Description

The contract uses a custom error code NOT_OWNER: u64 = 1 for permission checks, which causes the API to return HTTP 400 (Bad Request) instead of the semantically correct HTTP 403 (Permission Denied). This misleads API consumers into thinking the request format is incorrect when the actual issue is insufficient permissions.

Root Cause

The contract defines its own error constant:

const NOT_OWNER: u64 = 1;

And uses it for permission checks:

assert!(signer::address_of(caller) == @owner, NOT_OWNER);

Risk

Likelihood: High - Occurs in every permission check

Impact: Low - Obscures permission violations.

Impact

Operational Impact:

  • Incorrect HTTP semantics: Returns 400 (Bad Request) instead of 403 (Permission Denied)

  • Misleading error responses: API consumers receive wrong error type - suggesting request format issues rather than permission issues

Recommended Mitigation

Replace the custom error code with the standard library's permission error:

+ use std::error;
- const NOT_OWNER: u64 = 1;
+ const ENOT_OWNER: u64 = 1;
public fun set_secret(caller: &signer, secret: vector<u8>) {
- assert!(signer::address_of(caller) == @owner, NOT_OWNER);
+ assert!(signer::address_of(caller) == @owner, error::permission_denied(ENOT_OWNER));
// ...
}
public fun get_secret(caller: &signer): String acquires Vault {
- assert!(signer::address_of(caller) == @owner, NOT_OWNER);
+ assert!(signer::address_of(caller) == @owner, error::permission_denied(ENOT_OWNER));
// ...
}

Benefits of using standard errors:

  • Follows Aptos best practices

  • Documented HTTP error mapping: According to Aptos documentation, PERMISSION_DENIED maps to HTTP 403, providing clear semantics for API consumers

HTTP Error Mapping (Per Aptos Documentation)

According to the official Aptos error documentation, Move Standard Library errors have defined HTTP mappings:

Standard Error HTTP Status Meaning
PERMISSION_DENIED 403 The client does not have sufficient permission
INVALID_ARGUMENT 400 Caller specified an invalid argument
NOT_FOUND 404 A specified resource is not found

Current behavior with custom NOT_OWNER: u64 = 1:

  • Returns HTTP 400 (Bad Request)

  • Implies the request format or parameters are wrong

Expected behavior with error::permission_denied():

  • Returns HTTP 403 (Permission Denied) as documented

  • Clearly indicates a permission/authorization issue

Updates

Lead Judging Commences

bube Lead Judge 15 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.