Skip to content

Validate the sort key before building the ORDER BY clause - #2421

Open
kah-ja wants to merge 1 commit into
dataelement:mainfrom
kah-ja:fix/validate-order-by-fields
Open

kah-ja wants to merge 1 commit into
dataelement:mainfrom
kah-ja:fix/validate-order-by-fields

Conversation

@kah-ja

@kah-ja kah-ja commented Sep 17, 2026

Copy link
Copy Markdown

What

SpaceFileDao.order_field_text builds the ORDER BY fragment by interpolating its
two arguments into a string (knowledge_space_file.py:283), and the result is
handed to text() at knowledge_space_file.py:234 and :239 and at
knowledge_file.py:557. Both arguments arrive from the query string of
GET /api/v1/knowledge/space/{space_id}/children and
GET /api/v1/knowledge/space/{space_id}/search (knowledge_space.py:345 and
:382), where they are typed as a plain str with no further checking.

Why

text() takes the fragment verbatim, so whatever the caller sends becomes part
of the statement. There is no allow list and no escaping anywhere on the path.
The neighbouring branches in the same function already show the intended
shape: knowledge_file.py:559 and :561 order by a fixed column reference
picked by an elif over known values, which cannot carry caller input.

How

order_field_text now rejects anything outside the four sort keys the API
contract exposes, and rejects a direction other than asc or desc. The values
are the ones the web client sends (SortType in api/knowledge.ts:69), so no
existing caller changes behaviour. The two endpoints also declare the
parameters as Literal, which turns a bad value into a 422 instead of a 500.

The file_type branch keeps its CASE expression, which is built from a
constant table. It interpolates order_sort twice
(knowledge_space_file.py:276 and :280), so the direction check applies
there as well.

Test

  • Local tests pass
  • Verified on the 114 test server: no access to that environment.

pytest test/knowledge/test_order_field_allow_list.py covers each supported
sort key and rejects six malformed field values and five malformed directions.
Against the unpatched function those eleven cases fail and the eight
legitimate ones pass. The wider backend suite was not run here, it needs a
configured Milvus, Elasticsearch and MinIO.

Related

  • Issue/ticket: n/a

References

GHSA-hhmh-3fj8-f53v (reported privately, unpublished at time of writing)

Found during a penetration test by turingpoint.

order_field_text interpolated order_field and order_sort straight into a
raw ORDER BY fragment, so any caller of the space file listing endpoints
could inject SQL through them. Accept only the four sort keys the API
contract exposes and reject anything else, and constrain both query
parameters to those values.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant