Michelson: remove confusing MANAGER instruction
This commit is contained in:
parent
3d602424d1
commit
1ccfe6aed9
@ -201,46 +201,3 @@ Alternatives/Solutions
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
- Do not store funds in spendable contracts that you do not control.
|
- Do not store funds in spendable contracts that you do not control.
|
||||||
|
|
||||||
Do not use ``SENDER ; MANAGER`` for authentication
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
Each originated account has a manager. The manager may change the
|
|
||||||
delegate of the account or issue transfers from it (depending on the
|
|
||||||
'delegatable' and 'spendable' flags).
|
|
||||||
|
|
||||||
When an account is originated, the originator can set the manager to
|
|
||||||
any key hash. The originator also sets the code for contracts, and so
|
|
||||||
could immediately transfer to the originated contract, causing it in
|
|
||||||
turn to transfer to your contract. This means **an attacker may
|
|
||||||
arrange for the manager of the source to be any arbitrary key hash**,
|
|
||||||
without ever having access to the corresponding key.
|
|
||||||
|
|
||||||
.. _possible-issues-6:
|
|
||||||
|
|
||||||
Possible Issues
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
- An attacker may trivially subvert your authentication code by
|
|
||||||
originating a contract with manager set to the key hash you are
|
|
||||||
looking for.
|
|
||||||
- A user may (voluntarily) manage contracts which execute transfers
|
|
||||||
without their approval. Contracts should not (and, given the above,
|
|
||||||
must not) be authorized to act on behalf of their managers.
|
|
||||||
|
|
||||||
.. _alternativessolutions-6:
|
|
||||||
|
|
||||||
Alternatives/Solutions
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
- Directly compare the ``SENDER`` address to the expected sender,
|
|
||||||
ideally an implicit account associated with some trusted key
|
|
||||||
hash. If you have a trusted ``key_hash`` rather than an
|
|
||||||
``address``, you can obtain an address to compare against the
|
|
||||||
source using ``IMPLICIT_ACCOUNT ; ADDRESS``. If the expected sender
|
|
||||||
is a contract, you may want to understand its code -- it could
|
|
||||||
allow anyone to cause it to transfer to your contract.
|
|
||||||
- For more flexibility, require authorization via a signature of data
|
|
||||||
describing the operation you will perform, and use
|
|
||||||
``CHECK_SIGNATURE`` to verify it. See above regarding replay
|
|
||||||
attacks.
|
|
||||||
|
@ -1295,17 +1295,6 @@ for under/overflows.
|
|||||||
Operations on contracts
|
Operations on contracts
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
- ``MANAGER``: Access the manager of a contract.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
:: address : 'S -> key_hash option : 'S
|
|
||||||
:: contract 'p : 'S -> key_hash : 'S
|
|
||||||
|
|
||||||
Note that the originator of an account/contract may set the manager to
|
|
||||||
**any** key hash. Thus, ``SENDER; MANAGER`` is not appropriate for
|
|
||||||
authentication.
|
|
||||||
|
|
||||||
- ``CREATE_CONTRACT``: Forge a contract creation operation.
|
- ``CREATE_CONTRACT``: Forge a contract creation operation.
|
||||||
|
|
||||||
::
|
::
|
||||||
@ -1405,9 +1394,6 @@ contract, unit for an account.
|
|||||||
internal transaction. It may be the ``SOURCE``, but may
|
internal transaction. It may be the ``SOURCE``, but may
|
||||||
also not if the source sent an order to an intermediate
|
also not if the source sent an order to an intermediate
|
||||||
smart contract, which then called the current contract.
|
smart contract, which then called the current contract.
|
||||||
To make sure that ``SENDER`` is the ``SOURCE``, either
|
|
||||||
compare them, or make sure that ``SENDER`` is the implicit
|
|
||||||
account of its ``MANAGER``.
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -2036,7 +2022,6 @@ The instructions which accept at most one variable annotation are:
|
|||||||
GE
|
GE
|
||||||
ADDRESS
|
ADDRESS
|
||||||
CONTRACT
|
CONTRACT
|
||||||
MANAGER
|
|
||||||
SET_DELEGATE
|
SET_DELEGATE
|
||||||
IMPLICIT_ACCOUNT
|
IMPLICIT_ACCOUNT
|
||||||
NOW
|
NOW
|
||||||
@ -2304,10 +2289,6 @@ A similar mechanism is used for context dependent instructions:
|
|||||||
|
|
||||||
CONTRACT 'p :: @a address : 'S -> @a.contract contract 'p : 'S
|
CONTRACT 'p :: @a address : 'S -> @a.contract contract 'p : 'S
|
||||||
|
|
||||||
MANAGER
|
|
||||||
:: @a address : 'S -> @a.manager key_hash option : 'S
|
|
||||||
:: @c contract 'p : 'S -> @c.manager key_hash : 'S
|
|
||||||
|
|
||||||
BALANCE :: 'S -> @balance tez : 'S
|
BALANCE :: 'S -> @balance tez : 'S
|
||||||
|
|
||||||
SOURCE :: 'S -> @source address : 'S
|
SOURCE :: 'S -> @source address : 'S
|
||||||
@ -2921,7 +2902,6 @@ XII - Full grammar
|
|||||||
| LE
|
| LE
|
||||||
| GE
|
| GE
|
||||||
| INT
|
| INT
|
||||||
| MANAGER
|
|
||||||
| SELF
|
| SELF
|
||||||
| TRANSFER_TOKENS
|
| TRANSFER_TOKENS
|
||||||
| SET_DELEGATE
|
| SET_DELEGATE
|
||||||
|
@ -217,7 +217,6 @@ module Script : sig
|
|||||||
| I_LSL
|
| I_LSL
|
||||||
| I_LSR
|
| I_LSR
|
||||||
| I_LT
|
| I_LT
|
||||||
| I_MANAGER
|
|
||||||
| I_MAP
|
| I_MAP
|
||||||
| I_MEM
|
| I_MEM
|
||||||
| I_MUL
|
| I_MUL
|
||||||
|
@ -66,7 +66,6 @@ type prim =
|
|||||||
| I_LSL
|
| I_LSL
|
||||||
| I_LSR
|
| I_LSR
|
||||||
| I_LT
|
| I_LT
|
||||||
| I_MANAGER
|
|
||||||
| I_MAP
|
| I_MAP
|
||||||
| I_MEM
|
| I_MEM
|
||||||
| I_MUL
|
| I_MUL
|
||||||
@ -194,7 +193,6 @@ let string_of_prim = function
|
|||||||
| I_LSL -> "LSL"
|
| I_LSL -> "LSL"
|
||||||
| I_LSR -> "LSR"
|
| I_LSR -> "LSR"
|
||||||
| I_LT -> "LT"
|
| I_LT -> "LT"
|
||||||
| I_MANAGER -> "MANAGER"
|
|
||||||
| I_MAP -> "MAP"
|
| I_MAP -> "MAP"
|
||||||
| I_MEM -> "MEM"
|
| I_MEM -> "MEM"
|
||||||
| I_MUL -> "MUL"
|
| I_MUL -> "MUL"
|
||||||
@ -303,7 +301,6 @@ let prim_of_string = function
|
|||||||
| "LSL" -> ok I_LSL
|
| "LSL" -> ok I_LSL
|
||||||
| "LSR" -> ok I_LSR
|
| "LSR" -> ok I_LSR
|
||||||
| "LT" -> ok I_LT
|
| "LT" -> ok I_LT
|
||||||
| "MANAGER" -> ok I_MANAGER
|
|
||||||
| "MAP" -> ok I_MAP
|
| "MAP" -> ok I_MAP
|
||||||
| "MEM" -> ok I_MEM
|
| "MEM" -> ok I_MEM
|
||||||
| "MUL" -> ok I_MUL
|
| "MUL" -> ok I_MUL
|
||||||
@ -457,7 +454,6 @@ let prim_encoding =
|
|||||||
("LSL", I_LSL) ;
|
("LSL", I_LSL) ;
|
||||||
("LSR", I_LSR) ;
|
("LSR", I_LSR) ;
|
||||||
("LT", I_LT) ;
|
("LT", I_LT) ;
|
||||||
("MANAGER", I_MANAGER) ;
|
|
||||||
("MAP", I_MAP) ;
|
("MAP", I_MAP) ;
|
||||||
("MEM", I_MEM) ;
|
("MEM", I_MEM) ;
|
||||||
("MUL", I_MUL) ;
|
("MUL", I_MUL) ;
|
||||||
|
@ -64,7 +64,6 @@ type prim =
|
|||||||
| I_LSL
|
| I_LSL
|
||||||
| I_LSR
|
| I_LSR
|
||||||
| I_LT
|
| I_LT
|
||||||
| I_MANAGER
|
|
||||||
| I_MAP
|
| I_MAP
|
||||||
| I_MEM
|
| I_MEM
|
||||||
| I_MUL
|
| I_MUL
|
||||||
|
@ -610,18 +610,6 @@ let rec interp
|
|||||||
logged_return (Item (Some contract, rest), ctxt)
|
logged_return (Item (Some contract, rest), ctxt)
|
||||||
else
|
else
|
||||||
logged_return (Item (None, rest), ctxt)
|
logged_return (Item (None, rest), ctxt)
|
||||||
| Manager, Item ((_, contract), rest) ->
|
|
||||||
Lwt.return (Gas.consume ctxt Interp_costs.manager) >>=? fun ctxt ->
|
|
||||||
Contract.get_manager ctxt contract >>=? fun manager ->
|
|
||||||
logged_return (Item (manager, rest), ctxt)
|
|
||||||
| Address_manager, Item (contract, rest) ->
|
|
||||||
Lwt.return (Gas.consume ctxt Interp_costs.manager) >>=? fun ctxt ->
|
|
||||||
Contract.exists ctxt contract >>=? fun exists ->
|
|
||||||
if exists then
|
|
||||||
Contract.get_manager ctxt contract >>=? fun manager ->
|
|
||||||
logged_return (Item (Some manager, rest), ctxt)
|
|
||||||
else
|
|
||||||
logged_return (Item (None, rest), ctxt)
|
|
||||||
| Transfer_tokens,
|
| Transfer_tokens,
|
||||||
Item (p, Item (amount, Item ((tp, destination), rest))) ->
|
Item (p, Item (amount, Item ((tp, destination), rest))) ->
|
||||||
Lwt.return (Gas.consume ctxt Interp_costs.transfer) >>=? fun ctxt ->
|
Lwt.return (Gas.consume ctxt Interp_costs.transfer) >>=? fun ctxt ->
|
||||||
|
@ -193,8 +193,6 @@ let number_of_generated_growing_types : type b a. (b, a) instr -> int = function
|
|||||||
| Ge -> 0
|
| Ge -> 0
|
||||||
| Address -> 0
|
| Address -> 0
|
||||||
| Contract _ -> 1
|
| Contract _ -> 1
|
||||||
| Manager -> 0
|
|
||||||
| Address_manager -> 0
|
|
||||||
| Transfer_tokens -> 1
|
| Transfer_tokens -> 1
|
||||||
| Create_account -> 0
|
| Create_account -> 0
|
||||||
| Implicit_account -> 0
|
| Implicit_account -> 0
|
||||||
@ -278,7 +276,6 @@ let namespace = function
|
|||||||
| I_LSL
|
| I_LSL
|
||||||
| I_LSR
|
| I_LSR
|
||||||
| I_LT
|
| I_LT
|
||||||
| I_MANAGER
|
|
||||||
| I_MAP
|
| I_MAP
|
||||||
| I_MEM
|
| I_MEM
|
||||||
| I_MUL
|
| I_MUL
|
||||||
@ -2264,18 +2261,6 @@ and parse_instr
|
|||||||
>>=? fun annot ->
|
>>=? fun annot ->
|
||||||
typed ctxt loc (Contract t)
|
typed ctxt loc (Contract t)
|
||||||
(Item_t (Option_t ((Contract_t (t, None), None), None, None), rest, annot))
|
(Item_t (Option_t ((Contract_t (t, None), None), None, None), rest, annot))
|
||||||
| Prim (loc, I_MANAGER, [], annot),
|
|
||||||
Item_t (Contract_t _, rest, contract_annot) ->
|
|
||||||
parse_var_annot loc annot ~default:(gen_access_annot contract_annot default_manager_annot)
|
|
||||||
>>=? fun annot ->
|
|
||||||
typed ctxt loc Manager
|
|
||||||
(Item_t (Key_hash_t None, rest, annot))
|
|
||||||
| Prim (loc, I_MANAGER, [], annot),
|
|
||||||
Item_t (Address_t _, rest, addr_annot) ->
|
|
||||||
parse_var_annot loc annot ~default:(gen_access_annot addr_annot default_manager_annot)
|
|
||||||
>>=? fun annot ->
|
|
||||||
typed ctxt loc Address_manager
|
|
||||||
(Item_t (Option_t ((Key_hash_t None, None), None, None), rest, annot))
|
|
||||||
| Prim (loc, I_TRANSFER_TOKENS, [], annot),
|
| Prim (loc, I_TRANSFER_TOKENS, [], annot),
|
||||||
Item_t (p, Item_t
|
Item_t (p, Item_t
|
||||||
(Mutez_t _, Item_t
|
(Mutez_t _, Item_t
|
||||||
@ -2408,7 +2393,7 @@ and parse_instr
|
|||||||
| I_ABS | I_NEG | I_LSL | I_LSR
|
| I_ABS | I_NEG | I_LSL | I_LSR
|
||||||
| I_COMPARE | I_EQ | I_NEQ
|
| I_COMPARE | I_EQ | I_NEQ
|
||||||
| I_LT | I_GT | I_LE | I_GE
|
| I_LT | I_GT | I_LE | I_GE
|
||||||
| I_MANAGER | I_TRANSFER_TOKENS | I_CREATE_ACCOUNT
|
| I_TRANSFER_TOKENS | I_CREATE_ACCOUNT
|
||||||
| I_CREATE_CONTRACT | I_SET_DELEGATE | I_NOW
|
| I_CREATE_CONTRACT | I_SET_DELEGATE | I_NOW
|
||||||
| I_IMPLICIT_ACCOUNT | I_AMOUNT | I_BALANCE
|
| I_IMPLICIT_ACCOUNT | I_AMOUNT | I_BALANCE
|
||||||
| I_CHECK_SIGNATURE | I_HASH_KEY | I_SOURCE | I_SENDER
|
| I_CHECK_SIGNATURE | I_HASH_KEY | I_SOURCE | I_SENDER
|
||||||
@ -2453,7 +2438,7 @@ and parse_instr
|
|||||||
fail (Bad_stack (loc, I_TRANSFER_TOKENS, 4, stack))
|
fail (Bad_stack (loc, I_TRANSFER_TOKENS, 4, stack))
|
||||||
| Prim (loc, (I_DROP | I_DUP | I_CAR | I_CDR | I_SOME | I_H | I_DIP
|
| Prim (loc, (I_DROP | I_DUP | I_CAR | I_CDR | I_SOME | I_H | I_DIP
|
||||||
| I_IF_NONE | I_LEFT | I_RIGHT | I_IF_LEFT | I_IF
|
| I_IF_NONE | I_LEFT | I_RIGHT | I_IF_LEFT | I_IF
|
||||||
| I_LOOP | I_IF_CONS | I_MANAGER | I_IMPLICIT_ACCOUNT
|
| I_LOOP | I_IF_CONS | I_IMPLICIT_ACCOUNT
|
||||||
| I_NEG | I_ABS | I_INT | I_NOT
|
| I_NEG | I_ABS | I_INT | I_NOT
|
||||||
| I_EQ | I_NEQ | I_LT | I_GT | I_LE | I_GE as name), _, _),
|
| I_EQ | I_NEQ | I_LT | I_GT | I_LE | I_GE as name), _, _),
|
||||||
stack ->
|
stack ->
|
||||||
@ -2478,7 +2463,7 @@ and parse_instr
|
|||||||
I_ABS ; I_INT; I_NEG ; I_LSL ; I_LSR ;
|
I_ABS ; I_INT; I_NEG ; I_LSL ; I_LSR ;
|
||||||
I_COMPARE ; I_EQ ; I_NEQ ;
|
I_COMPARE ; I_EQ ; I_NEQ ;
|
||||||
I_LT ; I_GT ; I_LE ; I_GE ;
|
I_LT ; I_GT ; I_LE ; I_GE ;
|
||||||
I_MANAGER ; I_TRANSFER_TOKENS ; I_CREATE_ACCOUNT ;
|
I_TRANSFER_TOKENS ; I_CREATE_ACCOUNT ;
|
||||||
I_CREATE_CONTRACT ; I_NOW ; I_AMOUNT ; I_BALANCE ;
|
I_CREATE_CONTRACT ; I_NOW ; I_AMOUNT ; I_BALANCE ;
|
||||||
I_IMPLICIT_ACCOUNT ; I_CHECK_SIGNATURE ; I_H ; I_HASH_KEY ;
|
I_IMPLICIT_ACCOUNT ; I_CHECK_SIGNATURE ; I_H ; I_HASH_KEY ;
|
||||||
I_STEPS_TO_QUOTA ;
|
I_STEPS_TO_QUOTA ;
|
||||||
|
@ -318,10 +318,6 @@ and ('bef, 'aft) instr =
|
|||||||
(_ typed_contract * 'rest, Contract.t * 'rest) instr
|
(_ typed_contract * 'rest, Contract.t * 'rest) instr
|
||||||
| Contract : 'p ty ->
|
| Contract : 'p ty ->
|
||||||
(Contract.t * 'rest, 'p typed_contract option * 'rest) instr
|
(Contract.t * 'rest, 'p typed_contract option * 'rest) instr
|
||||||
| Manager :
|
|
||||||
('arg typed_contract * 'rest, public_key_hash * 'rest) instr
|
|
||||||
| Address_manager :
|
|
||||||
(Contract.t * 'rest, public_key_hash option * 'rest) instr
|
|
||||||
| Transfer_tokens :
|
| Transfer_tokens :
|
||||||
('arg * (Tez.t * ('arg typed_contract * 'rest)), packed_internal_operation * 'rest) instr
|
('arg * (Tez.t * ('arg typed_contract * 'rest)), packed_internal_operation * 'rest) instr
|
||||||
| Create_account :
|
| Create_account :
|
||||||
|
Loading…
Reference in New Issue
Block a user