Skip to content

[Bug] create_assertion_as_self has no caller authentication #157

Description

@collinsezedike

Summary

create_assertion_as_self (contracts/asserter-consumer/src/lib.rs:36-66) has no require_auth() call at all. It accepts tholos_id, token_id, and bond_amount as plain caller-supplied arguments, then calls env.authorize_as_current_contract(...) to pre-authorize a token_id.transfer(this_contract, tholos_id, bond_amount) sub-invocation, and invokes tholos_id.assert_outcome(...).

Because none of the three arguments are validated against any trusted, previously-configured value, and there is no auth check on the caller at all, any address can invoke this function with a token_id matching a real token this contract holds a balance in, and a tholos_id the caller controls. The self-authorized transfer then moves funds out of this contract's balance to an address the caller effectively controls, with no signature or permission from the contract's actual owner/deployer required.

Impact: an attacker can drain this contract's entire balance in the affected token, repeatable, with no rate limit or state tracking preventing multiple calls.

Scope

  • Pin tholos_id and token_id to trusted values set once at initialize (a new function this contract doesn't currently have), rather than accepting them as per-call arguments.
  • Admin-gate create_assertion_as_self (or otherwise restrict who may call it) so an arbitrary address can't trigger a self-authorized transfer at all.
  • Add tests confirming the function rejects a mismatched/untrusted tholos_id or token_id, and that only an authorized caller can invoke it.

Proposed approach

Add an initialize(env, admin, tholos_id, token_id) entrypoint (matching the pattern in contracts/tholos/contracts/tholos-v2) that stores tholos_id/token_id in instance storage once, admin-gated. Change create_assertion_as_self to read those stored values instead of accepting them as parameters, and require the caller (or an explicitly configured operator) to authorize the call. This closes the gap without changing the demonstrated integration pattern's shape.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinghardSecurity-sensitive or high-complexity change

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions