Add security best practice sections (#14798)

This commit is contained in:
Ryo Onodera 2021-01-26 08:36:11 +09:00 committed by GitHub
parent 74c83e6854
commit 60611ae8a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 0 deletions

View File

@ -13,6 +13,7 @@ $ npm install
This command starts a local development server and open up a browser window.
Most changes are reflected live without having to restart the server.
(You might have to run build.sh first if you run into failures)
```
$ npm run start

View File

@ -84,6 +84,39 @@ _assign_ account ownership, meaning changing owner to different program id. If
an account is not owned by a program, the program is only permitted to read its
data and credit the account.
## Verifying validity of unmodified, reference-only accounts
For security purposes, it is recommended that programs check the validity of any
account it reads but does not modify.
The security model enforces that an account's data can only be modified by the
account's `Owner` program. Doing so allows the program to trust that the data
passed to them via accounts they own will be in a known and valid state. The
runtime enforces this by rejecting any transaction containing a program that
attempts to write to an account it does not own. But, there are also cases
where a program may merely read an account they think they own and assume the
data has only been written by themselves and thus is valid. But anyone can
issues instructions to a program, and the runtime does not know that those
accounts are expected to be owned by the program. Therefore a malicious user
could create accounts with arbitrary data and then pass these accounts to the
program in the place of a valid account. The arbitrary data could be crafted in
a way that leads to unexpected or harmful program behavior.
To check an account's validity, the program should either check the account's
address against a known value or check that the account is indeed owned
correctly (usually owned by the program itself).
One example is when programs read a sysvar. Unless the program checks the
address or owner, it's impossible to be sure whether it's a real and valid
sysvar merely by successful deserialization. Accordingly, the Solana SDK [checks
the sysvar's validity during
deserialization](https://github.com/solana-labs/solana/blob/a95675a7ce1651f7b59443eb146b356bc4b3f374/sdk/program/src/sysvar/mod.rs#L65).
If the program always modifies the account in question, the address/owner check
isn't required because modifying an unowned (could be the malicious account with
the wrong owner) will be rejected by the runtime, and the containing transaction
will be thrown out.
## Rent
Keeping accounts alive on Solana incurs a storage cost called _rent_ because the

View File

@ -171,6 +171,26 @@ that this method only supports fixed sized types. Token utilizes the
trait to encode/decode instruction data for both token instructions as well as
token account states.
### Multiple instructions in a single transaction
A transaction can contain instructions in any order. This means a malicious
user could craft transactions that may pose instructions in an order that the
program has not been protected against. Programs should be hardened to properly
and safely handle any possible instruction sequence.
One not so obvious example is account deinitialization. Some programs may
attempt to deinitialize an account by setting its lamports to zero, with the
assumption that the runtime will delete the account. This assumption may be
valid between transactions, but it is not between instructions or cross-program
invocations. To harden against this, the program should also explicitly zero out the
account's data.
An example of where this could be a problem is if a token program, upon
transferring the token out of an account, sets the account's lamports to zero,
assuming it will be deleted by the runtime. If the program does zero out the
account's data, a malicious user could trail this instruction with another that
transfers the tokens a second time.
## Signatures
Each transaction explicitly lists all account public keys referenced by the