-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #217 from CoinFabrik/167-add-new-detector-and-test…
…-cases-for-incorrect-exponentiation 167 add new detector and test cases for incorrect exponentiation
- Loading branch information
Showing
18 changed files
with
367 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ on: | |
- main | ||
paths: | ||
- "docs/**" | ||
workflow_dispatch: | ||
|
||
jobs: | ||
deploy: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ on: | |
- main | ||
paths: | ||
- "docs/**" | ||
workflow_dispatch: | ||
|
||
jobs: | ||
test-deploy: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
[package] | ||
name = "incorrect-exponentiation" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[lib] | ||
crate-type = ["cdylib"] | ||
|
||
[dependencies] | ||
scout-audit-clippy-utils = { workspace = true } | ||
dylint_linting = { workspace = true } | ||
if_chain = { workspace = true } | ||
|
||
|
||
[package.metadata.rust-analyzer] | ||
rustc_private = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
#![feature(rustc_private)] | ||
#![warn(unused_extern_crates)] | ||
|
||
extern crate rustc_hir; | ||
extern crate rustc_span; | ||
|
||
use rustc_hir::def_id::LocalDefId; | ||
use rustc_hir::intravisit::Visitor; | ||
use rustc_hir::intravisit::{walk_expr, FnKind}; | ||
use rustc_hir::{Body, FnDecl}; | ||
use rustc_hir::{Expr, ExprKind}; | ||
use rustc_lint::{LateContext, LateLintPass}; | ||
use rustc_span::Span; | ||
use scout_audit_clippy_utils::diagnostics::span_lint_and_help; | ||
|
||
const LINT_MESSAGE: &str = "'^' It is not an exponential operator. It is a bitwise XOR."; | ||
const LINT_HELP: &str = "If you want to use XOR, use bitxor(). If you want to raise a number use .checked_pow() or .pow() "; | ||
|
||
dylint_linting::declare_late_lint! { | ||
pub INCORRECT_EXPONENTIATION, | ||
Warn, | ||
LINT_MESSAGE, | ||
{ | ||
name: "Incorrect Exponentiation", | ||
long_message: LINT_MESSAGE, | ||
severity: "Critical", | ||
help: "https://coinfabrik.github.io/scout/docs/vulnerabilities/incorrect-exponentiation", | ||
vulnerability_class: "Arithmetic", | ||
} | ||
|
||
} | ||
|
||
impl<'tcx> LateLintPass<'tcx> for IncorrectExponentiation { | ||
fn check_fn( | ||
&mut self, | ||
cx: &LateContext<'tcx>, | ||
_: FnKind<'tcx>, | ||
_: &'tcx FnDecl<'_>, | ||
body: &'tcx Body<'_>, | ||
_: Span, | ||
_: LocalDefId, | ||
) { | ||
struct IncorrectExponentiationStorage { | ||
span: Vec<Span>, | ||
incorrect_exponentiation: bool, | ||
} | ||
|
||
impl<'tcx> Visitor<'tcx> for IncorrectExponentiationStorage { | ||
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { | ||
if let ExprKind::Binary(op, _, _) = &expr.kind { | ||
if op.node == rustc_hir::BinOpKind::BitXor { | ||
self.incorrect_exponentiation = true; | ||
self.span.push(expr.span); | ||
} | ||
} | ||
|
||
walk_expr(self, expr); | ||
} | ||
} | ||
|
||
let mut expon_storage = IncorrectExponentiationStorage { | ||
span: Vec::new(), | ||
incorrect_exponentiation: false, | ||
}; | ||
|
||
walk_expr(&mut expon_storage, body.value); | ||
|
||
if expon_storage.incorrect_exponentiation { | ||
for span in expon_storage.span.iter() { | ||
span_lint_and_help( | ||
cx, | ||
INCORRECT_EXPONENTIATION, | ||
*span, | ||
LINT_MESSAGE, | ||
None, | ||
LINT_HELP, | ||
); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# Incorrect Exponentiation | ||
|
||
### What it does | ||
|
||
Warns about `^` being a `bit XOR` operation instead of an exponentiation. | ||
|
||
### Why is this bad? | ||
|
||
It can introduce unexpected behaviour in the smart contract. | ||
|
||
#### More info | ||
|
||
- https://doc.rust-lang.org/std/ops/trait.BitXor.html#tymethod.bitxor | ||
|
||
### Example | ||
|
||
```rust | ||
pub fn init(e: Env){ | ||
e.storage() | ||
.instance() | ||
.set::<DataKey, u128>(&DataKey::Data, &((255_u128 ^ 2) - 1)); | ||
} | ||
``` | ||
Use instead: | ||
|
||
```rust | ||
pub fn init(e: Env) { | ||
e.storage() | ||
.instance() | ||
.set::<DataKey, u128>(&DataKey::Data, &(255_u128.pow(2) - 1)); | ||
} | ||
``` | ||
|
||
### Implementation | ||
|
||
The detector's implementation can be found at [this link](https://github.com/CoinFabrik/scout-soroban/tree/main/detectors/incorrect-exponentiation). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# Incorrect Exponentiation | ||
|
||
## Description | ||
|
||
- Vulnerability Category: `Arithmetic` | ||
- Vulnerability Severity: `Critical` | ||
- Detectors: [`incorrect-exponentiation`](https://github.com/CoinFabrik/scout-soroban/tree/main/detectors/incorrect-exponentiation) | ||
- Test Cases: [`incorrect-exponentiation-1`](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/incorrect-exponentiation/incorrect-exponentiation-1) | ||
|
||
|
||
The operator `^` is not an exponential operator, it is a bitwise XOR. Make sure to use `pow()` instead for exponentiation. In case of performing a XOR operation, use `.bitxor()` for clarity. | ||
|
||
## Exploit Scenario | ||
|
||
In the following example, the `^` operand is being used for exponentiation. But in Rust, `^` is the operand for an XOR operation. If misused, this could lead to unexpected behaviour in our contract. | ||
|
||
```rust | ||
pub fn exp_data_3(e: Env) -> u128 { | ||
let mut data = e.storage() | ||
.instance() | ||
.get::<DataKey, u128>(&DataKey::Data) | ||
.expect("Data not found"); | ||
|
||
data ^= 3; | ||
data | ||
} | ||
``` | ||
|
||
The vulnerable code example can be found [`here`](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/incorrect-exponentiation/incorrect-exponentiation-1/vulnerable-example). | ||
|
||
## Remediation | ||
|
||
A possible solution is to use the method `pow()`. But, if a XOR operation is wanted, `.bitxor()` method is recommended. | ||
|
||
```rust | ||
pub fn exp_data_3(e: Env) -> u128 { | ||
let data = e.storage() | ||
.instance() | ||
.get::<DataKey, u128>(&DataKey::Data) | ||
.expect("Data not found"); | ||
|
||
data.pow(3) | ||
} | ||
``` | ||
|
||
The remediated code example can be found [`here`](https://github.com/CoinFabrik/scout-soroban/tree/main/test-cases/incorrect-exponentiation/incorrect-exponentiation-1/remediated-example). | ||
|
||
## References | ||
|
||
- https://doc.rust-lang.org/std/ops/trait.BitXor.html | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
[workspace] | ||
exclude = [".cargo", "target"] | ||
members = ["incorrect-exponentiation-*/*"] | ||
resolver = "2" | ||
|
||
[workspace.dependencies] | ||
soroban-sdk = { version = "20.3.2" } | ||
|
||
[profile.release] | ||
codegen-units = 1 | ||
debug = 0 | ||
debug-assertions = false | ||
lto = true | ||
opt-level = "z" | ||
overflow-checks = true | ||
panic = "abort" | ||
strip = "symbols" | ||
|
||
[profile.release-with-logs] | ||
debug-assertions = true | ||
inherits = "release" |
16 changes: 16 additions & 0 deletions
16
test-cases/incorrect-exponentiation/incorrect-exponentiation-1/remediated-example/Cargo.toml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
[package] | ||
name = "incorrect-exponentiation-remediated-1" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[lib] | ||
crate-type = ["cdylib"] | ||
|
||
[dependencies] | ||
soroban-sdk = { workspace = true } | ||
|
||
[dev-dependencies] | ||
soroban-sdk = { workspace = true, features = ["testutils"] } | ||
|
||
[features] | ||
testutils = ["soroban-sdk/testutils"] |
Oops, something went wrong.