Skip to content
Papermerge Core Issues 1291

Papermerge Core Issues 1291

github.com • October 15, 2026

Several API endpoints have missing or insufficient authorization checks, allowing authenticated users to access or modify resources belonging to other users or groups.

Finding 1: Shared Node Access — Scope Mismatch + Missing Ownership Check

File: papermerge/core/features/shared_nodes/router.py

The PATCH /shared-nodes/access/{node_id} endpoint (line 103) has two issues:

Scope mismatch (line 109): The endpoint requires scopes.SHARED_NODE_VIEW but should require scopes.SHARED_NODE_UPDATE (as stated in the docstring at line 104). Users with only VIEW permissions can modify shared node access.

Scope mismatch (line 109): The endpoint requires scopes.SHARED_NODE_VIEW but should require scopes.SHARED_NODE_UPDATE (as stated in the docstring at line 104). Users with only VIEW permissions can modify shared node access.

Missing ownership check (lines 103-123): Neither the PATCH nor the GET /shared-nodes/access/{node_id} verifies that the requesting user owns the node. Any authenticated user with SHARED_NODE_VIEW scope can view who has access to any node and modify sharing permissions on any node.

Missing ownership check (lines 103-123): Neither the PATCH nor the GET /shared-nodes/access/{node_id} verifies that the requesting user owns the node. Any authenticated user with SHARED_NODE_VIEW scope can view who has access to any node and modify sharing permissions on any node.

Compare with the nodes router which correctly uses user_can_access_resource() checks.

Finding 2: Tags /all — Missing Group Membership Check

File: papermerge/core/features/tags/router.py lines 43-72

The GET /tags/all endpoint accepts a group_id parameter. The docstring (lines 50-55) explicitly states a 403 should be raised if the user doesn't belong to the group, but the implementation skips this check.

Compare with the correct implementation in custom_fields/router.py lines 59-63:

Finding 3: Document Types /all — Missing Group Membership Check

File: papermerge/core/features/document_types/router.py lines 39-66

Same pattern as tags. The GET /document-types/all accepts group_id with docstring promising a 403 check, but the code directly queries without verifying group membership.

shared_nodes/router.py:109 — Change scopes.SHARED_NODE_VIEW to scopes.SHARED_NODE_UPDATE

shared_nodes/router.py:82-123 — Add ownership verification via ownership_api.user_can_access_resource()

tags/router.py:59-72 — Add user_dbapi.user_belongs_to() check (match custom_fields pattern)

document_types/router.py:55-62 — Add user_dbapi.user_belongs_to() check (match custom_fields pattern)

ciur self-assigned this on Feb 28, 2026

ciur added security on Feb 28, 2026

marfoerst added high confirmed on Sep 19, 2026

Jalst closed this as completed in #1324 on Sep 24, 2026

Jalst added a commit that references this issue on Sep 24, 2026 fix: authorization checks in shared nodes, tags, and document types ( #… 0fd4691

fix: authorization checks in shared nodes, tags, and document types ( #…

Extracted Entities

Attack Types (1)