Authorization Vulnerability Lab
Learn about critical authorization vulnerabilities in smart contracts and how to prevent unauthorized token transfers.
Back to LabsVulnerable Contract Details
Contract Address:
CDIH7MPZDLFUCSZNXAOWBHDDHTM37KP7Y6P4AIKD2UCETFCRSYDLZMKP
Vulnerability:
Due to the lack of authorization checks in this contract, any user can transfer tokens from another user's account.
#![no_std]
use soroban_sdk::{contract, contractimpl, Address, Env, Vec, Symbol};
#[contract]
pub struct VulnerableToken;
#[contractimpl]
impl VulnerableToken {
// VULNERABILITY: No authorization check!
pub fn transfer(env: Env, from: Address, to: Address, amount: i64) {
let key = Symbol::new(&env, "balances");
let balances: Vec<(Address, i64)> = env.storage().persistent().get(&key)
.unwrap_or_else(|| Vec::new(&env));
let from_balance = balances
.iter()
.find(|val| val.0 == from)
.map(|val| val.1)
.unwrap_or(0);
let mut new_balances = Vec::new(&env);
for balance in balances.iter() {
if balance.0 != from && balance.0 != to {
new_balances.push_back((balance.0.clone(), balance.1));
}
}
new_balances.push_back((from, from_balance - amount));
let to_balance = balances
.iter()
.find(|val| val.0 == to)
.map(|val| val.1)
.unwrap_or(0);
new_balances.push_back((to, to_balance + amount));
env.storage().persistent().set(&key, &new_balances);
}
}
Security Analysis
Vulnerability Details
- •No authorization check before token transfer
- •Any user can transfer tokens from any account
- •Missing balance validation
Impact
- •Unauthorized token theft
- •Complete loss of user funds
- •Loss of trust in the protocol
Best Practices for Authorization
1. Always Use require_auth()
Implement authorization checks at the beginning of functions that modify user assets or sensitive data.
2. Validate Inputs
Check balances and other conditions before performing transfers or state changes.
3. Handle Errors Gracefully
Use proper error handling and provide clear error messages for failed authorization attempts.