Skip to content

unsafe-cross-contract-input taint tracking doesn't clear on variable shadowing — false positive on validated re-bindings #366

Description

@unrealtim-tech

Labels: bug, checks-crate
Crate: checks

Description
crates/checks/src/xc_input.rs's taint set xc_bindings: HashSet<String> (lines ~74-88) is keyed purely by variable name, and entries are never removed:

if let Stmt::Local(local) = stmt {
    if let Some(init) = &local.init {
        if is_invoke_contract(&init.expr) {
            if let Pat::Ident(pi) = &local.pat {
                self.xc_bindings.insert(pi.ident.to_string());
            }
        }
    }
}

Rust code that shadows a tainted binding with a validated value under the same name still trips the check:

let result = env.invoke_contract(&callee, &sym, ());   // tainted, "result" inserted
let result = if result > 0 { result } else { 0 };      // shadowed/validated
env.storage().persistent().set(&k, &result);           // false positive: "result" still tainted

The existing passing test sidesteps this by using a different variable name for the validated value, so this shadowing case has no coverage.

Acceptance Criteria

  • Clear (or replace) a binding's taint status when it is shadowed by a new let with the same name and a non-tainted initializer.
  • Add a test using the shadowing pattern above, asserting no finding once the shadowed value is validated.

Difficulty: intermediate

Metadata

Metadata

Assignees

No one assigned

    Labels

    Stellar WaveIssues in the Stellar wave programbugSomething isn't workingchecks-crate

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions