tx.origin authentication is the insecure practice of using Solidity’s `tx.origin` (the original externally-owned account that started the transaction) to authorize callers, instead of `msg.sender` (the immediate caller). It is exploitable by phishing: if an owner is tricked into calling a malicious contract, that contract calls the victim contract, where tx.origin is still the owner, so the check passes and the attacker acts with the owner’s authority. The fix is to use `msg.sender` for authorization. It maps to SWC-115.
What it is
Solidity exposes two notions of "who is calling":
- `msg.sender`: the immediate caller (could be a user or another contract).
- `tx.origin`: the original account that signed and started the whole transaction (always an externally-owned account).
tx.origin authentication checks require(tx.origin == owner). The flaw: if the owner calls any other contract, tx.origin is still the owner for the entire call chain, so an intermediate malicious contract inherits the owner’s authority.
How it works and example
Vulnerable check and the phishing setup:
function withdraw(address to) public {
require(tx.origin == owner); // unsafe
to.call{value: address(this).balance}("");
}
The attacker lures the owner into calling the attacker’s contract (for example, an innocent-looking function). That contract calls withdraw(attacker). Inside, tx.origin is still the owner, so the check passes and funds go to the attacker. Documented for defensive context.
How to defend
- Use `msg.sender` for all authorization, not
tx.origin. - Reserve `tx.origin` for niche cases (such as detecting whether the caller is a contract at all), and even then with caution.
- Use a vetted access-control library that does this correctly.
- Audit for any
tx.origincomparison used in a permission check. - Educate developers that
tx.origincarries the original signer’s authority through the whole call chain.
References
- [1]SWC Registry: Smart Contract Weakness Classification(SWC Registry)
- [2]Solidity docs: Security considerations(Solidity)
- [3]MITRE CWE-287: Improper Authentication(MITRE CWE)