DEV Community

Discussion on: A frozen field with one witness is still a claim

Collapse
 
_firelinks profile image
Mike Dabydeen •

I'd move approvals ahead of the labelling step in issue #8, because the same header decides who may approve, not only who gets recorded. _context() also reads X-AINE-Roles from the caller. decide_approval checks that role against required_roles, and an approval passes once the count of distinct actor_id values reaches required_approvals. So one caller can post two approve decisions under two X-AINE-Actor names, both sending X-AINE-Roles: approver, and clear required_approvals: 2. I also couldn't find a check that the deciding actor differs from requested_by, so a single required approval can be the requester's own.

The 127.0.0.1 default bind keeps this local today, which is probably why it hasn't mattered yet. It stops being local the first time someone puts the server behind a proxy so a team can share it.

Until token verification lands, I'd record decisions whose actor came from the header but not count them toward required_approvals. The test: create an approval with required_approvals 2, post two approve decisions over HTTP with different X-AINE-Actor values and the approver role, and expect it not to reach approved. A requester-cannot-approve check can ship next to it, since that one needs no token.

Thread Thread
 
williamchiu profile image
weiche chiu • • Edited

You were right to put approvals first, and it was worse than the role. decide_approval took roles from X-AINE-Roles, so a caller could name itself approver. The quorum counts distinct actor ids, and those come from X-AINE-Actor, so one caller could fill a quorum of two by sending two names.

Both are closed in PR #10 (github.com/williamlabdev/aine-cont...). Approval decisions now refuse any actor whose source is missing or "header", and record nothing. A consumer that verifies identity sets source (for example token) and keeps working. The cost is that the reference server can no longer decide approvals on its own; it needs a verifying layer in front.

One thing I left open: decisions recorded before the fix don't store their source, so they still count. Thanks for pushing on the order.