From what I can see, it seems trivially easy to set message sender in a view function to whatever address you want for external calls through ethers.js via the 'connect' function.
For example, if you have a contract like this:
contract Test {
address public owner;
string private secret;
modifier onlyOwner() {
require(msg.sender==owner,"onlyOwner");
_;
}
constructor() {
owner = msg.sender;
secret="Abracadabra";
}
function setSecret(string memory newSecret) public onlyOwner {
secret = newSecret;
}
function getSecret() public view onlyOwner returns(string memory) {
return secret;
}
}
Even if you aren't the owner account, you could run
let owner = await con.owner();
let secret = con.connect(owner).getSecret()
And get no complaints from ethers. I know this would fail if you tried to run setSecret
but when there no transaction involved it looks like you don't need a real signer, just a contract address.
Is there some other to check if the msg.sender is actually an account, not just a string of the account address?