Skip to content

Detector Documentation

Vara Prasad Bandaru edited this page Feb 9, 2023 · 1 revision

Detectors

List of detectors

Deletable Application

Configuration

  • Check: is-deletable
  • Applicable to: Stateful
  • Severity: High
  • Confidence: High

Description

Application can be deleted by sending an DeleteApplication type application call.

Exploit Scenario:

@router.method(delete_application=CallConfig.CALL)
def delete_application() -> Expr:
    return Assert(Txn.sender() == Global.creator_address())

Eve steals application creator's private key and deletes the application. Application's assets are permanently lost.

Recommendation

Do not approve DeleteApplication type application calls.

Upgradable Application

Configuration

  • Check: is-updatable
  • Applicable to: Stateful
  • Severity: High
  • Confidence: High

Description

Application can be updated by sending an UpdateApplication type application call.

Exploit Scenario:

@router.method(update_application=CallConfig.CALL)
def update_application() -> Expr:
    return Assert(Txn.sender() == Global.creator_address())

Creator updates the application and steals all of its assets.

Recommendation

Do not approve UpdateApplication type application calls.

Unprotected Deletable Application

Configuration

  • Check: unprotected-deletable
  • Applicable to: Stateful
  • Severity: High
  • Confidence: High

Description

Application can be deleted by anyone. More at building-secure-contracts/not-so-smart-contracts/algorand/access_controls.

Exploit Scenario:

@router.method(delete_application=CallConfig.CALL)
def delete_application() -> Expr:
    return Approve()

Eve calls delete_application method and deletes the application making its assets permanently inaccesible.

Recommendation

  • Avoid deletable applications.
  • Add access controls to the vulnerable method.

Unprotected Upgradable Application

Configuration

  • Check: unprotected-updatable
  • Applicable to: Stateful
  • Severity: High
  • Confidence: High

Description

Application can be updated by anyone. More at building-secure-contracts/not-so-smart-contracts/algorand/access_controls.

Exploit Scenario:

@router.method(update_application=CallConfig.CALL)
def update_application() -> Expr:
    return Approve()

Eve updates the application by calling update_application method and steals all of its assets.

Recommendation

  • Avoid upgradable applications.
  • Add access controls to the vulnerable method.

Missing GroupSize Validation

Configuration

  • Check: group-size-check
  • Applicable to: Stateless, Stateful
  • Severity: High
  • Confidence: High

Description

Contract's execution depends on multiple transactions in the group and it uses absolute index to access information of other transactions in the group. Attacker can exploit the contract by abusing the lack of validations on GroupSize. More at building-secure-contracts/not-so-smart-contracts/algorand/group_size_check

Exploit Scenario:

def mint_wrapped_algo() -> Expr:
    validations = Assert(
        And(
            Gtxn[0].receiver() == Global.current_application_address(),
            Gtxn[0].type_enum() == TxnType.Payment,
        )
    )
    transfer_op = transfer_wrapped_algo(Txn.sender(), Gtxn[0].amount())
    return Seq([validations, transfer_op, Approve()])

Eve sends the following group transaction:

0. Payment of 1 million ALGOs to application address
1. Call mint_wrapped_algo
2. Call mint_wrapped_algo
...
15. Call mint_wrapped_algo

Eve receives 15 million wrapped-algos instead of 1 million wrapped-algos. Eve exchanges the Wrapped-algo to ALGO and steals 14 million ALGOs.

Recommendation

  • Avoid using absolute indexes. Validate GroupSize if used.
  • Favor using ARC-4 ABI and relative indexes for group transactions.

Missing CloseRemainderTo Field Validation

Configuration

  • Check: can-close-account
  • Applicable to: Stateless
  • Severity: High
  • Confidence: High

Description

LogicSig does not validate CloseRemainderTo field. Attacker can submit a transaction with CloseRemainderTo field set to their address and steal all of account's ALGOs. More at building-secure-contracts/not-so-smart-contracts/algorand/closing_account

Exploit Scenario:

def withdraw(...) -> Expr:
    return Seq(
        [
            Assert(
                And(
                    Txn.type_enum() == TxnType.Payment,
                    Txn.first_valid() % period == Int(0),
                    Txn.last_valid() == Txn.first_valid() + duration,
                    Txn.receiver() == receiver,
                    Txn.amount() == amount,
                    Txn.first_valid() < timeout,
                )
            ),
            Approve(),
        ]
    )

Alice signs the logic-sig to allow recurring payments to Bob. Eve uses the logic-sig and submits a valid transaction with CloseRemainderTo field set to her address. Eve steals Alice's ALGO balance.

Recommendation

Validate CloseRemainderTo field in the LogicSig.

Missing AssetCloseTo Field Validation

Configuration

  • Check: can-close-asset
  • Applicable to: Stateless
  • Severity: High
  • Confidence: High

Description

LogicSig does not validate AssetCloseTo field. Attacker can submit a transaction with AssetCloseTo field set to their address and steal account's assets. More at building-secure-contracts/not-so-smart-contracts/algorand/closing_asset

Exploit Scenario:

def withdraw(...) -> Expr:
    return Seq(
        [
            Assert(
                And(
                    Txn.type_enum() == TxnType.AssetTransfer,
                    Txn.first_valid() % period == Int(0),
                    Txn.last_valid() == Txn.first_valid() + duration,
                    Txn.asset_receiver() == receiver,
                    Txn.asset_amount() == amount,
                    Txn.first_valid() < timeout,
                )
            ),
            Approve(),
        ]
    )

Alice signs the logic-sig to allow recurring payments to Bob in USDC. Eve uses the logic-sig and submits a valid transaction with AssetCloseTo field set to her address. Eve steals Alice's USDC balance.

Recommendation

Validate AssetCloseTo field in the LogicSig.

Missing Fee Field Validation

Configuration

  • Check: missing-fee-check
  • Applicable to: Stateless
  • Severity: High
  • Confidence: High

Description

LogicSig does not validate Fee field. Attacker can submit a transaction with Fee field set to large value and drain the account balance. More at building-secure-contracts/not-so-smart-contracts/algorand/unchecked_transaction_fee

Exploit Scenario:

def withdraw(...) -> Expr:
    return Seq(
        [
            Assert(
                And(
                    Txn.type_enum() == TxnType.Payment,
                    Txn.first_valid() % period == Int(0),
                    Txn.last_valid() == Txn.first_valid() + duration,
                    Txn.receiver() == receiver,
                    Txn.amount() == amount,
                    Txn.first_valid() < timeout,
                )
            ),
            Approve(),
        ]
    )

Alice signs the logic-sig to allow recurring payments to Bob. Eve uses the logic-sig and submits a valid transaction with Fee set to 1 million ALGOs. Alice loses 1 million ALGOs.

Recommendation

Validate Fee field in the LogicSig.

Rekeyable LogicSig

Configuration

  • Check: rekey-to
  • Applicable to: Stateless
  • Severity: High
  • Confidence: High

Description

Logic signature does not validate RekeyTo field. Attacker can submit a transaction with RekeyTo field set to their address and take control over the account. More at building-secure-contracts/not-so-smart-contracts/algorand/rekeying

Exploit Scenario:

def withdraw(...) -> Expr:
    return Seq(
        [
            Assert(
                And(
                    Txn.type_enum() == TxnType.Payment,
                    Txn.first_valid() % period == Int(0),
                    Txn.last_valid() == Txn.first_valid() + duration,
                    Txn.receiver() == receiver,
                    Txn.amount() == amount,
                    Txn.first_valid() < timeout,
                )
            ),
            Approve(),
        ]
    )

Alice signs the logic-sig to allow recurring payments to Bob.Eve uses the logic-sig and submits a valid transaction with RekeyTo field set to her address.Eve takes over Alice's account.

Recommendation

Validate RekeyTo field in the LogicSig.