diff --git a/src/paginate.spec.ts b/src/paginate.spec.ts index b993cb8..e8a5095 100644 --- a/src/paginate.spec.ts +++ b/src/paginate.spec.ts @@ -415,6 +415,21 @@ describe('paginate', () => { expect(result.links.current).toBe('?page=1&limit=20&sortBy=id:ASC&search=i') }) + it('should not result in a sql syntax error when attempting a sql injection', async () => { + const config: PaginateConfig = { + sortableColumns: ['id', 'name', 'color'], + searchableColumns: ['name', 'color'], + } + const query: PaginateQuery = { + path: '', + search: "i UNION SELECT tbl_name FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'", + } + + const result = await paginate(query, catRepo, config) + + expect(result.data).toStrictEqual([]) + }) + it('should return result based on search term on many-to-one relation', async () => { const config: PaginateConfig = { relations: ['cat'], diff --git a/src/paginate.ts b/src/paginate.ts index 60fad22..4d3debf 100644 --- a/src/paginate.ts +++ b/src/paginate.ts @@ -311,10 +311,10 @@ export async function paginate( } const aliasColumn = alias + columns.substring(0, columns.length - 1) - qb.orWhere(`${aliasColumn}::text ILIKE '%${query.search}%'`) + qb.orWhere(`${aliasColumn}::text ILIKE(:search)`, { search: `%${query.search}%` }) } else { const aliasColumn = hasRelation ? `${qb.alias}_${column}` : `${qb.alias}.${column}` - qb.orWhere(`UPPER(${aliasColumn}) LIKE UPPER('%${query.search}%')`) + qb.orWhere(`UPPER(${aliasColumn}) LIKE UPPER(:search)`, { search: `%${query.search}%` }) } } })