10 Faces of Blockchain Security (Part 3)


Consensus-Level Attacks & Access Control Failures

So far we’ve covered the contract layer (Part 1) and the economic layer (Part 2). Part 3 splits in two directions. One targets the blockchain’s foundation — the consensus algorithm itself (the 51% attack). The other is an access control failure, where a contract fails to properly decide “who is allowed to call this function.” Different layers, but they share one thing: a boundary of authority collapses.


7. The 51% Attack (Majority Hashpower/Stake Attack)

The vulnerability

The security of a Proof-of-Work blockchain rests on the assumption that “honest participants hold the majority of hashpower.” If a single actor acquires a majority of the hashpower, they can produce blocks faster than anyone else and build their own longer chain. Because of the longest-chain rule — the longest chain is accepted as valid — this attacker can replace (reorg) the existing chain with theirs.

Exploit flow — double spend

  1. The attacker sends coins to an exchange on the honest chain (transaction A).
  2. Simultaneously, they privately mine a separate chain in which transaction A does not exist.
  3. The exchange confirms transaction A and gives the attacker goods / another coin.
  4. The attacker publishes their privately-mined, now-longer chain. The network adopts the longer chain as canonical.
  5. Since the chain without transaction A is now canonical, the attacker gets their coins back and keeps the goods — spending the same coins twice.

The crucial point: there is no contract bug at all. The protocol worked exactly by its rules; only the safety assumption behind those rules (honest majority) was broken.

Real cases

  • Ethereum Classic (ETC): hit by 51% attacks several times in 2019–2020, resulting in double spends and chain reorgs in the hundreds of thousands to over a million dollars.
  • Bitcoin Gold: suffered roughly $18M in double-spend losses from a 51% attack in 2018.

The common thread: small-hashpower chains. The lower the total hashrate, the cheaper it is to rent or acquire a majority, making the attack economically viable. Large chains like Bitcoin and Ethereum are effectively protected because acquiring a majority would cost astronomically.

Defense patterns

  • More confirmations: for larger transactions, wait for more block confirmations. Overturning them via reorg requires digging that much deeper, sharply raising attack cost.
  • Switch to PoS: under Proof-of-Stake, an attack gets the staked funds slashed — the attack literally destroys the attacker’s own assets. This was a core motivation behind Ethereum’s Merge.
  • Checkpointing: periodically fix trusted checkpoints, blocking any reorg past that point.
  • Hashrate distribution monitoring: raise an early warning when any single pool’s share approaches a dangerous level.

8. Access Control Failures (Parity Multisig, 2017)

The vulnerability

A contract’s sensitive functions — withdrawing funds, changing ownership, self-destructing — must restrict “who can call them.” If a modifier like onlyOwner or an initialization guard is missing, anyone can call that function.

Exploit flow

// Vulnerable: no guard on the init function, so anyone can re-initialize
contract Wallet {
    address public owner;

    // no initializer guard!
    function initWallet(address _owner) public {
        owner = _owner;   // an attacker can set themselves as owner
    }

    function withdraw(uint amount) public {
        require(msg.sender == owner);
        payable(msg.sender).transfer(amount);
    }
}

For an already-initialized wallet, the attacker simply calls initWallet(attacker) again, and ownership transfers to them. Then they drain the funds via withdraw.

Real case — Parity’s two incidents

First (July 2017): the Parity multisig wallet’s init function was unprotected in a manner similar to the above. An attacker reset ownership of the wallets and stole roughly $30M.

Second (November 2017): this one is more striking. Parity wallets delegated their logic (via delegatecall) to a single shared library contract. That library was itself uninitialized, and its kill() (self-destruct) function was unprotected. A user named devops199 accidentally initialized the library as their own, then called self-destruct. Instantly, every multisig wallet depending on that library was bricked, permanently freezing over $500M. What made it especially painful: this wasn’t theft but permanent loss of access.

The second incident is actually a combination of the delegatecall/storage vulnerability from Part 1 and an access control failure. Uninitialized library + unprotected destructor = catastrophe.

Defense patterns

  • Explicit access modifiers: apply onlyOwner or role-based access (OpenZeppelin AccessControl) to every sensitive function.
  • Initialization guards: use the initializer modifier to enforce that the init function runs exactly once.
  • Initialize on deploy: initialize implementation/library contracts immediately after deployment, leaving no “ownerless” state.
  • Use self-destruct cautiously: minimize destructor functions, and if you keep them, guard them strictly. (Solidity itself is moving to discourage selfdestruct.)
// Safe: init runs once, destructor is owner-only
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

contract Wallet is Initializable {
    address public owner;

    function initialize(address _owner) public initializer { // runs once only
        owner = _owner;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "not owner");
        _;
    }
}

Part 3 Summary

#ProblemBoundary that collapsedNotable caseCore defense
751% attackConsensus honest-majority assumptionETC, Bitcoin GoldMore confirmations · PoS
8Access control failureFunction call authorityParity (two cases)initializer · onlyOwner

The 51% attack is a collapse of the protocol’s safety assumption; the access control failure is a collapse of the contract’s authority boundary. Both arise when the answer to “who is allowed to do what” comes undone.

In the final Part 4, we leave on-chain code entirely. We cover replay attacks, where a signature is reused out of context, and the off-chain key theft behind the largest hack in history — the Ronin bridge.

This article is part of the ChainLab technical series.

Tags: BlockchainSecurity, 51PercentAttack, DoubleSpend, AccessControl, Parity

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *