fix: Escape SQL LIKE

* SQL LIKE escape
This commit is contained in:
MeiMei 2023-01-08 20:32:17 +09:00 committed by naskya
parent d8aaa8f199
commit 910b06c35a
No known key found for this signature in database
GPG Key ID: 164DFF24E2D40139
8 changed files with 23 additions and 15 deletions

View File

@ -2,6 +2,7 @@ import define from "../../../define.js";
import { Emojis } from "@/models/index.js";
import { toPuny } from "@/misc/convert-host.js";
import { makePaginationQuery } from "../../../common/make-pagination-query.js";
import { sqlLikeEscape } from "@/misc/sql-like-escape";
export const meta = {
tags: ["admin"],
@ -106,7 +107,7 @@ export default define(meta, paramDef, async (ps) => {
}
if (ps.query) {
q.andWhere("emoji.name like :query", { query: `%${ps.query}%` });
q.andWhere('emoji.name like :query', { query: `%${sqlLikeEscape(ps.query)}%` });
}
const emojis = await q.orderBy("emoji.id", "DESC").take(ps.limit).getMany();

View File

@ -2,6 +2,7 @@ import define from "../../../define.js";
import { Emojis } from "@/models/index.js";
import { makePaginationQuery } from "../../../common/make-pagination-query.js";
import type { Emoji } from "@/models/entities/emoji.js";
//import { sqlLikeEscape } from "@/misc/sql-like-escape";
export const meta = {
tags: ["admin"],
@ -96,7 +97,7 @@ export default define(meta, paramDef, async (ps) => {
let emojis: Emoji[];
if (ps.query) {
//q.andWhere('emoji.name ILIKE :q', { q: `%${ps.query}%` });
//q.andWhere('emoji.name ILIKE :q', { q: `%${sqlLikeEscape(ps.query)}%` });
//const emojis = await q.take(ps.limit).getMany();
emojis = await q.getMany();

View File

@ -1,5 +1,6 @@
import { Users } from "@/models/index.js";
import define from "../../define.js";
import { sqlLikeEscape } from "@/misc/sql-like-escape";
export const meta = {
tags: ["admin"],
@ -106,7 +107,7 @@ export default define(meta, paramDef, async (ps, me) => {
if (ps.username) {
query.andWhere("user.usernameLower like :username", {
username: `${ps.username.toLowerCase()}%`,
username: `${sqlLikeEscape(ps.username.toLowerCase())}%`,
});
}

View File

@ -2,6 +2,7 @@ import config from "@/config/index.js";
import define from "../../define.js";
import { Instances } from "@/models/index.js";
import { fetchMeta } from "@/misc/fetch-meta.js";
import { sqlLikeEscape } from "@/misc/sql-like-escape";
export const meta = {
tags: ["federation"],
@ -178,7 +179,7 @@ export default define(meta, paramDef, async (ps, me) => {
if (ps.host) {
query.andWhere("instance.host like :host", {
host: `%${ps.host.toLowerCase()}%`,
host: `%${sqlLikeEscape(ps.host.toLowerCase())}%`,
});
}

View File

@ -1,5 +1,6 @@
import define from "../../define.js";
import { Hashtags } from "@/models/index.js";
import { sqlLikeEscape } from "@/misc/sql-like-escape";
export const meta = {
tags: ["hashtags"],
@ -31,7 +32,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps) => {
const hashtags = await Hashtags.createQueryBuilder("tag")
.where("tag.name like :q", { q: `${ps.query.toLowerCase()}%` })
.where("tag.name like :q", { q: `${sqlLikeEscape(ps.query.toLowerCase())}%` })
.orderBy("tag.count", "DESC")
.groupBy("tag.id")
.take(ps.limit)

View File

@ -9,6 +9,7 @@ import { makePaginationQuery } from "../../common/make-pagination-query.js";
import { generateVisibilityQuery } from "../../common/generate-visibility-query.js";
import { generateMutedUserQuery } from "../../common/generate-muted-user-query.js";
import { generateBlockedUserQuery } from "../../common/generate-block-query.js";
import { sqlLikeEscape } from "@/misc/sql-like-escape";
export const meta = {
tags: ["notes"],
@ -77,7 +78,7 @@ export default define(meta, paramDef, async (ps, me) => {
}
query
.andWhere("note.text ILIKE :q", { q: `%${ps.query}%` })
.andWhere("note.text ILIKE :q", { q: `%${sqlLikeEscape(ps.query)}%` })
.innerJoinAndSelect("note.user", "user")
.leftJoinAndSelect("user.avatar", "avatar")
.leftJoinAndSelect("user.banner", "banner")

View File

@ -3,6 +3,7 @@ import { Followings, Users } from "@/models/index.js";
import { USER_ACTIVE_THRESHOLD } from "@/const.js";
import type { User } from "@/models/entities/user.js";
import define from "../../define.js";
import { sqlLikeEscape } from "@/misc/sql-like-escape";
export const meta = {
tags: ["users"],
@ -44,11 +45,11 @@ export default define(meta, paramDef, async (ps, me) => {
if (ps.host) {
const q = Users.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()}%`,
username: `${sqlLikeEscape(ps.username.toLowerCase())}%`,
});
}
@ -71,7 +72,7 @@ export default define(meta, paramDef, async (ps, me) => {
.andWhere("user.id != :meId", { meId: me.id })
.andWhere("user.isSuspended = FALSE")
.andWhere("user.usernameLower LIKE :username", {
username: `${ps.username.toLowerCase()}%`,
username: `${sqlLikeEscape(ps.username.toLowerCase())}%`,
})
.andWhere(
new Brackets((qb) => {
@ -95,7 +96,7 @@ export default define(meta, paramDef, async (ps, me) => {
.andWhere("user.id != :meId", { meId: me.id })
.andWhere("user.isSuspended = FALSE")
.andWhere("user.usernameLower LIKE :username", {
username: `${ps.username.toLowerCase()}%`,
username: `${sqlLikeEscape(ps.username.toLowerCase())}%`,
})
.andWhere("user.updatedAt IS NOT NULL");
@ -112,7 +113,7 @@ export default define(meta, paramDef, async (ps, me) => {
users = await Users.createQueryBuilder("user")
.where("user.isSuspended = FALSE")
.andWhere("user.usernameLower LIKE :username", {
username: `${ps.username.toLowerCase()}%`,
username: `${sqlLikeEscape(ps.username.toLowerCase())}%`,
})
.andWhere("user.updatedAt IS NOT NULL")
.orderBy("user.updatedAt", "DESC")

View File

@ -2,6 +2,7 @@ import { Brackets } from "typeorm";
import { UserProfiles, Users } from "@/models/index.js";
import type { User } from "@/models/entities/user.js";
import define from "../../define.js";
import { sqlLikeEscape } from "@/misc/sql-like-escape";
export const meta = {
tags: ["users"],
@ -50,7 +51,7 @@ export default define(meta, paramDef, async (ps, me) => {
if (isUsername) {
const usernameQuery = Users.createQueryBuilder("user")
.where("user.usernameLower LIKE :username", {
username: `${ps.query.replace("@", "").toLowerCase()}%`,
username: `${sqlLikeEscape(ps.query.replace("@", "").toLowerCase())}%`,
})
.andWhere(
new Brackets((qb) => {
@ -77,12 +78,12 @@ export default define(meta, paramDef, async (ps, me) => {
const nameQuery = Users.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 (Users.validateLocalUsername(ps.query)) {
qb.orWhere("user.usernameLower LIKE :username", {
username: `%${ps.query.toLowerCase()}%`,
username: `%${sqlLikeEscape(ps.query.toLowerCase())}%`,
});
}
}),
@ -113,7 +114,7 @@ export default define(meta, paramDef, async (ps, me) => {
const profQuery = UserProfiles.createQueryBuilder("prof")
.select("prof.userId")
.where("prof.description ILIKE :query", {
query: `%${ps.query}%`,
query: `%${sqlLikeEscape(ps.query)}%`,
});
if (ps.origin === "local") {