Why is it very risky to use `tx.origin` to decide who can do important things in a contract, even if `msg.sender` is used for other stuff?
Using `tx.origin` to decide who can perform important actions in a smart contract is very risky due to the fundamental difference between `tx.origin` and `msg.sender` in a transaction's call stack. `tx.origin` is the address of the Externally Owned Account (EOA) that initially signed and sent the transaction, initiating the entire sequence of calls. This value remains constant throughout all subsequent internal and external calls within that single transaction. In contrast, `msg.sender` is the address of the account or contract that directly called the currently executing function. `msg.sender` changes with each external call in a transaction's call chain. For instance, if EOA A calls Contract B, and Contract B then calls Contract C, `tx.origin` would be A for all three contexts, while `msg.sender` would be A when B is executing, and B when C is executing. The risk arises because an attacker can exploit this difference by tricking a user into initiating a transaction with a malicious contract. An example scenario is a phishing attack: An attacker deploys a malicious contract. This malicious contract contains a function that, when called, makes an external call to a victim's legitimate contract. The victim's contract incorrectly uses `tx.origin` to authorize sensitive actions, such as withdrawing funds. The attacker then convinces the victim (an EOA) to call the malicious contract. When the victim's EOA calls the malicious contract, the `tx.origin` for the entire transaction chain is the victim's EOA. The malicious contract then makes an external call to the victim's legitimate contract, attempting to execute a function like `withdrawFunds()`. Because the victim's contract checks `tx.origin` for authorization and `tx.origin` is indeed the victim's EOA (who initiated the *entiretransaction), the legitimate contract mistakenly perceives the call as authorized by its owner, even though the direct caller (`msg.sender` for this specific internal call) is the malicious contract. This allows the malicious contract to drain funds or perform other unauthorized critical actions from the victim's contract on the victim's behalf. Therefore, `msg.sender` should always be used for authorization checks because it accurately identifies the immediate caller directly interacting with the contract, preventing malicious proxy calls.