ref-fvm icon indicating copy to clipboard operation
ref-fvm copied to clipboard

Caller-side restrictions on method capabilities

Open anorth opened this issue 3 years ago • 1 comments

An idea via @jsuresh (working with me on token API design).

Re-entrancy bugs are rather common in existing blockchain systems (see The DAO hack and many others), and Filecoin isn't immune. They can sometimes be exploited/attacked by a malicious receiver.

Some cases could be prevented if a caller could restrict the capabilities of a callee method, such as to disallow the use of send(). Then a high-value contract could call hooks/receivers/getters with no risk of a malicious receiver calling back to exploit an unsaved state. Similarly a method could be forced to be read-only by restricting writes. I imagine these restrictions might be switched with a flag to the send() syscall.

An alternative to runtime enforcement would be compile-time, e.g. a readonly attribute on a method, enforced by the VM. But note that this would have to be done in a way that callers can rely on. E.g. if a standard API specified a GetThing() readonly method, it must be impossible for an actor to implement GetThing (not readonly) and satisfy the API. I can't think how to do that at the moment, given internal dispatch.

I would note that preventing send() would restrict some otherwise positive design patterns like delegation, and the general preference for many small interacting contracts over monoliths.

These runtime restrictions could share mechanism with similar restrictions for account abstraction.

anorth avatar Jun 27 '22 21:06 anorth

Two alternatives:

  1. Transactional memory: the actor SDK could check to see if the state-root has changed since last reading/writing it, and fail (unless the method was marked as "safe" for re-entrency). Unfortunately, this doesn't:
    1. Prevent reads while the actor is in some invalid state.
    2. Prevent the ABA problem (unless we introduce a state version, which honestly wouldn't be a terrible idea).
  2. Reverts: Filecoin already has state-tree transactions, and we could expose those to users. That is:
    1. Open a filecoin-level transaction.
    2. Perform 1 or more sends to read information.
    3. Abort the transaction.

Stebalien avatar Jun 28 '22 00:06 Stebalien

See https://github.com/filecoin-project/FIPs/discussions/487

Stebalien avatar Nov 19 '22 00:11 Stebalien

Implemented.

Stebalien avatar Nov 29 '22 16:11 Stebalien

In #1150

Stebalien avatar Nov 29 '22 16:11 Stebalien