Skip to content

Note Script Documentation Promises Sender Authorization That AuthControlled Accounts Do Not Enforce #3499

Description

@onurinanc

A Miden account can be administered by consuming a note. The PauseAction note instructs the account that consumes it to pause or unpause itself, and the account decides whether to permit the request through its account-wide Authority component. Authority supports three modes, all three of which PausableManager declares as supported. Under OwnerControlled and RbacControlled, the shared helper assert_authorized resolves the note sender and fails if that sender is not the owner or does not hold the required role. Under AuthControlled, assert_authorized performs no check at all and returns immediately, deferring the entire decision to the account authentication component.

The documentation of the PauseAction note states the sender check unconditionally. It describes authorization as bound to the note sender, states that the Authority component resolves the note sender against the configured owner or role, and lists an unauthorized sender as a condition under which the script fails. None of that holds for an account in AuthControlled mode, where no sender is resolved and no such failure occurs. The same wording appears in the FaucetPolicyAction note and in the public Rust documentation of PauseAction and PauseActionNote, the latter contradicted four lines later by its own qualification naming only OwnerControlled and RbacControlled.

The crate documents the opposite requirement elsewhere. The safety invariant on Authority states that under AuthControlled the authentication component is the sole gate and must authenticate every authority-gated procedure, otherwise those procedures become permissionless. A reader who consults the note documentation instead may skip that step. As an example, an integrator combining Authority::AuthControlled with an authentication component that admits transactions by allowlisting note script roots, as AuthNetworkAccount does, would have no reason to add a separate authorization check on pause and unpause, because the note documentation states that the sender is already verified. Any party could then create a PauseAction note and pause or unpause that account. A single script root serves both actions, and the creator selects between them through note storage, so allowlisting that root grants both. No account constructed in this repository is in that configuration: every factory that installs AuthControlled alongside PausableManager pairs it with a signature-requiring authentication component, and no allowlist contains the PauseAction script root. The finding is therefore an inaccuracy in documentation rather than an exploitable condition in the current code.

Consider qualifying the affected doc comments so that they name all three Authority modes instead of asserting a sender check unconditionally, in the note scripts and in the mirrored Rust documentation alike, and aligning the stated failure conditions with the phrasing the lower-level components already use, which refers to the caller not being authorized per the installed Authority component without claiming a sender check. Cross-referencing the AuthControlled safety invariant from the note documentation would additionally direct a reader who encounters the note first toward the configuration requirement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions