@tinacms/graphql 2.2.1 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +47 -8
- package/dist/resolver/index.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3026,7 +3026,7 @@ var validateField = async (field) => {
|
|
|
3026
3026
|
var package_default = {
|
|
3027
3027
|
name: "@tinacms/graphql",
|
|
3028
3028
|
type: "module",
|
|
3029
|
-
version: "2.2.
|
|
3029
|
+
version: "2.2.2",
|
|
3030
3030
|
main: "dist/index.js",
|
|
3031
3031
|
module: "./dist/index.js",
|
|
3032
3032
|
files: [
|
|
@@ -4917,7 +4917,7 @@ var updateObjectWithJsonPath = (obj, path9, oldValue, newValue) => {
|
|
|
4917
4917
|
}
|
|
4918
4918
|
return { object: obj, updated };
|
|
4919
4919
|
};
|
|
4920
|
-
var Resolver = class {
|
|
4920
|
+
var Resolver = class _Resolver {
|
|
4921
4921
|
constructor(init) {
|
|
4922
4922
|
this.init = init;
|
|
4923
4923
|
this.config = init.config;
|
|
@@ -5188,8 +5188,17 @@ var Resolver = class {
|
|
|
5188
5188
|
* path traversal attacks where a user might attempt to read or write files
|
|
5189
5189
|
* outside of the intended collection.
|
|
5190
5190
|
*/
|
|
5191
|
+
static sanitizePath(input) {
|
|
5192
|
+
if (input.includes("\0")) {
|
|
5193
|
+
throw new Error("Invalid path: null bytes are not allowed");
|
|
5194
|
+
}
|
|
5195
|
+
return input.replace(/\\/g, "/");
|
|
5196
|
+
}
|
|
5191
5197
|
validatePath = (fullPath, collection, relativePath) => {
|
|
5192
|
-
|
|
5198
|
+
if (fullPath.includes("\0")) {
|
|
5199
|
+
throw new Error("Invalid path: null bytes are not allowed");
|
|
5200
|
+
}
|
|
5201
|
+
const normalizedPath = path3.normalize(fullPath.replace(/\\/g, "/"));
|
|
5193
5202
|
const normalizedCollectionPath = path3.normalize(collection.path);
|
|
5194
5203
|
const relative = path3.relative(normalizedCollectionPath, normalizedPath);
|
|
5195
5204
|
if (relative.startsWith("..")) {
|
|
@@ -5220,16 +5229,17 @@ var Resolver = class {
|
|
|
5220
5229
|
*/
|
|
5221
5230
|
getValidatedPath = (collectionName, relativePath, options) => {
|
|
5222
5231
|
const collection = this.getCollectionWithName(collectionName);
|
|
5223
|
-
const
|
|
5232
|
+
const sanitizedRelativePath = _Resolver.sanitizePath(relativePath);
|
|
5233
|
+
const pathSegments = [collection.path, sanitizedRelativePath];
|
|
5224
5234
|
if (options?.extraSegments) {
|
|
5225
|
-
pathSegments.push(...options.extraSegments);
|
|
5235
|
+
pathSegments.push(...options.extraSegments.map(_Resolver.sanitizePath));
|
|
5226
5236
|
}
|
|
5227
5237
|
const realPath = path3.join(...pathSegments);
|
|
5228
5238
|
const shouldValidateExtension = options?.validateExtension !== false;
|
|
5229
5239
|
this.validatePath(
|
|
5230
5240
|
realPath,
|
|
5231
5241
|
collection,
|
|
5232
|
-
shouldValidateExtension ?
|
|
5242
|
+
shouldValidateExtension ? sanitizedRelativePath : void 0
|
|
5233
5243
|
);
|
|
5234
5244
|
return { collection, realPath };
|
|
5235
5245
|
};
|
|
@@ -8021,14 +8031,39 @@ import path7 from "path";
|
|
|
8021
8031
|
import fg from "fast-glob";
|
|
8022
8032
|
import fs2 from "fs-extra";
|
|
8023
8033
|
import normalize from "normalize-path";
|
|
8034
|
+
function resolveRealPath(candidate) {
|
|
8035
|
+
try {
|
|
8036
|
+
return fs2.realpathSync(candidate);
|
|
8037
|
+
} catch {
|
|
8038
|
+
const parent = path7.dirname(candidate);
|
|
8039
|
+
if (parent === candidate) return candidate;
|
|
8040
|
+
return path7.join(resolveRealPath(parent), path7.basename(candidate));
|
|
8041
|
+
}
|
|
8042
|
+
}
|
|
8024
8043
|
function assertWithinBase(filepath, baseDir) {
|
|
8044
|
+
if (filepath.includes("\0")) {
|
|
8045
|
+
throw new Error("Invalid path: null bytes are not allowed");
|
|
8046
|
+
}
|
|
8047
|
+
const sanitized = filepath.replace(/\\/g, "/");
|
|
8025
8048
|
const resolvedBase = path7.resolve(baseDir);
|
|
8026
|
-
const resolved = path7.resolve(path7.join(baseDir,
|
|
8049
|
+
const resolved = path7.resolve(path7.join(baseDir, sanitized));
|
|
8027
8050
|
if (resolved !== resolvedBase && !resolved.startsWith(resolvedBase + path7.sep)) {
|
|
8028
8051
|
throw new Error(
|
|
8029
8052
|
`Path traversal detected: "${filepath}" escapes the base directory`
|
|
8030
8053
|
);
|
|
8031
8054
|
}
|
|
8055
|
+
try {
|
|
8056
|
+
const realBase = fs2.realpathSync(resolvedBase);
|
|
8057
|
+
const realResolved = resolveRealPath(resolved);
|
|
8058
|
+
if (realResolved !== realBase && !realResolved.startsWith(realBase + path7.sep)) {
|
|
8059
|
+
throw new Error(
|
|
8060
|
+
`Path traversal detected: "${filepath}" escapes the base directory`
|
|
8061
|
+
);
|
|
8062
|
+
}
|
|
8063
|
+
} catch (err) {
|
|
8064
|
+
if (err instanceof Error && err.message.startsWith("Path traversal"))
|
|
8065
|
+
throw err;
|
|
8066
|
+
}
|
|
8032
8067
|
return resolved;
|
|
8033
8068
|
}
|
|
8034
8069
|
var FilesystemBridge = class {
|
|
@@ -8090,7 +8125,11 @@ import { GraphQLError as GraphQLError6 } from "graphql";
|
|
|
8090
8125
|
import git2 from "isomorphic-git";
|
|
8091
8126
|
import normalize2 from "normalize-path";
|
|
8092
8127
|
function assertWithinBase2(filepath, relativePath) {
|
|
8093
|
-
|
|
8128
|
+
if (filepath.includes("\0")) {
|
|
8129
|
+
throw new Error("Invalid path: null bytes are not allowed");
|
|
8130
|
+
}
|
|
8131
|
+
const sanitized = filepath.replace(/\\/g, "/");
|
|
8132
|
+
const qualified = relativePath ? `${relativePath}/${sanitized}` : sanitized;
|
|
8094
8133
|
const normalized = path8.normalize(qualified);
|
|
8095
8134
|
if (normalized.startsWith("..") || normalized.startsWith("/") || path8.isAbsolute(normalized) || relativePath && normalized !== relativePath && !normalized.startsWith(relativePath + "/")) {
|
|
8096
8135
|
throw new Error(
|
package/dist/resolver/index.d.ts
CHANGED
|
@@ -235,6 +235,7 @@ export declare class Resolver {
|
|
|
235
235
|
* path traversal attacks where a user might attempt to read or write files
|
|
236
236
|
* outside of the intended collection.
|
|
237
237
|
*/
|
|
238
|
+
private static sanitizePath;
|
|
238
239
|
private validatePath;
|
|
239
240
|
/**
|
|
240
241
|
* Helper method to get collection and construct validated path.
|