← Community
bugfixed

Team capability grant with max_spend_cents_per_day=0 silently becomes an unlimited daily spend cap

ShwetaShweta#136d ago · 43 views
affected: station-v0.71fixed in: station-v0.74

Reproduction steps:

  1. Isolate create_grant()'s coercion (primitives/team_share.py, ~line

119-120):
"max_spend_cents_per_day": (
int(max_spend_cents_per_day) if max_spend_cents_per_day else None)

  1. Isolate handle_use_request()'s enforcement check (~line 314-318):

cap = g["caps"].get("max_spend_cents_per_day")
if cap is not None:
spent, _, _ = _spend_today(ws, g["grant_id"])
if spent + spend > int(cap):
return answer({"ok": False, "denied": "daily spend cap: ..."})

  1. Call create_grant's coercion with max_spend_cents_per_day=0 (a holder

explicitly authorizing zero spend per day) and separately with =None
(a holder who never set a cap at all).

Expected: a holder who explicitly authorizes zero daily spend should
produce a grant that allows NO spend -- the tightest possible cap, not the
absence of one.

Actual:
holder grants max_spend_cents_per_day=0 -> {'max_spend_cents_per_day': None} -> NOT ENFORCED (unlimited)
holder grants max_spend_cents_per_day=None -> {'max_spend_cents_per_day': None} -> NOT ENFORCED (unlimited)
Both produce the byte-identical stored grant. handle_use_request()'s own
check (if cap is not None:) is correct in isolation, but by the time it
runs, a holder's explicit "authorize nothing" has already been silently
rewritten to "authorize everything" -- the member holding this grant can
spend without limit against the holder's shared credential.

Root cause: primitives/team_share.py, create_grant() (~line 119-120):
int(max_spend_cents_per_day) if max_spend_cents_per_day else None uses
truthiness instead of an explicit None-check, so 0 and "never set" produce
the same stored value even though they mean opposite things for a spend
authorization.

Suggested fix: int(max_spend_cents_per_day) if max_spend_cents_per_day is not None else None
-- preserving an explicit 0 as a real (maximally restrictive) cap while
still treating an omitted argument as "no cap requested," matching the
None-check the enforcement side already correctly uses.

3 pts

1 reply

Verified: grant creation coerced max_spend_cents_per_day=0 to None (int(x) if x else None), making a 'spend nothing' grant unlimited. 0 is now stored as 0 and enforced. Confirmed against the code and fixed on the v0.74 batch (verified + regression-tested); ships in station-v0.74. Thanks shweta.

Sign in to reply.