Skip to content

Ownership Vulnerabilities

id: LS04H
title: Ownership Vulnerabilities 
baseSeverity: H
category: access-control
language: solidity
blockchain: [ethereum]
impact: Unauthorized or irreversible control of privileged operations
status: draft
complexity: medium
attack_vector: external
mitigation_difficulty: easy
versions: [">=0.4.0", "<0.8.21"]
cwe: CWE-284
swc: SWC-100

πŸ“ Description

  • Ownership vulnerabilities occur when smart contracts fail to properly assign, restrict, or validate the owner or admin role, allowing unauthorized actors to gain privileged accessβ€”or leaving no one able to manage the contract.
  • This commonly includes uninitialized owner, wrong visibility on admin-only functions, or incorrect use of access control modifiers.

🚨 Vulnerable Code

contract InsecureAdmin {
    address public owner;

    function initialize() public {
        owner = msg.sender; // ❌ Can be called by anyone at any time
    }

    function mint(address to, uint256 amount) public {
        require(msg.sender == owner, "Not authorized");
        // mint logic
    }
}

πŸ§ͺ Exploit Scenario

Step-by-step exploit process:

  1. Contract is deployed but initialize() is never called.
  2. Attacker calls initialize() and sets themselves as owner.
  3. Now attacker can call mint() and create unlimited tokens.
  4. If immutable storage is used or token is deployed via a factory, this may not be reversible.

Assumptions:

  • Improper handling during ownership transfers can result in unauthorized access or permanent loss of control over the contract.
  • Ownership is not properly set during deployment or proxy usage.

βœ… Fixed Code

import "@openzeppelin/contracts/access/Ownable.sol";

contract SecureAdmin is Ownable {
    constructor() {
        transferOwnership(msg.sender);
    }

    function mint(address to, uint256 amount) external onlyOwner {
        // mint logic
    }
}

🧭 Contextual Severity

- context: "Default"
  severity: H
  reasoning: "Ownership flaws often result in full control loss over critical protocol operations."
- context: "DAO with on-chain governance overrides"
  severity: M
  reasoning: "Governance can limit damage if owner functions are rarely used or gated by proposals."
- context: "Private contracts or low-value assets"
  severity: L
  reasoning: "Low impact if the contract is not externally accessible or not holding valuable assets."

πŸ›‘οΈ Prevention

Primary Defenses

  • Use OpenZeppelin’s Ownable or AccessControl to enforce proper admin rights.
  • Always assign owner at deployment (constructor) or restrict initialize() with onlyOnce.
  • In upgradeable contracts, use initializer modifier from OpenZeppelin Upgradeable Libraries.

Additional Safeguards

  • Include emergency admin rotation or multisig-based recovery.
  • Log ownership transfers with OwnershipTransferred events.
  • Do not expose transferOwnership() without onlyOwner.

Detection Methods

  • Slither: uninitialized-state, missing-authorization, unprotected-function.
  • Manual review of all external/public functions that modify critical state.
  • Use Hardhat plugins like hardhat-upgrades for initializer checks.

πŸ•°οΈ Historical Exploits

  • Name: Bancor Network Hack
  • Date: 2018-07-09
  • Loss: Approximately $13.5 million
  • Post-mortem: Link to post-mortem

πŸ“š Further Reading


βœ… Vulnerability Report

id: LS04H
title: Ownership Vulnerabilities 
severity: H
score:
impact: 5         
exploitability: 4 
reachability: 4   
complexity: 2     
detectability: 3  
finalScore: 4.2

πŸ“„ Justifications & Analysis

  • Impact: Full takeover of protocol via unrestricted ownership assignment or transfer.
  • Exploitability: Common if initialize logic is public or not called.
  • Reachability: Most admin logic is accessible in public methods.
  • Complexity: Basic scripting or contract call can trigger exploit.
  • Detectability: Easily found with tools like Slither, but often missed in upgradeable contracts.