SWC-115
Title
Authorization through tx.origin
Relationships
CWE-477: Use of Obsolete Function
Description
tx.origin
is a global variable in Solidity which returns the address of the account that sent the transaction. Using the variable for authorization could make a contract vulnerable if an authorized account calls into a malicious contract. A call could be made to the vulnerable contract that passes the authorization check since tx.origin
returns the original sender of the transaction which in this case is the authorized account.
Remediation
tx.origin
should not be used for authorization. Use msg.sender
instead.
References
- Solidity Documentation - tx.origin
- Ethereum Smart Contract Best Practices - Avoid using tx.origin
- SigmaPrime - Visibility
Contract Samples
mycontract.sol
/*
* @source: https://consensys.github.io/smart-contract-best-practices/recommendations/#avoid-using-txorigin
* @author: Consensys Diligence
* Modified by Gerhard Wagner
*/
pragma solidity 0.4.24;
contract MyContract {
address owner;
function MyContract() public {
owner = msg.sender;
}
function sendTo(address receiver, uint amount) public {
require(tx.origin == owner);
receiver.transfer(amount);
}
}
mycontract.yaml
description: Use tx.origin to authorize ETH withdrawls
issues:
- id: SWC-115
count: 1
locations:
- bytecode_offsets:
'0xb5277138e87869e9e71cf9737221a19a68d46fdb979a6c9b4837100a5ba8eb8f': [204]
line_numbers:
mycontract.sol: [18]
mycontract_fixed.sol
/*
* @source: https://consensys.github.io/smart-contract-best-practices/recommendations/#avoid-using-txorigin
* @author: Consensys Diligence
* Modified by Gerhard Wagner
*/
pragma solidity 0.4.25;
contract MyContract {
address owner;
function MyContract() public {
owner = msg.sender;
}
function sendTo(address receiver, uint amount) public {
require(msg.sender == owner);
receiver.transfer(amount);
}
}
mycontract_fixed.yaml
description: Use tx.origin to authorize ETH withdrawls
issues:
- id: SWC-115
count: 0
locations: []