Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

DAWN-398 ⁃ User configurable generic security delay #1022

Closed
4 of 5 tasks
wanderingbort opened this issue Jan 2, 2018 · 7 comments
Closed
4 of 5 tasks

DAWN-398 ⁃ User configurable generic security delay #1022

wanderingbort opened this issue Jan 2, 2018 · 7 comments

Comments

@wanderingbort
Copy link
Contributor

wanderingbort commented Jan 2, 2018

Delayed Signed Transactions

As a user, I may be willing to trade immediate access to certain features for increased security in the event of an account compromise. #922 outlines the procedures by which I, as the user, will respond to such a compromise and regain secure control over my account however, there is a period of time where an attacker may be able to sign certain transactions on my behalf. Depending on my own values, it may be favorable to impose a delay on sensitive transactions on myself in order to ensure that an attacker cannot issue them without recourse.

Feature Description

Each named permission on an account is given a required delay which defaults to "no delay".
Updates to a permission that affect this delay must have been delayed by the existing delay.

When processing a newly learned transaction AFTER completely validating all necessary Authority
IF a permission which has a non-defaulted delay, is used on the transaction:

  • The transaction will be "boxed" into a deferred transaction, to be delivered no earlier than the current block time + maximum requested delay.
  • Storage for this will count as usage from the account requesting the maximum delay, breaking ties based on explicit ordering in the actions[]::authorizations[] (first mentioned).
  • The transaction's receipt in the block will have a new status code delayed
  • The deferred transaction can be cancelled by sending a signed action to config::system_account_name with an action name of canceldelay and a payload of the transactions ID (BDJ -- assuming this should be sender_id.
    • this action only succeeds if there exists a transaction with that ID that is delayed and the canceldelay action has the active permission authorization of one of accounts mentioned in the original transaction's in actions[]::authorizations[]
  • When/if the delayed transaction is finally included in a block it will carry the normal excuted status flag, there should be no contract-based error handling required.

Example use cases

Alice has a "savings" account and wants to prevent the loss of any EOS, in the event of an account compromise assuming she notices the compromise within 30 days and is willing to delay withdraws from that account to guarantee this. She sets up the sub-account with a permission named withdraw authorized by her primary account alice@active and having a delay of 30 days requested. She uses linkauth to set the permission for any eosio::transfer action to withdraw (meaning that any transfer authorized by the savings account now has a 30 day delay). She transfers her secure funds to the sub-account.

Alice suffers a breach and her active key is compromised. The attacker, immediately issues change to alice's active key and then a eosio::transfer from the savings account with the new attacker-key. Due to previously set up permissions, this transfer is delayed by 30 days. Meanwhile, the real Alice collaborates with her trusted 3rd parties to issue an update from owner to change active keys. This process takes a week but otherwise completes as expected. Alice now has 23 days of grace time where she has removed the attackers access and can still cancel the withdraw from savings before it takes effect. Alice publishes such a cancellation and loses no tokens in the attack

Tasks

  • Add delay to permission_object
  • Apply rules, boxing transactions that request a delay
  • Accounting for boxing storage appropriately (separate task for Bart)
  • Implement eosio::canceldelay native contract endpoint
  • implement use case(s) as unit tests

ATC:
(See delay_tests.cpp link_delay_direct_test and for an example)

  1. Load the currency contract and abi for the "currency" account.
  2. For a given primary "tester" account, create a permission (linkauth action) with the permission set to "first" and parent set to "active", and a delay (use something like 240 seconds if you are manually performing test or use 60 seconds if you have some performed commands to issue actions).
  3. Use linkauth to link a currency transfer for the "tester" account to the "first" permission.
  4. Also create a "tester2" account.
  5. Send the create action to setup the "currency" account with a maximum_supply of 1,000,000 CUR and an issue action to give "currency" account 1,000 CUR.
  6. Send a transfer action to transfer 100 CUR from "currency" account to "tester" account.
  7. Verify the transactions is performed and that the the "currency" account has 999,000 CUR and "tester" account has 1,000 CUR immediately.
  8. Send a transfer action to transfer 1 CUR from "tester" account to "tester2" account.
  9. Verify the transactions is identified as delayed and that the the "tester" account still has 1,000 CUR and "tester2" account still has 0 CUR immediately.
  10. After about half of the delay period has passed after sending the transfer in Port to AppBase #6, send a updateauth to update the "first" permission with a delay of 0.
  11. Verify the transactions is identified as delayed.
  12. After about half of the delay period has passed after sending the updateauth in Fix unit tests #10, send a transfer action to transfer 10 CUR from "tester" account to "tester2" account.
  13. Verify the transactions is identified as delayed.
  14. Once the delay period after the transfer in Port to AppBase #6 has expired, verify that the the "tester" account has 999 CUR and "tester2" account has 1 CUR.
  15. Once the delay period after the updateauth in Fix unit tests #10 has expired, send a transfer action to transfer 3 CUR from "tester" account to "tester2" account.
  16. Verify the transaction is performed and that the the "tester" account has 996 CUR and "tester" account has 4 CUR immediately.
  17. Once the delay period for the transfer in API Theory #14, verify the transactions is performed and that the the "tester" account has 986 CUR and "tester" account has 14 CUR immediately.
@bytemaster
Copy link
Contributor

In theory the recovery with owner could occur within hours so much shorter delays are possible and still benefit.

@blockone-syncclient blockone-syncclient changed the title User configurable generic security delay DAWN-398 ⁃ User configurable generic security delay Jan 3, 2018
@blockone-syncclient blockone-syncclient changed the title DAWN-398 ⁃ User configurable generic security delay DAWN-398 ⁃ User configurable generic security delay Jan 19, 2018
@blockone-syncclient
Copy link

➤ Brian Johnson commented:

This talks about applying the delay for the permission that is linked if the permission is being updated, I'm also presuming the same delay applies for linkauth(from existing link on permission to another link) or unlinkauth for permission.

@blockone-syncclient
Copy link

➤ Brian Johnson commented:

[~bart.wyatt] [~dan.larimer] How should happen for inline actions and deferred_transactions that have delays? I would think the answer could be more nuanced if the transaction that is currently being processed has a published time that satisfies the delay (Transaction was already boxed and delayed for required time and is now executing and now creating a follow on action). Simple requirements for inline deferred_actions would be to check if delay is already satisfied and execute or delay the rest of time. Would also like to know if the delayed status is set on the transaction_trace.

@blockone-syncclient
Copy link

➤ Bart Wyatt commented:

Ok, talked with [~dan.larimer] and came to the following conclusion.

We are not going to execute the transaction to determine implied actions because it is trivial to write a stateful contract which changes those results. So, the delay for auto-boxing will not be based on execution results. However, as a nod to these situations we want to add the concept of a semantic actions which are no different than normal actions but may carry additional meaning at the chain level. In this case mindelay@config::system_account_name. During our check for minimum permissions etc we should also scan the explicit actions on a transaction for this action and interpret the data for that action as an additional factor in the minimum delay calculation.

NOTE: when executing an action, if an inline_action is sent and the implied minimum delay is non-zero for the permissions associated with that the transaction should FAIL if it has not already been delayed for an amount of time that satisfies that delay.

while cludgy this gives us a few good things:

  1. we don't have to execute transactions to box them
  2. complex scenarios where delay is dependent (aka unknowable until deliver) can be handled with user-tools specifying a conservative value
  3. This doesn't add any information to transactions until the feature is needed (as opposed to a reserved header field)
  4. This is still hashed and included in consensus

RE delayed status. Please extend transaction_receipt::status_type to include a "delayed" enumeration. The amount of the delay should be deterministic and if one producer attempts to apply a block with a deferred transaction before that transactions delay has expired it should fail the block

@coreylederer coreylederer added this to the RC1 milestone Mar 23, 2018
brianjohnson5972 added a commit to brianjohnson5972/eos that referenced this issue Mar 28, 2018
brianjohnson5972 added a commit to brianjohnson5972/eos that referenced this issue Mar 28, 2018
brianjohnson5972 added a commit to brianjohnson5972/eos that referenced this issue Mar 28, 2018
brianjohnson5972 added a commit to brianjohnson5972/eos that referenced this issue Mar 28, 2018
brianjohnson5972 added a commit to brianjohnson5972/eos that referenced this issue Mar 28, 2018
brianjohnson5972 added a commit to brianjohnson5972/eos that referenced this issue Mar 28, 2018
brianjohnson5972 added a commit to brianjohnson5972/eos that referenced this issue Mar 28, 2018
@blockone-syncclient
Copy link

➤ Brian Johnson commented:

[~dan.larimer] [~bart.wyatt] [~phil.mesnier] First peer review was merged with "#warning TODO..." for processing of delayed transactions in net_plugin_impl::handle_message, since these requirements are not clear.

@brianjohnson5972 brianjohnson5972 added code review in code review and removed in progress labels Mar 28, 2018
brianjohnson5972 added a commit to brianjohnson5972/eos that referenced this issue Mar 29, 2018
…sing so that all the processing around _apply_transaction could be performed for transactions that get delayed. GH EOSIO#1022
brianjohnson5972 added a commit to brianjohnson5972/eos that referenced this issue Mar 29, 2018
brianjohnson5972 added a commit to brianjohnson5972/eos that referenced this issue Mar 30, 2018
wanderingbort pushed a commit that referenced this issue Mar 30, 2018
…-p2p-2

Moved template function into cpp file. GH #1022
@SheldonHH
Copy link
Contributor

SheldonHH commented Apr 1, 2018

  1. Alice has a "savings" account assuming she notices the compromise within 30 days and is willing to delay withdraws from that account to guarantee this.
  2. She sets up the sub-account with a permission named withdraw authorized by her primary account alice@active and having a delay of 30 days requested.
  3. She uses linkauth to set the permission for any eosio::transfer action to withdraw(meaning that any transfer authorized by the savings account now has a 30 day delay).
  4. She transfers her secure funds to the sub-account.

If her active key is compromised. The attacker, immediately issues change to alice's active key and then a eosio::transfer from the savings account with the new attacker-key.

Due to previously set up permissions, this transfer is delayed by 30 days. Meanwhile, the real Alice collaborates with her trusted 3rd parties to issue an update from owner to change active keys.

This process takes a week but otherwise completes as expected. Alice now has 23 days of grace time where she has removed the attackers access and can still cancel the withdraw from savings before it takes effect.

Alice publishes such a cancellation and loses no tokens in the attack.

@andriantolie
Copy link
Contributor

ATC Passes.
The above ATC scenario has been performed in delay_tests/link_delay_permission_change_test and verified to pass

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants