Skip to content

Commit f5cbd12

Browse files
fix: improve query sanitization for enhanced stability and security
1 parent 0bbbd74 commit f5cbd12

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

src/stack.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1857,9 +1857,8 @@ export class Stack {
18571857
$or: [],
18581858
}
18591859

1860-
const sanitizedQueryBucket = this.sanitizeQueryBucket(queryBucket);
18611860
for (let i = 0, j = paths.length; i < j; i++) {
1862-
this.fetchPathDetails(entries, locale, paths[i].split('.'), sanitizedQueryBucket, shelf, true, entries, 0)
1861+
this.fetchPathDetails(entries, locale, paths[i].split('.'), queryBucket, shelf, true, entries, 0)
18631862
}
18641863

18651864
if (shelf.length === 0) {
@@ -1870,7 +1869,7 @@ export class Stack {
18701869
content_type_uid: this.types.assets,
18711870
locale,
18721871
}, this.collectionNames))
1873-
.find(sanitizedQueryBucket) // Use sanitized query here
1872+
.find(queryBucket)
18741873
.project({
18751874
_content_type_uid: 0,
18761875
_id: 0,
@@ -1934,6 +1933,7 @@ export class Stack {
19341933
private fetchPathDetails(data: any, locale: string, pathArr: string[], queryBucket: IQuery, shelf,
19351934
assetsOnly = false, parent, pos, counter = 0) {
19361935
if (counter === (pathArr.length)) {
1936+
queryBucket = this.sanitizeQueryBucket(queryBucket)
19371937
if (data && typeof data === 'object') {
19381938
if (data instanceof Array && data.length) {
19391939
data.forEach((elem, idx) => {
@@ -2000,13 +2000,13 @@ export class Stack {
20002000
// tslint:disable-next-line: prefer-for-of
20012001
for (let i = 0; i < data.length; i++) {
20022002
if (data[i][currentField]) {
2003-
this.fetchPathDetails(data[i][currentField], locale, pathArr, queryBucket, shelf, assetsOnly, data[i],
2003+
this.fetchPathDetails(data[i][currentField], locale, pathArr, this.sanitizeQueryBucket(queryBucket) , shelf, assetsOnly, data[i],
20042004
currentField, counter)
20052005
}
20062006
}
20072007
} else {
20082008
if (data[currentField]) {
2009-
this.fetchPathDetails(data[currentField], locale, pathArr, queryBucket, shelf, assetsOnly, data,
2009+
this.fetchPathDetails(data[currentField], locale, pathArr, this.sanitizeQueryBucket(queryBucket), shelf, assetsOnly, data,
20102010
currentField, counter)
20112011
}
20122012
}
@@ -2101,11 +2101,12 @@ export class Stack {
21012101
if (!this.sanityQueryAny(query)) {
21022102
throw new Error('Invalid query provided');
21032103
}
2104+
const querySanitize = this.sanitizeQueryBucket(query)
21042105
const schemas = await this.db.collection(getCollectionName({
21052106
content_type_uid: this.types.content_types,
21062107
locale,
21072108
}, this.collectionNames))
2108-
.find(query)
2109+
.find(querySanitize)
21092110
.project({
21102111
_assets: 1,
21112112
_id: 0,
@@ -2196,11 +2197,12 @@ export class Stack {
21962197
if (!this.sanitizeIQuery(query)) {
21972198
throw new Error('Invalid queries provided');
21982199
}
2200+
const sanitizeQuery = this.sanitizeQueryBucket(query)
21992201
const result = await this.db.collection(getCollectionName({
22002202
content_type_uid: 'entries',
22012203
locale,
22022204
}, this.collectionNames))
2203-
.find(query)
2205+
.find(sanitizeQuery)
22042206
.project({
22052207
_content_type_uid: 0,
22062208
_id: 0,
@@ -2261,7 +2263,7 @@ export class Stack {
22612263
// iterate over each path in the entries and fetch the references
22622264
// while fetching, keep track of their location
22632265
for (let i = 0, j = paths.length; i < j; i++) {
2264-
this.fetchPathDetails(entries, locale, paths[i].split('.'), queries, objectPointerList, true, entries, 0)
2266+
this.fetchPathDetails(entries, locale, paths[i].split('.'), this.sanitizeQueryBucket(queries), objectPointerList, true, entries, 0)
22652267
}
22662268

22672269
// even after traversing, if no references were found, simply return the entries found thusfar
@@ -2437,15 +2439,15 @@ export class Stack {
24372439
private sanitizeQueryBucket(queryBucket: any): any {
24382440
// Validate basic structure
24392441
if (!queryBucket || typeof queryBucket !== 'object') {
2440-
return { $or: [] };
2442+
return { $or: [{ _id: { $exists: true } }] }; // Default query that matches all documents
24412443
}
24422444

24432445
// Create a new sanitized query object
24442446
const sanitized = { $or: [] };
24452447

24462448
// Ensure $or is an array
24472449
if (!Array.isArray(queryBucket.$or)) {
2448-
return sanitized;
2450+
return { $or: [{ _id: { $exists: true } }] }; // Default query that matches all documents
24492451
}
24502452

24512453
// Process each item in the $or array
@@ -2479,6 +2481,12 @@ export class Stack {
24792481
sanitized.$or.push(safeItem);
24802482
}
24812483
}
2484+
2485+
// If sanitized.$or is empty, use a default query that matches all documents
2486+
if (sanitized.$or.length === 0) {
2487+
return { $or: [{ _id: { $exists: true } }] };
2488+
}
2489+
24822490
return sanitized;
24832491
}
24842492
}

typings/stack.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,4 +1094,5 @@ export declare class Stack {
10941094
private getAllReferencePaths;
10951095
private sanitizeIQuery;
10961096
private sanityQueryAny;
1097+
private sanitizeQueryBucket;
10971098
}

0 commit comments

Comments
 (0)