forked from FoundKeyGang/FoundKey
security: make sure there is no SQL insertion
This commit is contained in:
parent
3ad6323c23
commit
c1ae134c0a
3 changed files with 5 additions and 11 deletions
|
@ -1,3 +0,0 @@
|
||||||
export function safeForSql(text: string): boolean {
|
|
||||||
return !/[\0\x08\x09\x1a\n\r"'\\\%]/g.test(text);
|
|
||||||
}
|
|
|
@ -3,7 +3,6 @@ import { MINUTE, HOUR } from '@/const.js';
|
||||||
import { fetchMeta } from '@/misc/fetch-meta.js';
|
import { fetchMeta } from '@/misc/fetch-meta.js';
|
||||||
import { Notes } from '@/models/index.js';
|
import { Notes } from '@/models/index.js';
|
||||||
import { Note } from '@/models/entities/note.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 { normalizeForSearch } from '@/misc/normalize-for-search.js';
|
||||||
import define from '../../define.js';
|
import define from '../../define.js';
|
||||||
|
|
||||||
|
@ -122,7 +121,7 @@ export default define(meta, paramDef, async () => {
|
||||||
for (let i = 0; i < range; i++) {
|
for (let i = 0; i < range; i++) {
|
||||||
countPromises.push(Promise.all(hots.map(tag => Notes.createQueryBuilder('note')
|
countPromises.push(Promise.all(hots.map(tag => Notes.createQueryBuilder('note')
|
||||||
.select('count(distinct note.userId)')
|
.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 < :lt', { lt: new Date(now.getTime() - (interval * i)) })
|
||||||
.andWhere('note.createdAt > :gt', { gt: new Date(now.getTime() - (interval * (i + 1))) })
|
.andWhere('note.createdAt > :gt', { gt: new Date(now.getTime() - (interval * (i + 1))) })
|
||||||
.cache(60000) // 1 min
|
.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')
|
const totalCounts = await Promise.all(hots.map(tag => Notes.createQueryBuilder('note')
|
||||||
.select('count(distinct note.userId)')
|
.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) })
|
.andWhere('note.createdAt > :gt', { gt: new Date(now.getTime() - rangeA) })
|
||||||
.cache(60000 * 60) // 60 min
|
.cache(60000 * 60) // 60 min
|
||||||
.getRawOne()
|
.getRawOne()
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { Brackets } from 'typeorm';
|
import { Brackets } from 'typeorm';
|
||||||
import { Notes } from '@/models/index.js';
|
import { Notes } from '@/models/index.js';
|
||||||
import { safeForSql } from '@/misc/safe-for-sql.js';
|
|
||||||
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
|
import { normalizeForSearch } from '@/misc/normalize-for-search.js';
|
||||||
import define from '../../define.js';
|
import define from '../../define.js';
|
||||||
import { makePaginationQuery } from '../../common/make-pagination-query.js';
|
import { makePaginationQuery } from '../../common/make-pagination-query.js';
|
||||||
|
@ -86,15 +85,14 @@ export default define(meta, paramDef, async (ps, me) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (ps.tag) {
|
if (ps.tag) {
|
||||||
if (!safeForSql(ps.tag)) throw new Error('Injection');
|
query.andWhere(':tag = ANY(note.tags)', { tag: normalizeForSearch(ps.tag) });
|
||||||
query.andWhere(`'{"${normalizeForSearch(ps.tag)}"}' <@ note.tags`);
|
|
||||||
} else {
|
} else {
|
||||||
|
let i = 0;
|
||||||
query.andWhere(new Brackets(qb => {
|
query.andWhere(new Brackets(qb => {
|
||||||
for (const tags of ps.query!) {
|
for (const tags of ps.query!) {
|
||||||
qb.orWhere(new Brackets(qb => {
|
qb.orWhere(new Brackets(qb => {
|
||||||
for (const tag of tags) {
|
for (const tag of tags) {
|
||||||
if (!safeForSql(tag)) throw new Error('Injection');
|
qb.andWhere(`:tag${++i} = ANY(note.tags)`, { ['tag' + i]: normalizeForSearch(tag) });
|
||||||
qb.andWhere(`'{"${normalizeForSearch(tag)}"}' <@ note.tags`);
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue