security: make sure there is no SQL insertion

This commit is contained in:
Johann150 2023-02-10 18:31:23 +01:00
parent 3ad6323c23
commit c1ae134c0a
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1
3 changed files with 5 additions and 11 deletions

View file

@ -1,3 +0,0 @@
export function safeForSql(text: string): boolean {
return !/[\0\x08\x09\x1a\n\r"'\\\%]/g.test(text);
}

View file

@ -3,7 +3,6 @@ import { MINUTE, HOUR } from '@/const.js';
import { fetchMeta } from '@/misc/fetch-meta.js';
import { Notes } from '@/models/index.js';
import { Note } from '@/models/entities/note.js';
import { safeForSql } from '@/misc/safe-for-sql.js';
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
import define from '../../define.js';
@ -122,7 +121,7 @@ export default define(meta, paramDef, async () => {
for (let i = 0; i < range; i++) {
countPromises.push(Promise.all(hots.map(tag => Notes.createQueryBuilder('note')
.select('count(distinct note.userId)')
.where(`'{"${safeForSql(tag) ? tag : 'aichan_kawaii'}"}' <@ note.tags`)
.where(':tag = ANY(note.tags)', { tag })
.andWhere('note.createdAt < :lt', { lt: new Date(now.getTime() - (interval * i)) })
.andWhere('note.createdAt > :gt', { gt: new Date(now.getTime() - (interval * (i + 1))) })
.cache(60000) // 1 min
@ -136,7 +135,7 @@ export default define(meta, paramDef, async () => {
const totalCounts = await Promise.all(hots.map(tag => Notes.createQueryBuilder('note')
.select('count(distinct note.userId)')
.where(`'{"${safeForSql(tag) ? tag : 'aichan_kawaii'}"}' <@ note.tags`)
.where(':tag = ANY(note.tags)', { tag })
.andWhere('note.createdAt > :gt', { gt: new Date(now.getTime() - rangeA) })
.cache(60000 * 60) // 60 min
.getRawOne()

View file

@ -1,6 +1,5 @@
import { Brackets } from 'typeorm';
import { Notes } from '@/models/index.js';
import { safeForSql } from '@/misc/safe-for-sql.js';
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
import define from '../../define.js';
import { makePaginationQuery } from '../../common/make-pagination-query.js';
@ -86,15 +85,14 @@ export default define(meta, paramDef, async (ps, me) => {
try {
if (ps.tag) {
if (!safeForSql(ps.tag)) throw new Error('Injection');
query.andWhere(`'{"${normalizeForSearch(ps.tag)}"}' <@ note.tags`);
query.andWhere(':tag = ANY(note.tags)', { tag: normalizeForSearch(ps.tag) });
} else {
let i = 0;
query.andWhere(new Brackets(qb => {
for (const tags of ps.query!) {
qb.orWhere(new Brackets(qb => {
for (const tag of tags) {
if (!safeForSql(tag)) throw new Error('Injection');
qb.andWhere(`'{"${normalizeForSearch(tag)}"}' <@ note.tags`);
qb.andWhere(`:tag${++i} = ANY(note.tags)`, { ['tag' + i]: normalizeForSearch(tag) });
}
}));
}