GuardRails

GuardRails

  • Languages iconEnglish
    • 中文

›Solidity

Overview

  • Introduction
  • What is GuardRails
  • Getting started
  • Findings
  • Vulnerabilities
  • Configuration
  • Custom Engines
  • False Positives
  • Enforce Passing Checks
  • Build Status on Pull Requests
  • FAQ
  • Pricing
  • Glossary
  • Tools & Licenses

API

  • Usage Guide
  • Endpoints

Vulnerabilities

  • Introduction
  • General

    • Overview
    • Hard-Coded Secrets

    Apex

    • Overview
    • Insecure Access Control
    • Insecure Network Communication
    • Insecure Processing of Data
    • Insecure Use of Cryptography
    • Insecure Use of Language/Framework API
    • Insecure Use of SQL Queries

    C/C++

    • Overview
    • Insecure Access Control
    • Insecure File Management
    • Insecure Processing of Data
    • Insecure Use of Cryptography
    • Insecure Use of Dangerous Function

    Dotnet

    • Overview
    • Insecure Access Control
    • Insecure Configuration
    • Insecure File Management
    • Insecure Processing of Data
    • Insecure Use of Cryptography
    • Insecure Use of Dangerous Function
    • Insecure Use of SQL Queries
    • Using Vulnerable Libraries

    Elixir

    • Overview
    • Insecure Configuration
    • Insecure File Management
    • Insecure Processing of Data
    • Insecure Network Communication
    • Insecure Use of Dangerous Function
    • Insecure Use of Language/Framework API
    • Insecure Use of SQL Queries
    • Using Vulnerable Libraries

    Go

    • Overview
    • Insecure File Management
    • Insecure Network Communication
    • Insecure Processing of Data
    • Insecure Use of Cryptography
    • Insecure Use of Dangerous Function
    • Insecure Use of SQL Queries
    • Using Vulnerable Libraries

    Java

    • Overview
    • Using Vulnerable Libraries
    • Insecure Use of SQL Queries
    • Insecure Use of Dangerous Function
    • Insecure Use of Regular Expressions
    • Insecure Authentication
    • Insecure Configuration
    • Insecure File Management
    • Insecure Use of Cryptography
    • Insecure Use of Language/Framework API
    • Insecure Processing of Data
    • Insecure Network Communication

    Javascript/TypeScript

    • Overview
    • Insecure Authentication
    • Insecure Processing of Data
    • Insecure Use of SQL Queries
    • Insecure Use of Regular Expressions
    • Insecure Use of Language/Framework API
    • Insecure Use of Dangerous Function
    • Using Vulnerable Libraries

    Kubernetes

    • Overview
    • Insecure Access Control
    • Insecure Configuration
    • Insecure Network Communication

    PHP

    • Overview
    • Insecure Configuration
    • Insecure File Management
    • Insecure Network Communication
    • Insecure Processing of Data
    • Insecure Use of Dangerous Function
    • Insecure Use of Language/Framework API
    • Insecure Use of Regular Expressions
    • Insecure Use of SQL Queries
    • Using Vulnerable Libraries

    Python

    • Overview
    • Insecure Configuration
    • Insecure Use of Cryptography
    • Insecure Network Communication
    • Insecure Processing of Data
    • Insecure Use of Dangerous Function
    • Insecure Use of SQL Queries
    • Using Vulnerable Libraries

    Ruby

    • Overview
    • Insecure Access Control
    • Insecure Configuration
    • Insecure File Management
    • Insecure Network Communication
    • Insecure Processing of Data
    • Insecure Use of Dangerous Function
    • Insecure Use of Language/Framework API
    • Insecure Use of Regular Expressions
    • Insecure Use of SQL Queries
    • Using Vulnerable Libraries

    Rust

    • Overview
    • Using Vulnerable Libraries

    Solidity

    • Overview
    • Insecure Integer Arithmetic
    • Insecure Use of Low-Level Call
    • Reliance on Insecure Random Numbers
    • State Change After External Call
    • Transaction Order Dependence
    • Unprotected Critical Function
    • Use of Insecure Function
    • Dependence on Predictable Environment Variables
    • Write to Arbitrary Storage Location
    • Call to Untrusted Contract

    Terraform

    • Overview
    • Hard-Coded Secrets
    • Insecure Access Control
    • Insecure Configuration
    • Insecure Network Communication
    • Insecure Use of Cryptography

Write to Arbitrary Storage Location

Why is this important?

A smart contract's data (e.g., storing the owner of the contract) is persistently stored at some storage location (i.e., a key or address) on the EVM level. The contract is responsible for ensuring that only authorized user or contract accounts may write to sensitive storage locations. If an attacker is able to write to arbitrary storage locations of a contract, the authorization checks may easily be circumvented. This can allow an attacker to corrupt the storage; for instance, by overwriting a field that stores the address of the contract owner.

Avoid Writing to Arbitrary Storage Location

Option A: Prevent overwrite of data structures

  1. Go through the issues that GuardRails identified in the PR.
  2. Identify the code that looks like this:
  pragma solidity ^0.4.25;

  contract Wallet {
    uint[] private bonusCodes;
    address private owner;

    constructor() public {
      bonusCodes = new uint[](0);
      owner = msg.sender;
    }

    function () public payable {
    }

    function PushBonusCode(uint c) public {
      bonusCodes.push(c);
    }

    function PopBonusCode() public {
      require(0 <= bonusCodes.length);
      bonusCodes.length--;
    }

    function UpdateBonusCodeAt(uint idx, uint c) public {
      require(idx < bonusCodes.length);
      // This is the vulnerable line of code
      bonusCodes[idx] = c;
    }

    function Destroy() public {
      require(msg.sender == owner);
      selfdestruct(msg.sender);
    }
  }
  1. As a general advice, given that all data structures share the same storage (address) space, one should make sure that writes to one data structure cannot inadvertently overwrite entries of another data structure.
  pragma solidity ^0.4.25;

  contract Wallet {
    uint[] private bonusCodes;
    address private owner;

    constructor() public {
      bonusCodes = new uint[](0);
      owner = msg.sender;
    }

    function () public payable {
    }

    function PushBonusCode(uint c) public {
      bonusCodes.push(c);
    }

    function PopBonusCode() public {
      require(0 < bonusCodes.length);
      bonusCodes.length--;
    }

    function UpdateBonusCodeAt(uint idx, uint c) public {
      require(idx < bonusCodes.length); //Since you now have to push every code this is no longer an arbitrary write.
      bonusCodes[idx] = c;
    }

    function Destroy() public {
      require(msg.sender == owner);
      selfdestruct(msg.sender);
    }
  }
  1. Test it
  2. Ship it 🚢 and relax 🌴

More information

  • Smart Contract Weakness Classification (SWC 124)
  • Common Weakness Enumeration (CWE-123)
← Dependence on Predictable Environment VariablesCall to Untrusted Contract →
  • Why is this important?
  • Avoid Writing to Arbitrary Storage Location
    • Option A: Prevent overwrite of data structures
  • More information
  • Status
  • Help
  • Security
  • Terms
  • Privacy

© 2021 GuardRails