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

[Docs] content updates and fixes #906

Merged
merged 7 commits into from
Jun 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions docs/05_best-practices/05_securing_your_contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,35 @@
content_title: Securing your contract
---

These are basic recommendations that should be the foundation of securing your smart contract:
## Basic Recommendations

1. The master git branch has the `has_auth`, `require_auth`, `require_auth2` and `require_recipient` methods available in the EOSIO library. They can be found in detail [here](https://eosio.github.io/eosio.cdt/1.6.0-rc1/group__action.html#function-requirerecipient) and implemented [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L144) (they end up calling the methods implemented in the `apply_context` class).
The following are basic recommendations which can be the foundation for securing your smart contract.

2. Understand how each of your contracts' actions is impacting the RAM, CPU, and NET consumption, and which account ends up paying for these resources.
### 1. Authorization Checks

3. Have a solid and comprehensive development process that includes security considerations from day one of the product planning and development.
The following methods are available in the `EOSIO` library and they can be used to implemented authorization checks in your smart contracts:

4. Test your smart contracts with every update announced for the blockchain you have deployed to. To ease your work, automate the testing as much as possible so you can run them often, and improve them periodically.
- [`has_auth`](../group__action/#function-has_auth)
- [`require_auth`](../group__action/#function-require_auth)
- [`require_auth2`](../how-to-guides/authorization/how_to_restrict_access_to_an_action_by_user/#3-using-require_auth2)
- [`require_recipient`](../group__action/#function-require_recipient)

5. Conduct independent smart contract audits, at least two from different organizations.
### 2. Resource Management

6. Host periodic bug bounties on your smart contracts and keep a continuous commitment to reward real security problems reported at any time.
Understand how each of your contracts' actions is impacting the RAM, CPU, and NET consumption, and which account ends up paying for these resources.

### 3. Secure by Default

Have a solid and comprehensive development process that includes security considerations from day one of the product planning and development.

### 4. Continuous Integration And Continuous Delivery

Test your smart contracts with every update announced for the blockchain you have deployed to. To ease your work, automate the testing as much as possible so you can run them often, and improve them periodically.

### 5. Security Audits

Conduct independent smart contract audits, at least two from different organizations.

### 6. Bug Bounties

Host periodic bug bounties on your smart contracts and keep a continuous commitment to reward real security problems reported at any time.
6 changes: 4 additions & 2 deletions docs/05_best-practices/09_deferred_transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ Deferred communication conceptually takes the form of action notifications sent

As already mentioned, deferred communication will get scheduled later at the producer's discretion. From the perspective of the originating transaction, i.e., the transaction that creates the deferred transaction, it can only determine whether the create request was submitted successfully or whether it failed (if it fails, it will fail immediately). Deferred transactions carry the authority of the contract that sends them. A transaction can cancel a deferred transaction.

[[warning | Warning about deferred transaction usage]]
| Because of the above, it is not recommended to use `deferred transactions`. There is consideration to deprecate deferred transactions in a future version.
[[warning | Deferred Transactions Are Deprecated]]
| As of [EOSIO 2.0 RC1](https://github.com/EOSIO/eos/releases/tag/v2.0.0-rc1) deferred transactions are deprecated.

Due to the above described behaviors it is not recommended to use `deferred transactions`.
Original file line number Diff line number Diff line change
@@ -1,14 +1,42 @@
---
content_title: How to restrict access to an action by a user
content_title: How To Perform Authorization Checks
link_text: How To Perform Authorization Checks
---

## Preconditions
- It is assumed you have the sources for a contract and one of the actions defined is getting as a parameter an account name and it is printing the account name.

To restrict access to the `hi` action, you can do it in two ways:
The following conditions are assumed:

1. Using require_auth
The below code is enforcing the action `hi` to be executed only by the account that is sent as parameter to the action, no matter what permission the account is using to sign the transaction (e.g. owner, active, code).
1. You have the sources of a contract with one of the actions defined, let's call it `hi` action.
2. The `hi` action has defined one input parameter `user` of type `name`.
3. The `hi` action prints the name of the `user` account.
4. The `hi` action needs to authorize the `user` account.

## Authorization Methods

To restrict access to the `hi` action, you can do it in three ways.

### 1. Use eosio::check(eosio::has_auth(...)...)

The below code enforces the action `hi` to be executed only by the account that is sent as parameter to the action, no matter what permission the account uses to sign the transaction (e.g. owner, active, code).

[[info | Error message is custom]]
| Observe that in this case the yielded error message is a custom one and thus it can be used to provide a better experience for the user.

```cpp
#include <capi/eosio/action.h>

void hi( name user ) {
check(has_auth(user), "User is not authorized to perform this action.");
print( "Hello, ", name{user} );
}
```

Another example can be found in the [Tic Tac Toe Tutorial](https://developers.eos.io/welcome/latest/tutorials/tic-tac-toe-game-contract/#action-handler---move).

### 2. Use require_auth

The below code enforces the action `hi` to be executed only by the account that is sent as parameter to the action, no matter what permission the account uses to sign the transaction (e.g. owner, active, code).

```cpp
void hi( name user ) {
Expand All @@ -17,17 +45,21 @@ void hi( name user ) {
}
```

2. Or using require_auth2
[[info | Error message is not custom]]
| Note that this time you can not customize the yielded error message, it will be a generic authorization error message.

### 3. Use require_auth2

The below code is enforcing the action `hi` to be executed only by the account that is sent as parameter to the action and only if the permission used to sign the transaction is the 'active' one. In other words, if the same user is signing the transaction with a different permission (e.g. code, owner) the execution of the action is halted.
The below code is enforces the action `hi` to be executed only by the account that is sent as parameter to the action and only if the permission used to sign the transaction is the 'active' one. In other words, if the same user uses the transaction with a different permission (e.g. code, owner) the execution of the action is halted.

```cpp
#include <capi/eosio/action.h>

void hi( name user ) {
require_auth2(nm.value, "active"_n.value);
require_auth2(user.value, "active"_n.value);
print( "Hello, ", name{user} );
}
```

An example of this contract can be found [here](https://github.com/EOSIO/eosio.cdt/blob/master/examples/hello/src/hello.cpp)
[[info | Error message is not custom]]
| Note that this time, as well as previous method, you can not customize the yielded error message, it will be a generic authorization error message.
4 changes: 2 additions & 2 deletions libraries/eosiolib/contracts/eosio/multi_index.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1571,7 +1571,7 @@ class multi_index
* @ingroup multiindex
*
* @param itr - an iterator pointing to the object to be updated
* @param payer - account name of the payer for the Storage usage of the updated row
* @param payer - account name of the payer for the storage usage of the updated row
* @param updater - lambda function that updates the target object
*
* @pre itr points to an existing element
Expand Down Expand Up @@ -1618,7 +1618,7 @@ class multi_index
* @ingroup multiindex
*
* @param obj - a reference to the object to be updated
* @param payer - account name of the payer for the Storage usage of the updated row
* @param payer - account name of the payer for the storage usage of the updated row
* @param updater - lambda function that updates the target object
*
* @pre obj is an existing object in the table
Expand Down
Loading