Security·5 min का पठन·Solingo द्वारा

tx.origin vs msg.sender — Security के लिए क्यों Important है

tx.origin और msg.sender के बीच critical difference जानें, क्यों authentication के लिए tx.origin उपयोग करना dangerous है, और कब कौन सा global variable उपयोग करें।

# tx.origin vs msg.sender — Security के लिए क्यों Important है

Solidity में सबसे common security mistakes में से एक है authentication के लिए tx.origin का उपयोग करना। यह seemingly innocent choice आपके contract को phishing attacks के लिए expose कर सकता है जो user funds drain कर सकते हैं।

इस article में, हम tx.origin और msg.sender के बीच के difference को clarify करेंगे, vulnerability demonstrate करेंगे, और establish करेंगे कि कब किसका उपयोग करें।

Difference क्या है

msg.sender

Current function का immediate caller।

  • अगर user आपके contract को directly call करता है: msg.sender = user का address
  • अगर contract A, contract B को call करता है: msg.sender = contract A का address
  • Call chain में हर call पर change होता है

tx.origin

Original external account जिसने transaction initiate की।

  • हमेशा वह EOA (Externally Owned Account) जिसने transaction sign की
  • कभी contract address नहीं होता
  • पूरे call chain में constant रहता है

Visual Example

User (0xUser) → Contract A → Contract B → Contract C

| | |

msg.sender: 0xUser A B

tx.origin: 0xUser 0xUser 0xUser

Contract C पर:

  • msg.sender = Contract B का address
  • tx.origin = 0xUser (original EOA)

Vulnerability: Phishing Attack

Vulnerable Contract

contract VulnerableWallet {

address public owner;

constructor() {

owner = msg.sender;

}

// VULNERABLE: tx.origin का उपयोग authentication के लिए

function transfer(address payable to, uint256 amount) public {

require(tx.origin == owner, "Not owner");

to.transfer(amount);

}

receive() external payable {}

}

Attack

Attacker एक malicious contract बनाता है:

contract MaliciousContract {

address payable public attacker;

VulnerableWallet public wallet;

constructor(address _wallet) {

attacker = payable(msg.sender);

wallet = VulnerableWallet(payable(_wallet));

}

// Innocent-looking function

function claimAirdrop() public {

// Victim के wallet को call करता है

wallet.transfer(attacker, address(wallet).balance);

}

}

Attack Flow

  • Attacker MaliciousContract deploy करता है
  • Attacker victim को claimAirdrop() call करने के लिए convince करता है (phishing के through)
  • Victim MaliciousContract.claimAirdrop() call करता है
  • Malicious contract VulnerableWallet.transfer() को call करता है
  • Vulnerable wallet में:
  • - tx.origin = victim का address ✅ (check pass होता है!)

    - msg.sender = MaliciousContract का address

  • Funds attacker को transfer हो जाते हैं
  • Victim सभी funds खो देता है
  • क्यों काम करता है: Victim ने transaction initiate की, इसलिए पूरे call chain में tx.origin owner के equal है।

    Secure Implementation

    msg.sender का उपयोग

    contract SecureWallet {
    

    address public owner;

    constructor() {

    owner = msg.sender;

    }

    // SECURE: msg.sender का उपयोग

    function transfer(address payable to, uint256 amount) public {

    require(msg.sender == owner, "Not owner");

    to.transfer(amount);

    }

    receive() external payable {}

    }

    अब attack fail हो जाता है:

    • msg.sender = MaliciousContract का address ❌ (check fail)
    • Transaction revert हो जाता है funds steal होने से पहले

    कब कौन सा उपयोग करें

    msg.sender का उपयोग करें:

    Authentication/Authorization के लिए

    modifier onlyOwner() {
    

    require(msg.sender == owner, "Not authorized");

    _;

    }

    Access Control के लिए

    mapping(address => bool) public whitelist;
    
    

    function restrictedAction() external {

    require(whitelist[msg.sender], "Not whitelisted");

    }

    Sender-Specific Logic

    mapping(address => uint256) public balances;
    
    

    function deposit() external payable {

    balances[msg.sender] += msg.value;

    }

    tx.origin का उपयोग करें:

    ⚠️ Rare legitimate cases:

  • Original caller को gas refunds
  • function expensiveOperation() external {
    

    // Complex computation

    // Original user को gas refund (intermediate contract को नहीं)

    payable(tx.origin).transfer(gasRefund);

    }

  • Analytics/Logging (security के लिए कभी नहीं)
  • event Action(address indexed user, address indexed caller);
    
    

    function logAction() external {

    emit Action(tx.origin, msg.sender);

    }

  • Contract-to-contract calls को prevent करना (सावधानी से उपयोग करें)
  • function onlyEOA() external {
    

    require(tx.origin == msg.sender, "No contract calls");

    // Direct user interaction ensure करता है

    }

    Warning: Contracts को block करना account abstraction और future composability को prevent करता है।

    Real-World Impact

    THORChain Vulnerability (2021)

    Early version में tx.origin checks थे जिन्हें router contracts के through exploit किया जा सकता था। Fortunately, launch से पहले audit में catch हो गया।

    OpenZeppelin Recommendation

    OpenZeppelin team explicitly tx.origin के against warn करती है:

    > "Authorization के लिए tx.origin का उपयोग करना phishing attacks का कारण बन सकता है जहाँ malicious contract users को transactions approve करने के लिए trick करता है।"

    EIP-3074 Implications

    Future Ethereum improvements जैसे EIP-3074 (transaction sponsorship) tx.origin behavior को change कर सकते हैं, जिससे इस पर rely करना और भी risky हो जाता है।

    Detection और Prevention

    Slither Detection

    Slither automatically tx.origin usage को flag करता है:

    slither . --detect tx-origin

    Output:

    VulnerableWallet.transfer() (contracts/Wallet.sol#8-11) uses tx.origin for authorization:
    

    - require(bool)(tx.origin == owner) (contracts/Wallet.sol#9)

    Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-usage-of-txorigin

    Code Review Checklist

    ✅ सभी tx.origin occurrences justified हैं

    ✅ Authorization के लिए require() में कोई tx.origin नहीं

    ✅ Access control modifiers में कोई tx.origin नहीं

    ✅ सभी authentication के लिए msg.sender उपयोग किया गया

    Testing

    Tests लिखें जो malicious intermediaries को simulate करें:

    // Foundry test
    

    function testPhishingAttack() public {

    // User के owned wallet को deploy करें

    vm.prank(user);

    VulnerableWallet wallet = new VulnerableWallet();

    vm.deal(address(wallet), 10 ether);

    // Malicious contract deploy करें

    MaliciousContract attacker = new MaliciousContract(address(wallet));

    // User phishing में फंस जाता है, malicious contract को call करता है

    vm.prank(user);

    attacker.claimAirdrop();

    // अब attacker के पास funds हैं

    assertEq(address(attacker).balance, 10 ether);

    }

    Summary Table

    | Aspect | msg.sender | tx.origin |

    |--------|---------------|--------------|

    | Value | Immediate caller | Original EOA |

    | Contract हो सकता है | Yes | No |

    | Call chain में changes | Yes | No |

    | Authentication के लिए | ✅ Safe | ❌ Dangerous |

    | Access control के लिए | ✅ Recommended | ❌ Vulnerable |

    | Logging के लिए | ✅ दोनों उपयोग करें | ✅ Acceptable |

    | Phishing risk | ❌ No | ✅ High |

    Best Practices

  • Default से msg.sender उपयोग करें — यह लगभग हमेशा वही होता है जो आपको चाहिए
  • Authentication के लिए कभी tx.origin उपयोग न करें — कोई exception नहीं
  • हर tx.origin occurrence को audit करें — इसकी necessity justify करें
  • Slither checks enable करें — detection automate करें
  • Phishing scenarios test करें — assume करें कि malicious intermediaries exist करते हैं
  • अपनी team को educate करें — यह एक common mistake है
  • Conclusion

    tx.origin और msg.sender के बीच का choice सिर्फ technical detail नहीं है — यह critical security decision है।

    Rule simple है: Authentication और authorization के लिए msg.sender उपयोग करें। tx.origin को rare edge cases के लिए reserve करें जहाँ आपको genuinely original transaction signer चाहिए, और कभी security-critical checks के लिए नहीं।

    Solingo पर secure authentication patterns master करें — हमारे exercises में phishing attack simulations और real-time feedback शामिल हैं जो आपको इन dangerous pitfalls से बचने में help करते हैं।

    Practice में लगाने के लिए तैयार हैं?

    Solingo पर interactive exercises के साथ इन concepts को apply करें।

    मुफ्त में शुरू करें