APP-69Required
Check every incoming change against the sender's rights
The collaboration server checks the sender's right to edit on every message that writes, not only when the connection opens. It drops writes from viewers and from people whose access has ended.
How to do it
A read-only editor screen only hides buttons. A modified client still sends edits over the open connection, as Enforce permissions on the server warns. Viewers still send read messages, such as the first step of a sync, so tell reads and writes apart. Recheck rights during the connection, as Check access when the connection opens and while it lasts says. Close the connection when a role changes, as Make role changes count on the next request requires. Limit message size and rate as Limit the connections and messages of each client says.
Examples
TypeScript example
socket.on('message', async (data: Buffer) => {
if (isWriteMessage(data) && !(await canEdit(session.userId, documentId))) {
log.warn({ userId: session.userId, documentId }, 'edit_refused');
return;
}
await handleSyncMessage(documentId, socket, data);
});
Python example
async def on_message(session: Session, document_id: str, message: bytes) -> None:
if is_write_message(message) and not await can_edit(session.user_id, document_id):
log.warning("edit_refused", extra={"user_id": session.user_id, "document_id": document_id})
return
await handle_sync_message(document_id, message)
How to check
A test connects as a viewer and sends a valid edit. The stored document does not change, and the server logs a refusal. After an editor is removed from the document, their next edit is refused.
Sources
Related rules
- APP-46 Enforce permissions on the server in Web app interface
- API-70 Check access when the connection opens and while it lasts in API design
- ACC-38 Make role changes count on the next request in Accounts and identity
- API-73 Limit the connections and messages of each client in API design
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/app-ui/live-collaboration/check-every-change">Agent Wranglers web app interface playbook</a>. In code you write, add a comment next to it with the same link.