feat: Add Function module to detect functions returning msg.sender directly or via alias #2753
feat: Add Function module to detect functions returning msg.sender directly or via alias #2753sidarth16 wants to merge 5 commits intocrytic:masterfrom
Conversation
|
The following Solidity contract was used for local testing of the // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract TestMsgSender {
address public owner;
constructor() {
owner = msg.sender;
}
// ✅ Should be detected
function directSender() internal view returns (address) {
return msg.sender;
}
// ✅ Should be detected
function aliasSender() internal view returns (address) {
address a = msg.sender;
return a;
}
// ✅ Should be detected
function multiAliasSender() internal view returns (address) {
address a = msg.sender;
address b = a;
address c = b;
return c;
}
// ✅ Should be detected
function reassignSender() internal view returns (address) {
address a = msg.sender;
address b = a;
a = b;
return a;
}
// ✅ Should be detected
function _getSender() internal view returns (address) {
return msg.sender;
}
// ❌ Should NOT be detected (msg.sender conversions)
function conversionSender() internal view returns (address) {
address a = msg.sender;
address b = address(uint160(uint256(uint160(a))));
return b;
}
// ❌ Should NOT be detected (nested internal call)
function returnsViaInternal() internal view returns (address) {
return _getSender();
}
// ❌ Should NOT be detected (returns unrelated var)
function unrelatedReturn() internal view returns (address) {
address a = owner;
return a;
}
// ❌ Should NOT be detected (does not return msg.sender)
function notMsgSender() internal view returns (address) {
return address(this);
}
// ❌ Should NOT be detected (does not return address)
function notAddress() internal view returns (uint256) {
address a = msg.sender;
return 7;
}
}Test Codefrom slither.slither import Slither
sl = Slither('test_msgsender.sol')
contract = sl.contracts[0]
for func in contract.functions:
print(f'{func.canonical_name} : {func.is_returning_msg_sender()}' )Output |
Code ReviewGood feature addition for issue #2755. The implementation follows existing patterns in the codebase (similar to What the PR does well
Issues to address1. Missing automated tests The PR includes manual test results in a comment but no automated unit tests. Please add tests to
Example test structure: def test_is_returning_msg_sender(solc_binary_path):
# Test cases from your manual testing
...2. PR contains unrelated changes The diff includes many unrelated files (Dockerfiles, CI workflows, pyproject.toml) that appear to be merge artifacts from the 'dev' branch. Consider rebasing to only include the Minor observationsControl flow limitation: The algorithm doesn't distinguish between different control flow paths. For example: function foo(bool x) returns (address) {
address a;
if (x) {
a = msg.sender;
} else {
a = address(0);
}
return a;
}This would return VerdictThe implementation is sound, but please add automated tests before merging. The existing manual test cases in the PR comment would make excellent unit tests. 🤖 Generated with Claude Code |
….sender Add method to Function class that detects if a function returns msg.sender directly or through variable aliasing. This is useful for: - Authorization checks - Meta-transaction handling (_msgSender() patterns) - Access control analysis The method handles: - Direct return of msg.sender - Single alias (address a = msg.sender; return a) - Transitive alias chains - Reassignment patterns Does not handle returns via internal function calls. Closes crytic#2755 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive unit tests covering: - Direct return of msg.sender - Single alias (address a = msg.sender; return a) - Transitive alias chains - Reassignment patterns - Negative cases: conversions, internal calls, unrelated returns Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
c1ca5cb to
323d974
Compare
Summary
This PR introduces a new method
is_returning_msg_sender()in theFunctionclass, enabling detection of Solidity functions that returnmsg.sender, either directly or through variable aliasing.Motivation
In many smart contract patterns,
msg.senderis returned through internal functions, often after assignment to local variables or via wrapper functions like_msgSender(). Detecting such patterns is crucial for accurate static analysis—particularly when assessing function protection or authorization flows.This utility provides foundational support for enhancing other modules involving
msg.sender(in future PRs ).What’s Covered
The newly added method
Function.is_returning_msg_sender()returnsTrueif:msg.sendermsg.senderExamples:
What's not Covered
msg.sender:Support for such recursive or wrapper logic will be addressed in a future update.
Closes #2755