Merge pull request 'security: escape SQL-like queries' (#10182) from naskya/calckey:security/escape-sql into develop
Reviewed-on: https://codeberg.org/calckey/calckey/pulls/10182
This commit is contained in:
commit
88b2c1d60c
8 changed files with 31 additions and 15 deletions
|
@ -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.js";
|
||||
|
||||
export const meta = {
|
||||
tags: ["admin"],
|
||||
|
@ -106,7 +107,9 @@ 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();
|
||||
|
|
|
@ -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.js";
|
||||
|
||||
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();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Users } from "@/models/index.js";
|
||||
import define from "../../define.js";
|
||||
import { sqlLikeEscape } from "@/misc/sql-like-escape.js";
|
||||
|
||||
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())}%`,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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.js";
|
||||
|
||||
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())}%`,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import define from "../../define.js";
|
||||
import { Hashtags } from "@/models/index.js";
|
||||
import { sqlLikeEscape } from "@/misc/sql-like-escape.js";
|
||||
|
||||
export const meta = {
|
||||
tags: ["hashtags"],
|
||||
|
@ -31,7 +32,9 @@ 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)
|
||||
|
|
|
@ -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.js";
|
||||
|
||||
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")
|
||||
|
|
|
@ -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.js";
|
||||
|
||||
export const meta = {
|
||||
tags: ["users"],
|
||||
|
@ -44,11 +45,13 @@ 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 +74,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 +98,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 +115,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")
|
||||
|
|
|
@ -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.js";
|
||||
|
||||
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,14 @@ 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 +116,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") {
|
||||
|
|
Loading…
Reference in a new issue