Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/runtime/internal/security.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ export function assertSafeQuery(sql: string, collection: string) {

// ORDER BY
const _order = (orderBy + ' ' + order).split(', ')
if (!_order.every(column => column.match(/^("[a-zA-Z_]+"|[a-zA-Z_]+) (ASC|DESC)$/))) {
if (!_order.every(column => column.match(/^("[a-zA-Z_]\w*"|[a-zA-Z_]\w*) (ASC|DESC)$/))) {
throw new Error('Invalid query: ORDER BY clause must contain valid column names followed by ASC or DESC')
}

Expand Down
7 changes: 7 additions & 0 deletions test/unit/assertSafeQuery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ describe('decompressSQLDump', () => {
'SELECT * FROM _content_test ORDER BY id ASC, stem DESC': true,
'SELECT * FROM _content_test ORDER BY id ASC, publishedAt DESC': true,
'SELECT "PublishedAt" FROM _content_test ORDER BY id ASC, PublishedAt DESC': true,
// Digits are valid in quoted column names (schema fields such as `h1` or `publishedAt2`)
'SELECT * FROM _content_test ORDER BY "field1" DESC': true,
'SELECT * FROM _content_test ORDER BY id ASC, publishedAt2 DESC': true,
'SELECT * FROM _content_test ORDER BY "a b" DESC': false,
'SELECT * FROM _content_test ORDER BY id DESC -- comment is not allowed': false,
'SELECT * FROM _content_test ORDER BY id DESC; SELECT * FROM _content_test ORDER BY id DESC': false,
'SELECT * FROM _content_test ORDER BY id DESC LIMIT 10': true,
Expand Down Expand Up @@ -162,6 +166,9 @@ describe('decompressSQLDump', () => {
await collectionQueryBuilder(mockCollection, mockFetch).order('stem', 'DESC').first()
expect(() => assertSafeQuery(mockFetch.mock.lastCall![1], mockCollection)).not.toThrow()

await collectionQueryBuilder(mockCollection, mockFetch).order('field1' as never, 'DESC').first()
expect(() => assertSafeQuery(mockFetch.mock.lastCall![1], mockCollection)).not.toThrow()

await collectionQueryBuilder(mockCollection, mockFetch).order('stem', 'DESC').order('id', 'ASC').first()
expect(() => assertSafeQuery(mockFetch.mock.lastCall![1], mockCollection)).not.toThrow()

Expand Down
Loading