Skip to content

Commit

Permalink
Merge pull request #513 from oasisprotocol/CU-8692kbhwx_Storage-IO-Pa…
Browse files Browse the repository at this point in the history
…tterns_Xi-Zhang

Start security section for Sapphire/OPL
  • Loading branch information
aefhm authored Nov 14, 2023
2 parents c7bda75 + 92586e7 commit 0eeadfd
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 1 deletion.
5 changes: 4 additions & 1 deletion docs/dapp/sapphire/guide.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,10 @@ state encryption key from the Oasis key manager. Both the keys and values of the
items stored in state are encrypted, but the size of either is *not* hidden. You
app may need to pad state items to a constant length, or use other obfuscation.
Observers may also be able to infer computation based on storage access patterns,
so you might need to obfuscate that, too.
so you may need to obfuscate that, too. See [Security chapter] for more
recommendations.

[Security chapter]: ./security.md#storage-access-patterns

:::danger Contract state leaks a fine-grained access pattern

Expand Down
116 changes: 116 additions & 0 deletions docs/dapp/sapphire/security.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
---
description: "Secure dApps: Recipes for Confidentiality"
---

# Security

This page is an ongoing work in progress to support confidential smart contract
development. At the moment we address safeguarding storage variable access
patterns and provide best practices for more secure orderings of error checking
to prevent leaking contract state.

## Storage Access Patterns

You can use a tool such as [hardhat-tracer] to examine the base EVM state
transitions under the hood.

```shell npm2yarn
npm install -D hardhat-tracer
```

and add `hardhat-tracer` to your `config.ts` file,

```typescript
import "hardhat-tracer"
```

in order to test and show call traces.

```shell
npx hardhat test --vvv --opcodes SSTORE,SLOAD
```

You can also trace a particular transaction, once you know its hash.

```shell
npx hardhat trace --hash 0xTransactionHash
```

For both [gas] usage and confidentiality purposes, we **recommend using
non-unique data size**. E.g. 64-byte value will still be distinct from a
128-byte value.

:::caution Inference based on access patterns

`SSTORE` keys from one transaction may be linked to `SLOAD` keys of another
transaction.

:::

## Order of Operations

When handling errors, gas usage patterns not only can reveal the code path
taken, **but sometimes the balance of a user as well** (in the case of a diligent
attacker using binary search).

```solidity
function transferFrom(address who, address to, uint amount)
external
{
require( balances[who] >= amount );
require( allowances[who][msg.sender] >= amount );
// ...
}
```

Modifying the order of error checking can prevent the accidental disclosure of
balance information in the example above.

```solidity
function transferFrom(address who, address to, uint amount)
external
{
require( allowances[who][msg.sender] >= amount );
require( balances[who] >= amount );
// ...
}
```

## Gas Padding

To prevent leaking information about a particular transaction, Sapphire
provides a [precompile] for dApp developers to **pad the amount of gas used
in a transaction**.

```solidity
contract GasExample {
bytes32 tmp;
function constantMath(bool doMath, uint128 padGasAmount) external {
if (doMath) {
bytes32 x;
for (uint256 i = 0; i < 100; i++) {
x = keccak256(abi.encodePacked(x, tmp));
}
tmp = x;
}
Sapphire.padGas(padGasAmount);
}
}
```

Both contract calls below should use the same amount of gas. Sapphire also
provides the precompile to return the gas [used] by the current transaction.

```typescript
await contract.constantMath(true, 100000);
await contract.constantMath(false, 100000);
```

[gas]: https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html
[hardhat-tracer]: https://www.npmjs.com/package/hardhat-tracer
[precompile]: https://api.docs.oasis.io/sol/sapphire-contracts/contracts/Sapphire.sol/library.Sapphire.html#padgas
[used]: https://api.docs.oasis.io/sol/sapphire-contracts/contracts/Sapphire.sol/library.Sapphire.html#gasused
1 change: 1 addition & 0 deletions sidebarDapp.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const sidebars = {
'dapp/sapphire/gasless',
'dapp/sapphire/precompiles',
'dapp/sapphire/addresses',
'dapp/sapphire/security',
{
type: 'link',
label: 'TypeScript API',
Expand Down

0 comments on commit 0eeadfd

Please sign in to comment.