summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/api/endpoints/users
diff options
context:
space:
mode:
authorMeiMei <30769358+mei23@users.noreply.github.com>2023-01-08 20:32:17 +0900
committerGitHub <noreply@github.com>2023-01-08 20:32:17 +0900
commit10e526ba5682fef9488d1d38ba5dfcda38619673 (patch)
tree1677ade360e317be70200050cb67b0957f35ebca /packages/backend/src/server/api/endpoints/users
parentfix following chart (diff)
downloadsharkey-10e526ba5682fef9488d1d38ba5dfcda38619673.tar.gz
sharkey-10e526ba5682fef9488d1d38ba5dfcda38619673.tar.bz2
sharkey-10e526ba5682fef9488d1d38ba5dfcda38619673.zip
fix: Escape SQL LIKE (#9493)
* SQL LIKE escape * CHANGELOG
Diffstat (limited to 'packages/backend/src/server/api/endpoints/users')
-rw-r--r--packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts11
-rw-r--r--packages/backend/src/server/api/endpoints/users/search.ts9
2 files changed, 11 insertions, 9 deletions
diff --git a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts
index f13df3ee9d..029b1e91c3 100644
--- a/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts
+++ b/packages/backend/src/server/api/endpoints/users/search-by-username-and-host.ts
@@ -6,6 +6,7 @@ import type { User } from '@/models/entities/User.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { DI } from '@/di-symbols.js';
+import { sqlLikeEscape } from '@/misc/sql-like-escape';
export const meta = {
tags: ['users'],
@@ -59,10 +60,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
if (ps.host) {
const q = this.usersRepository.createQueryBuilder('user')
.where('user.isSuspended = FALSE')
- .andWhere('user.host LIKE :host', { host: ps.host.toLowerCase() + '%' });
+ .andWhere('user.host LIKE :host', { host: sqlLikeEscape(ps.host.toLowerCase()) + '%' });
if (ps.username) {
- q.andWhere('user.usernameLower LIKE :username', { username: ps.username.toLowerCase() + '%' });
+ q.andWhere('user.usernameLower LIKE :username', { username: sqlLikeEscape(ps.username.toLowerCase()) + '%' });
}
q.andWhere('user.updatedAt IS NOT NULL');
@@ -83,7 +84,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
.where(`user.id IN (${ followingQuery.getQuery() })`)
.andWhere('user.id != :meId', { meId: me.id })
.andWhere('user.isSuspended = FALSE')
- .andWhere('user.usernameLower LIKE :username', { username: ps.username.toLowerCase() + '%' })
+ .andWhere('user.usernameLower LIKE :username', { username: sqlLikeEscape(ps.username.toLowerCase()) + '%' })
.andWhere(new Brackets(qb => { qb
.where('user.updatedAt IS NULL')
.orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold });
@@ -101,7 +102,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
.where(`user.id NOT IN (${ followingQuery.getQuery() })`)
.andWhere('user.id != :meId', { meId: me.id })
.andWhere('user.isSuspended = FALSE')
- .andWhere('user.usernameLower LIKE :username', { username: ps.username.toLowerCase() + '%' })
+ .andWhere('user.usernameLower LIKE :username', { username: sqlLikeEscape(ps.username.toLowerCase()) + '%' })
.andWhere('user.updatedAt IS NOT NULL');
otherQuery.setParameters(followingQuery.getParameters());
@@ -116,7 +117,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
} else {
users = await this.usersRepository.createQueryBuilder('user')
.where('user.isSuspended = FALSE')
- .andWhere('user.usernameLower LIKE :username', { username: ps.username.toLowerCase() + '%' })
+ .andWhere('user.usernameLower LIKE :username', { username: sqlLikeEscape(ps.username.toLowerCase()) + '%' })
.andWhere('user.updatedAt IS NOT NULL')
.orderBy('user.updatedAt', 'DESC')
.take(ps.limit - users.length)
diff --git a/packages/backend/src/server/api/endpoints/users/search.ts b/packages/backend/src/server/api/endpoints/users/search.ts
index ba07714972..25bd621269 100644
--- a/packages/backend/src/server/api/endpoints/users/search.ts
+++ b/packages/backend/src/server/api/endpoints/users/search.ts
@@ -5,6 +5,7 @@ import type { User } from '@/models/entities/User.js';
import { Endpoint } from '@/server/api/endpoint-base.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { DI } from '@/di-symbols.js';
+import { sqlLikeEscape } from '@/misc/sql-like-escape';
export const meta = {
tags: ['users'],
@@ -57,7 +58,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
if (isUsername) {
const usernameQuery = this.usersRepository.createQueryBuilder('user')
- .where('user.usernameLower LIKE :username', { username: ps.query.replace('@', '').toLowerCase() + '%' })
+ .where('user.usernameLower LIKE :username', { username: sqlLikeEscape(ps.query.replace('@', '').toLowerCase()) + '%' })
.andWhere(new Brackets(qb => { qb
.where('user.updatedAt IS NULL')
.orWhere('user.updatedAt > :activeThreshold', { activeThreshold: activeThreshold });
@@ -78,11 +79,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
} else {
const nameQuery = this.usersRepository.createQueryBuilder('user')
.where(new Brackets(qb => {
- qb.where('user.name ILIKE :query', { query: '%' + ps.query + '%' });
+ qb.where('user.name ILIKE :query', { query: '%' + sqlLikeEscape(ps.query) + '%' });
// Also search username if it qualifies as username
if (this.userEntityService.validateLocalUsername(ps.query)) {
- qb.orWhere('user.usernameLower LIKE :username', { username: '%' + ps.query.toLowerCase() + '%' });
+ qb.orWhere('user.usernameLower LIKE :username', { username: '%' + sqlLikeEscape(ps.query.toLowerCase()) + '%' });
}
}))
.andWhere(new Brackets(qb => { qb
@@ -106,7 +107,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
if (users.length < ps.limit) {
const profQuery = this.userProfilesRepository.createQueryBuilder('prof')
.select('prof.userId')
- .where('prof.description ILIKE :query', { query: '%' + ps.query + '%' });
+ .where('prof.description ILIKE :query', { query: '%' + sqlLikeEscape(ps.query) + '%' });
if (ps.origin === 'local') {
profQuery.andWhere('prof.userHost IS NULL');