Programación segura

Rudy Godoy, Quinpu.com

Programación segura

Presentado por Rudy Godoy

Hands on the orange typewriter in a park
© John Carey

Contexto

ETH env.
© Rudy Godoy

Programas

  1. Escritos en lenguajes Solidity, LLL, Rust, o Serpent (Alto nivel)
EVM
© Rudy Godoy

Riesgo

Cada año muere más gente asesinada por cerdos que por tiburones, lo que demuestra cuan buenos somos evaluando el riesgo.

Bruce Schneier

Si crees que la tecnología puede resolver los problemas de seguridad, entonces no entiendes los problemas y tampoco la tecnología.

Bruce Schneier
Piensa
© Rudy Godoy

Historias de guerra

DAO

17 de junio 2016. Incidente más importante en Ethereum.

Aprovecha vulnerabilidad de llamada recursiva. Utiliza funcionalidad de votación propia de la DAO para forzar creación de DAOs hijos (splitDAO()) que, además, obtengan beneficios y fondos del padre y que repitan el proceso.

Resultado: Bifurcación de block chain: ETC y ETH.

Parity: billetera de firmas múltiples I

19 de julio 2017. Código auditado por la Fundación Ethereum.

  1. Código vulnerable identificado en initWallet(). Identifica programas en la red que lo usan.
  2. Ejecuta ataque en dos transacciones:
    1. tx 1: initWallet() para hacerse de la propiedad del programa/contrato
    2. tx 2: transfiere fondos hacia otra cuenta

Parity: billetera de firmas múltiples I

        function initWallet (address[] _owners, uint _required,
        uint _daylimit)  {
          initMultiOwned(_owners, _required);
          initDayLimit(_daylimit);
        }
      

Fondos robados: 150,000 ETH, cerca de USD 30MM. Recuperado buena parte usando mismo ataque.

Parity: billetera de firmas múltiples I

        function() payable {
         // just being sent some cash?
          if (msg.value > 0)
            Deposit(msg.sender, msg.value);
          else if (msg.data.length > 0)
            _walletLibrary.delegatecall(msg.data);
        }
    

Parity: billetera de firmas múltiples II

Hello, first of all i'm not the owner of that contract. I was able to make myself the owner of that contract because its uninitialized. These multi_sig wallets deployed using Parity were using the library located at "0x863df6bfa4469f3ead0be8f9f2aae51c91a907b4" address. I made myself the owner of "0x863df6bfa4469f3ead0be8f9f2aae51c91a907b4" contract and killed it and now when i query the dependent contracts "isowner(<any_addr>)" they all return TRUE because the delegate call made to a died contract. I believe some one might exploit.

Parity: billetera de firmas múltiples II

7 de noviembre 2017. Código de biblioteca Parity convertido a billetera de firmas múltiples.

  1. Código vulnerable en versión publicada el 20 de julio 2017
  2. Cualquier persona puede apropiarse y destruir programa.
  3. Ataque similar a anterior:
    1. tx 1: Invoca a initWallet() para hacerse de la propiedad de biblioteca
    2. tx 2: Invoca selfdestruct() para destruirla

Parity: billetera de firmas múltiples II

        function initWallet(address[] _owners, uint _required,
        uint _daylimit) only_uninitialized {
          initDaylimit(_daylimit);
          initMultiowned(_owners, _required);
        }
      

Resultado: Cerca a 513 mil ETH inamovibles en billeteras dependientes de biblioteca (Ejm. Polkadot).

extraData : Consensys HumanStandardToken

31 de marzo 2017.

Invocación de llamada bajo nivel con un arreglo de bytes como parámetro no intepreta correctamente de acuerdo a definición del ABI, solo lo añade al resto de la cadena.

Informe del problema: https://github.com/ConsenSys/Tokens/pull/45 Todavía no resuelto.

Ganador de USCC: Kings of Rountable

Web: https://github.com/Arachnid/uscc/blob/master/submissions-2017/martinswende/

USCC Roundtable
© Rudy Godoy
Piensa
© Rudy Godoy

OpenZeppelin

OpenZeppelin

Biblioteca de contratos reutilizables y seguros en Solidity.

npm install zeppelin-solidity,

yarn add zeppelin-solidity o

git submodule add https://github.com/OpenZeppelin/zeppelin-solidity

Web: openzeppelin.org

OpenZeppelin

Contratos base o plantillas y ejemplos de implementación con conjunto de pruebas automatizadas

  1. crowdsale: Crodwsale (ICO)
  2. lifecycle: Destrutible, Pausable
  3. ownership: CanReclaim, Claimable, Contactable, DelayedClaimable, Ownable
  4. payment: PullPayment
  5. token: Basic, Burnable, Mintable, Pausable, Standard, Timelock, Vesting

OpenZeppelin: Tokens

        pragma solidity ^0.4.11;
        import 'zeppelin-solidity/contracts/token/ERC20Basic.sol';
        import 'zeppelin-solidity/contracts/math/SafeMath.sol';
        contract WhitelistToken is ERC20Basic {
          using SafeMath for uint256;
          mapping(address => uint256) balances;
          mapping(address => bool) whitelist;
      

📜 ERC20Basic.sol

OpenZeppelin: BurnableToken

        pragma solidity ^0.4.13;
        import 'zeppelin-solidity/contracts/token/BurnableToken.sol';
        contract LimToken is BurnableToken {
        function LimToken(address initialAccount, uint initialBalance) {
          balances[initialAccount] = initialBalance;
          totalSupply = initialBalance;
          }
      

📜 BurnableToken.sol

OpenZeppelin: Hagamos una ICO

        import 'zeppelin-solidity/contracts/crowdsale/CappedCrowdsale.sol';
        contract LimaICO is CappedCrowdsale {
          function LimaICO ( uint256 _startTime, uint256 _endTime, uint256 _rate,
  address _wallet, uint256 _cap )
      Crowdsale(_startTime, _endTime, _rate, _wallet)
      CappedCrowdsale(_cap) { }
    }
      

📜 CappedCrowdsale.sol

OpenZeppelin: ¿Porqué usarlo?

Documentación: http://zeppelin-solidity.readthedocs.io/en/latest/

github.com/rudygodoy