#1814·apitable

APITable: fail-open NodePermissionGuard allows attachment write to denied private datasheets

Author: geo-chenCreated Jul 1, 2026Updated Jul 1, 2026
Labelsbug

reported via email on 13 June - no response:

I am reporting a fail-open authorization issue, confirmed against the real guard logic (unchanged) driving the backend-denial path. This is distinct from the prior internal-server findings; it is in the Node.js room-server Fusion guard.

NodePermissionGuard.matchPermissions (packages/room-server/src/fusion/middleware/guard/node.permission.guard.ts:55-65) does try { nodePermission = await getNodeRole(...) } catch(e){} then if (nodePermission) {...} return true. When the backend denies a private node it throws BusinessException(NODE_ACCESS_DENIED)=601; the room-server interceptor's responseCodeHandler(601) (: never) always throws, which unwinds into the empty catch -> nodePermission undefined -> loop skipped -> guard returns true. The two EDITABLE attachment endpoints (presignedUrl ~160, attachments POST ~186) rely on this guard (ApiDatasheetGuard checks only membership).

What I observed: compiling the unmodified guard and driving canActivate() with a getNodeRole that throws like the 601 path returned true despite denial, with the reflector supplying the real ['editable'] metadata.

Impact: a member denied a private datasheet can still upload attachments / get presigned URLs to it. CWE-636/862, ~4.3. Net-new: 0 advisories, no matching issue.

Suggested fix: fail closed in the catch (and on undefined) by throwing api_node_permission_error. A PoC is available.