Skip to content

fix: API-key destination allowlist bypass#1099

Open
Saladerl wants to merge 1 commit into
tempoxyz:mainfrom
Saladerl:fix/fee-payer-allowlist-bypass
Open

fix: API-key destination allowlist bypass#1099
Saladerl wants to merge 1 commit into
tempoxyz:mainfrom
Saladerl:fix/fee-payer-allowlist-bypass

Conversation

@Saladerl

Copy link
Copy Markdown

Security Advisory: API-key destination allowlist bypass

Severity High
Class Authorization bypass / fee-sponsorship abuse
Component apps/fee-payer rate-limit middleware
Status Fixed in this change

⚠️ Impact

A sponsorship API key may be provisioned with allowedDestinations to restrict
which contracts it is permitted to pay gas for. The enforcement check was gated
behind a truthiness test on the resolved destination:

if (apiKeyRecord.allowedDestinations.length > 0 && to) { ... }

to is resolved as transaction.calls?.[0]?.to ?? transaction.to. For a
contract-creation transaction — or any deserialized envelope where neither
field is present — to is undefined. The && to guard then short-circuits
and the entire allowlist branch is skipped, so the request is sponsored
regardless of the key's configured allowlist.

A holder of a restricted key can therefore have arbitrary to-less
transactions (including contract deployments) paid for by the sponsor,
defeating the destination restriction entirely.

Resolution

The check now fails closed. When an allowlist is configured, an
undeterminable destination is treated as "not allowed" and the request is
rejected with 403:

if (apiKeyRecord.allowedDestinations.length > 0) {
  const dest = to?.toLowerCase()
  const allowed = dest !== undefined &&
    apiKeyRecord.allowedDestinations.some((a) => a.toLowerCase() === dest)
  if (!allowed) return c.json({ error: 'Destination address not allowed ...' }, 403)
}

Keys with an empty allowedDestinations array are unaffected (unrestricted).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant