From 7977c8c7cec79a05f2ec5d9bc0538af3ef82349c Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 11 Aug 2021 12:03:47 +0200 Subject: [PATCH] Authorized Proxies --- docs/security-considerations.rst | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/security-considerations.rst b/docs/security-considerations.rst index e348dd915..0fab056ff 100644 --- a/docs/security-considerations.rst +++ b/docs/security-considerations.rst @@ -193,6 +193,39 @@ Note that ``.send()`` does **not** throw an exception if the call stack is depleted but rather returns ``false`` in that case. The low-level functions ``.call()``, ``.delegatecall()`` and ``.staticcall()`` behave in the same way. +Authorized Proxies +================== + +If your contract can act as a proxy, i.e. if it can call arbitrary contracts +with user-supplied data, then the user can essentially assume the identity +of the proxy contract. Even if you have other protective measures in place, +it is best to build your contract system such that the proxy does not have +any permissions (not even for itself). If needed, you can accomplish that +using a second proxy: + +.. code-block:: solidity + + // SPDX-License-Identifier: GPL-3.0 + pragma solidity ^0.8.0; + contract ProxyWithMoreFunctionality { + PermissionlessProxy proxy; + + function callOther(address _addr, bytes memory _payload) public + returns (bool, bytes memory) { + return proxy.callOther(_addr, _payload); + } + // Other functions and other functionality + } + + // This is the full contract, it has no other functionality and + // requires no privileges to work. + contract PermissionlessProxy { + function callOther(address _addr, bytes memory _payload) public + returns (bool, bytes memory) { + return _addr.call(_payload); + } + } + tx.origin =========