[Hack] Incorrect User Operation Hash Vulnerability in ERC4337

A high severity vulnerability found in ERC4337 entrypoint v0.5

Severity: High

Impact Range: ERC4337 and the infrastructure built on it

My Report Link: https://github.com/eth-infinitism/account-abstraction/issues/237


The bug will lead to incorrect UserOperation hash calculation in ERC4337 entrypoint contract v0.5.

The contract calculates the hash directly from the calldata. However, Solidity doesn’t not enforce the calldata encoding. That means an attacker can add dummy data in the calldata and then generate different hash for the same UserOperation.

 function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) { 
     //lighter signature scheme. must match UserOp.ts#packUserOp 
     bytes calldata sig = userOp.signature; 
     // copy directly the userOp from calldata up to (but not including) the signature. 
     // this encoding depends on the ABI encoding of calldata, but is much lighter to copy 
     // than referencing each field separately. 
     assembly { 
         let ofs := userOp 
         let len := sub(sub(sig.offset, ofs), 32) 
         ret := mload(0x40) 
         mstore(0x40, add(ret, add(len, 32))) 
         mstore(ret, len) 
         calldatacopy(add(ret, 32), ofs, len) 
     } 
 } 

The entrypoint contract has upgraded to v0.6 to resolve this issue.