Commit graph

7 commits

Author SHA1 Message Date
Manish Gupta
d25b99cae2
[WEB-8110] fix: sanitize page list order_by against an allowlist (#9387)
* [WEB-8110] fix: sanitize page list order_by against an allowlist (GHSA-2v48)

PageViewSet.get_queryset passed the raw order_by query param into
.order_by(). In Django 4.2 .order_by() resolves field names at call time,
so an unknown field (e.g. order_by=password) raises FieldError → 500 DoS,
and a valid relation path (e.g. order_by=owned_by__password) enables ORM
relational traversal (GHSA-2v48-qcjw-74ch).

Add PAGE_ORDER_BY_ALLOWLIST to utils/order_queryset.py and wrap the param
with the existing sanitize_order_by() before it reaches .order_by(),
matching the issue/project/view/notification endpoints. Unknown or
malformed values fall back to the safe -created_at default.

Covers only the app project-pages residual; the 3 external-REST-API sites
in the advisory are handled by PR #9348. EE Wiki counterpart: WEB-8111.

Add contract regression tests (fail-before verified).

Co-authored-by: Plane AI <noreply@plane.so>

* [WEB-8110] fix: fold sanitized order_by into a single order_by() call (review)

Address CodeRabbit + Copilot on #9387: the sanitized .order_by(user) was
immediately overridden by a later .order_by("-is_favorite", "-created_at"),
so the order_by param had no effect on the result (dead code) and cost an
extra query-build step.

Merge them into one .order_by("-is_favorite", <sanitized>, "id") — matching
the EE project-pages viewset — so favourites stay pinned first, the
allowlisted user ordering actually applies as the secondary sort, and id is
a stable pagination tiebreak. The no-param default is unchanged
(-created_at). Add a test asserting order_by=name / -name actually reorders
the results.

Co-authored-by: Plane AI <noreply@plane.so>

* chore(security): drop advisory identifiers from code comments

Explanations kept unchanged; only the IDs are removed.

Co-authored-by: Plane AI <noreply@plane.so>

---------

Co-authored-by: Plane AI <noreply@plane.so>
2026-08-28 00:16:47 +05:30
Akhil Vamshi Konam
7cef741c29
feat(api): add lite list endpoints for projects, members, cycles, and modules (#9410)
* feat: add lite list endpoints for projects, members, cycles, and modules

* refactor: enhance order_by sanitization for cycle and module endpoints, update error handling for non-existent projects and workspaces
2026-07-17 17:40:26 +05:30
Manish Gupta
d3d3de44cf
[WEB-8012] fix: prevent ORM group_by/sub_group_by injection in issue endpoints (#9347)
Add ISSUE_GROUP_BY_ALLOWLIST and validate group_by_field_name/
sub_group_by_field_name in BasePaginator.paginate() — the single chokepoint
all GroupedOffsetPaginator/SubGroupedOffsetPaginator callers funnel through
(the unauthenticated public deploy-board endpoint plus 5 GUEST-reachable
authenticated endpoints). Invalid fields now raise ParseError (HTTP 400)
instead of reaching F()/.values()/.order_by()/Window partition_by as a raw
ORM field name, which previously let an anonymous caller crash the endpoint
or force a blind relational-traversal oracle (GHSA-wwgj-929g-42cm).

Same field-name-injection class as the order_by fix (GHSA-2r95/GHSA-w45q,
WEB-7813), which never extended to group_by/sub_group_by.

Closes WEB-8012

Co-authored-by: Plane AI <noreply@plane.so>
2026-07-13 20:40:01 +05:30
Manish Gupta
cc3eb974f1
[WEB-7813] fix: prevent ORM order_by injection in issue and other endpoints (#9292)
* fix: prevent ORM order_by injection via user-supplied query params (GHSA-2r95, GHSA-w45q)

Add field-name allowlists and a sanitize_order_by() utility in order_queryset.py.
All allowlists are centralised there; each call site imports the named constant
so there are no inline sets scattered across view files.

- order_queryset.py: ISSUE_ORDER_BY_ALLOWLIST, INTAKE_ISSUE_ORDER_BY_ALLOWLIST,
  ACTIVITY_ORDER_BY_ALLOWLIST, PROJECT_ORDER_BY_ALLOWLIST, VIEW_ORDER_BY_ALLOWLIST,
  NOTIFICATION_ORDER_BY_ALLOWLIST + sanitize_order_by() utility; validation added
  at the top of order_issue_queryset() — fixes all callers including the
  unauthenticated ProjectIssuesPublicEndpoint (GHSA-w45q)
- api/views/cycle.py, api/views/module.py: cycle/module issue list endpoints
- api/views/issue.py: IssueActivity list and detail endpoints
- app/views/intake/base.py: IntakeIssue list
- app/views/view/base.py: saved-view list
- app/views/notification/base.py: notification paginator
- app/views/project/base.py: project list paginator
- app/views/user/base.py, app/views/workspace/user.py: activity paginators

Closes WEB-7813

Co-authored-by: Plane AI <noreply@plane.so>

* fix: harden sanitize_order_by against multi-dash malformed inputs

lstrip("-") stripped all leading dashes, allowing "--created_at" to
pass the allowlist check unchanged and reach .order_by() as a malformed
token (causing FieldError). Now strips only one leading dash; any
remaining dash prefix is rejected to the safe default.

Co-authored-by: Plane AI <noreply@plane.so>

---------

Co-authored-by: Plane AI <noreply@plane.so>
2026-06-23 18:02:52 +05:30
sriram veeraghanta
02d0ee3e0f
chore: add copyright (#8584)
* feat: adding new copyright info on all files

* chore: adding CI
2026-01-27 13:54:22 +05:30
sriram veeraghanta
9237f568dd
[WEB-5044] fix: ruff lint and format errors (#7868)
* fix: lint errors

* fix: file formatting

* fix: code refactor
2025-09-29 19:15:32 +05:30
sriram veeraghanta
fdbe4c2ca6
chore: rename server to api (#7342) 2025-07-04 15:32:21 +05:30
Renamed from apps/server/plane/utils/order_queryset.py (Browse further)