Skip to content

Commit

Permalink
Merge pull request #133 from CoinFabrik/131-update-documentation-for-…
Browse files Browse the repository at this point in the history
…unprotected-mapping-operation

131 update documentation for unprotected mapping operation
  • Loading branch information
nachogutman authored Apr 18, 2024
2 parents 663d14d + 368f3ba commit 49b7746
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Visit [Scout's website](https://coinfabrik.github.io/scout-soroban/) to view the
| [unused-return-enum](https://github.com/CoinFabrik/scout-soroban/tree/main/detectors/unused-return-enum) | Return enum from a function is not completely used. | [1](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/unused-return-enum/unused-return-enum-1), [2](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/unused-return-enum/unused-return-enum-2) | Minor |
| [iterators-over-indexing](https://github.com/CoinFabrik/scout-soroban/tree/main/detectors/iterators-over-indexing) |Iterating with hardcoded indexes is slower than using an iterator. Also, if the index is out of bounds, it will panic. | [1](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/iterators-over-indexing-1) | Enhancement |
| [assert-violation](https://github.com/CoinFabrik/scout-soroban/tree/main/detectors/assert-violation) | Avoid the usage of the macro assert!, it can panic.| [1](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/assert-violation/assert-violation-1) | Enhancement |
| [unprotected-mapping-operation](https://github.com/CoinFabrik/scout-soroban/tree/main/detectors/unprotected-mapping-operation) | Modifying mappings with an arbitrary key given by users can be a significant vulnerability. | [1](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/unprotected-mapping-operation/unprotected-mapping-operation-1), [2](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/unprotected-mapping-operation/unprotected-mapping-operation-2) | Critical |


## Tests
Expand Down
60 changes: 60 additions & 0 deletions docs/docs/detectors/16-unprotected-mapping-operation
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Unprotected Mapping Operation

### What it does

It warns you if a mapping operation (`insert`, `take`, `remove`) function is called with a user-given `key` field of the type `AccountId`.

### Why is this bad?

Modifying mappings with an arbitrary key given by users can be a significant vulnerability for several reasons:

- Unintended Modifications: Allowing users to provide arbitrary keys can lead to unintended modifications of critical data within the smart contract. If the input validation and sanitation are not done properly, users may be able to manipulate the data in ways that were not intended by the contract's author.

- Data Corruption: Malicious users could intentionally provide keys that result in the corruption or manipulation of important data stored in the mapping. This could lead to incorrect calculations, unauthorized access, or other undesirable outcomes.

- Denial-of-Service (DoS) Attacks: If users can set arbitrary keys, they may be able to create mappings with a large number of entries, potentially causing the contract to exceed its gas limit. This could lead to denial-of-service attacks, making the contract unusable for other users.

### Known problems

### Example

```rust
pub fn set_balance(env: Env, address: Address, balance: i128) -> State {
// Get the current state.
let mut state = Self::get_state(env.clone());

// Set the new account to have total supply if it doesn't exist.
if !state.balances.contains_key(address.clone()) {
state.balances.set(address, balance);
// Save the state.
env.storage().persistent().set(&STATE, &state);
}

state
}
```

Use instead:

```rust
pub fn set_balance(env: Env, address: Address, balance: i128) -> State {
// Authenticate user
address.require_auth();

// Get the current state.
let mut state = Self::get_state(env.clone());

// Set the new account to have total supply if it doesn't exist.
if !state.balances.contains_key(address.clone()) {
state.balances.set(address, balance);
// Save the state.
env.storage().persistent().set(&STATE, &state);
}

state
}
```

### Implementation

The detector's implementation can be found at [this link](https://github.com/CoinFabrik/scout-soroban/tree/main/detectors/unprotected-mapping-operation).
5 changes: 5 additions & 0 deletions docs/docs/vulnerabilities/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,9 @@ The assert! macro is used in Rust to ensure that a certain condition holds true

This vulnerability falls under the category [Validations and error handling](#vulnerability-categories) and has an Enhancement severity.

### Unprotected mapping operation

Modifying mappings with an arbitrary key given by the user could lead to unintented modifications of critical data, modifying data belonging to other users, causing denial of service, unathorized access, and other potential issues.

This vulnerability falls under the [Validations and error handling category](#vulnerability-categories) and assigned it a Critical severity.

0 comments on commit 49b7746

Please sign in to comment.