@commercetools-frontend/application-config 27.5.0 → 27.5.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.
|
@@ -267,41 +267,59 @@ const substituteFilePathVariablePlaceholder = (valueOfPlaceholder, matchedString
|
|
|
267
267
|
const _valueOfPlaceholder$s5 = valueOfPlaceholder.split(':'),
|
|
268
268
|
_valueOfPlaceholder$s6 = _slicedToArray(_valueOfPlaceholder$s5, 2),
|
|
269
269
|
filePathOrModule = _valueOfPlaceholder$s6[1];
|
|
270
|
+
|
|
271
|
+
// Security check: Prevent path traversal attacks.
|
|
272
|
+
// Two strategies depending on whether the specifier is a bare module name
|
|
273
|
+
// (e.g. "@scope/pkg/file.svg") or a relative/absolute path (e.g. "./app.svg").
|
|
274
|
+
const isModuleName = !_startsWithInstanceProperty__default["default"](filePathOrModule).call(filePathOrModule, '.') && !_startsWithInstanceProperty__default["default"](filePathOrModule).call(filePathOrModule, '/');
|
|
275
|
+
if (isModuleName) {
|
|
276
|
+
// Bare module specifiers are resolved by require.resolve through
|
|
277
|
+
// node_modules, linked packages, or Yarn PnP — all legitimate locations
|
|
278
|
+
// that may be outside the workspace root (e.g. hoisted deps in CI).
|
|
279
|
+
// We skip the workspace root check for these, but we must block ".."
|
|
280
|
+
// segments in the specifier itself — those are the only way to make
|
|
281
|
+
// require.resolve escape module directories and reach arbitrary files
|
|
282
|
+
// (e.g. "some-pkg/../../../../etc/passwd" resolves through node_modules
|
|
283
|
+
// to /etc/passwd).
|
|
284
|
+
const normalizedSpecifier = path__default$1["default"].posix.normalize(filePathOrModule);
|
|
285
|
+
if (_startsWithInstanceProperty__default["default"](normalizedSpecifier).call(normalizedSpecifier, '..')) {
|
|
286
|
+
throw new Error(`Path traversal in module specifiers is not allowed: ${filePathOrModule}`);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
270
289
|
const resolvedPath = require.resolve(filePathOrModule, {
|
|
271
290
|
paths: [loadingOptions.applicationPath]
|
|
272
291
|
});
|
|
273
|
-
|
|
274
|
-
// Security check: Prevent path traversal attacks.
|
|
275
|
-
// require.resolve() already provides protection by only resolving modules
|
|
276
|
-
// accessible from the applicationPath. However, we add an extra layer to
|
|
277
|
-
// prevent access to sensitive system files outside the workspace.
|
|
278
292
|
const normalizedPath = path__default$1["default"].normalize(resolvedPath);
|
|
279
|
-
|
|
293
|
+
if (!isModuleName) {
|
|
294
|
+
// For relative/absolute paths, verify the resolved path is within the
|
|
295
|
+
// workspace root. require.resolve() already provides some protection by
|
|
296
|
+
// only resolving from applicationPath, but we add an extra layer to
|
|
297
|
+
// prevent access to sensitive system files outside the workspace.
|
|
298
|
+
const applicationPath = path__default$1["default"].normalize(loadingOptions.applicationPath);
|
|
280
299
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
300
|
+
// Find workspace root by traversing up from applicationPath until we find
|
|
301
|
+
// package.json, pnpm-workspace.yaml, or reach root
|
|
302
|
+
let workspaceRoot = applicationPath;
|
|
303
|
+
let currentPath = applicationPath;
|
|
304
|
+
const rootPath = path__default$1["default"].parse(currentPath).root;
|
|
305
|
+
while (currentPath !== rootPath) {
|
|
306
|
+
const hasPackageJson = fs__default$1["default"].existsSync(path__default$1["default"].join(currentPath, 'package.json'));
|
|
307
|
+
const hasWorkspaceConfig = fs__default$1["default"].existsSync(path__default$1["default"].join(currentPath, 'pnpm-workspace.yaml')) || fs__default$1["default"].existsSync(path__default$1["default"].join(currentPath, 'lerna.json'));
|
|
308
|
+
if (hasPackageJson) {
|
|
309
|
+
workspaceRoot = currentPath;
|
|
310
|
+
if (hasWorkspaceConfig) {
|
|
311
|
+
// Found workspace root
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
294
314
|
}
|
|
315
|
+
currentPath = path__default$1["default"].dirname(currentPath);
|
|
316
|
+
}
|
|
317
|
+
const relativePath = path__default$1["default"].relative(workspaceRoot, normalizedPath);
|
|
318
|
+
// Use path.relative() to avoid string prefix vulnerabilities (e.g., "/app" vs "/app-evil")
|
|
319
|
+
const isSafePath = !_startsWithInstanceProperty__default["default"](relativePath).call(relativePath, '..') && !path__default$1["default"].isAbsolute(relativePath);
|
|
320
|
+
if (!isSafePath) {
|
|
321
|
+
throw new Error(`Access to files outside workspace directory is not allowed: ${filePathOrModule}`);
|
|
295
322
|
}
|
|
296
|
-
currentPath = path__default$1["default"].dirname(currentPath);
|
|
297
|
-
}
|
|
298
|
-
const relativePath = path__default$1["default"].relative(workspaceRoot, normalizedPath);
|
|
299
|
-
|
|
300
|
-
// Path is safe if it's within the workspace root.
|
|
301
|
-
// Use path.relative() to avoid string prefix vulnerabilities (e.g., "/app" vs "/app-evil")
|
|
302
|
-
const isSafePath = !_startsWithInstanceProperty__default["default"](relativePath).call(relativePath, '..') && !path__default$1["default"].isAbsolute(relativePath);
|
|
303
|
-
if (!isSafePath) {
|
|
304
|
-
throw new Error(`Access to files outside workspace directory is not allowed: ${filePathOrModule}`);
|
|
305
323
|
}
|
|
306
324
|
const content = fs__default$1["default"].readFileSync(normalizedPath, {
|
|
307
325
|
encoding: 'utf-8'
|
|
@@ -267,41 +267,59 @@ const substituteFilePathVariablePlaceholder = (valueOfPlaceholder, matchedString
|
|
|
267
267
|
const _valueOfPlaceholder$s5 = valueOfPlaceholder.split(':'),
|
|
268
268
|
_valueOfPlaceholder$s6 = _slicedToArray(_valueOfPlaceholder$s5, 2),
|
|
269
269
|
filePathOrModule = _valueOfPlaceholder$s6[1];
|
|
270
|
+
|
|
271
|
+
// Security check: Prevent path traversal attacks.
|
|
272
|
+
// Two strategies depending on whether the specifier is a bare module name
|
|
273
|
+
// (e.g. "@scope/pkg/file.svg") or a relative/absolute path (e.g. "./app.svg").
|
|
274
|
+
const isModuleName = !_startsWithInstanceProperty__default["default"](filePathOrModule).call(filePathOrModule, '.') && !_startsWithInstanceProperty__default["default"](filePathOrModule).call(filePathOrModule, '/');
|
|
275
|
+
if (isModuleName) {
|
|
276
|
+
// Bare module specifiers are resolved by require.resolve through
|
|
277
|
+
// node_modules, linked packages, or Yarn PnP — all legitimate locations
|
|
278
|
+
// that may be outside the workspace root (e.g. hoisted deps in CI).
|
|
279
|
+
// We skip the workspace root check for these, but we must block ".."
|
|
280
|
+
// segments in the specifier itself — those are the only way to make
|
|
281
|
+
// require.resolve escape module directories and reach arbitrary files
|
|
282
|
+
// (e.g. "some-pkg/../../../../etc/passwd" resolves through node_modules
|
|
283
|
+
// to /etc/passwd).
|
|
284
|
+
const normalizedSpecifier = path__default$1["default"].posix.normalize(filePathOrModule);
|
|
285
|
+
if (_startsWithInstanceProperty__default["default"](normalizedSpecifier).call(normalizedSpecifier, '..')) {
|
|
286
|
+
throw new Error(`Path traversal in module specifiers is not allowed: ${filePathOrModule}`);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
270
289
|
const resolvedPath = require.resolve(filePathOrModule, {
|
|
271
290
|
paths: [loadingOptions.applicationPath]
|
|
272
291
|
});
|
|
273
|
-
|
|
274
|
-
// Security check: Prevent path traversal attacks.
|
|
275
|
-
// require.resolve() already provides protection by only resolving modules
|
|
276
|
-
// accessible from the applicationPath. However, we add an extra layer to
|
|
277
|
-
// prevent access to sensitive system files outside the workspace.
|
|
278
292
|
const normalizedPath = path__default$1["default"].normalize(resolvedPath);
|
|
279
|
-
|
|
293
|
+
if (!isModuleName) {
|
|
294
|
+
// For relative/absolute paths, verify the resolved path is within the
|
|
295
|
+
// workspace root. require.resolve() already provides some protection by
|
|
296
|
+
// only resolving from applicationPath, but we add an extra layer to
|
|
297
|
+
// prevent access to sensitive system files outside the workspace.
|
|
298
|
+
const applicationPath = path__default$1["default"].normalize(loadingOptions.applicationPath);
|
|
280
299
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
300
|
+
// Find workspace root by traversing up from applicationPath until we find
|
|
301
|
+
// package.json, pnpm-workspace.yaml, or reach root
|
|
302
|
+
let workspaceRoot = applicationPath;
|
|
303
|
+
let currentPath = applicationPath;
|
|
304
|
+
const rootPath = path__default$1["default"].parse(currentPath).root;
|
|
305
|
+
while (currentPath !== rootPath) {
|
|
306
|
+
const hasPackageJson = fs__default$1["default"].existsSync(path__default$1["default"].join(currentPath, 'package.json'));
|
|
307
|
+
const hasWorkspaceConfig = fs__default$1["default"].existsSync(path__default$1["default"].join(currentPath, 'pnpm-workspace.yaml')) || fs__default$1["default"].existsSync(path__default$1["default"].join(currentPath, 'lerna.json'));
|
|
308
|
+
if (hasPackageJson) {
|
|
309
|
+
workspaceRoot = currentPath;
|
|
310
|
+
if (hasWorkspaceConfig) {
|
|
311
|
+
// Found workspace root
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
294
314
|
}
|
|
315
|
+
currentPath = path__default$1["default"].dirname(currentPath);
|
|
316
|
+
}
|
|
317
|
+
const relativePath = path__default$1["default"].relative(workspaceRoot, normalizedPath);
|
|
318
|
+
// Use path.relative() to avoid string prefix vulnerabilities (e.g., "/app" vs "/app-evil")
|
|
319
|
+
const isSafePath = !_startsWithInstanceProperty__default["default"](relativePath).call(relativePath, '..') && !path__default$1["default"].isAbsolute(relativePath);
|
|
320
|
+
if (!isSafePath) {
|
|
321
|
+
throw new Error(`Access to files outside workspace directory is not allowed: ${filePathOrModule}`);
|
|
295
322
|
}
|
|
296
|
-
currentPath = path__default$1["default"].dirname(currentPath);
|
|
297
|
-
}
|
|
298
|
-
const relativePath = path__default$1["default"].relative(workspaceRoot, normalizedPath);
|
|
299
|
-
|
|
300
|
-
// Path is safe if it's within the workspace root.
|
|
301
|
-
// Use path.relative() to avoid string prefix vulnerabilities (e.g., "/app" vs "/app-evil")
|
|
302
|
-
const isSafePath = !_startsWithInstanceProperty__default["default"](relativePath).call(relativePath, '..') && !path__default$1["default"].isAbsolute(relativePath);
|
|
303
|
-
if (!isSafePath) {
|
|
304
|
-
throw new Error(`Access to files outside workspace directory is not allowed: ${filePathOrModule}`);
|
|
305
323
|
}
|
|
306
324
|
const content = fs__default$1["default"].readFileSync(normalizedPath, {
|
|
307
325
|
encoding: 'utf-8'
|
|
@@ -231,41 +231,59 @@ const substituteFilePathVariablePlaceholder = (valueOfPlaceholder, matchedString
|
|
|
231
231
|
const _valueOfPlaceholder$s5 = valueOfPlaceholder.split(':'),
|
|
232
232
|
_valueOfPlaceholder$s6 = _slicedToArray(_valueOfPlaceholder$s5, 2),
|
|
233
233
|
filePathOrModule = _valueOfPlaceholder$s6[1];
|
|
234
|
+
|
|
235
|
+
// Security check: Prevent path traversal attacks.
|
|
236
|
+
// Two strategies depending on whether the specifier is a bare module name
|
|
237
|
+
// (e.g. "@scope/pkg/file.svg") or a relative/absolute path (e.g. "./app.svg").
|
|
238
|
+
const isModuleName = !_startsWithInstanceProperty(filePathOrModule).call(filePathOrModule, '.') && !_startsWithInstanceProperty(filePathOrModule).call(filePathOrModule, '/');
|
|
239
|
+
if (isModuleName) {
|
|
240
|
+
// Bare module specifiers are resolved by require.resolve through
|
|
241
|
+
// node_modules, linked packages, or Yarn PnP — all legitimate locations
|
|
242
|
+
// that may be outside the workspace root (e.g. hoisted deps in CI).
|
|
243
|
+
// We skip the workspace root check for these, but we must block ".."
|
|
244
|
+
// segments in the specifier itself — those are the only way to make
|
|
245
|
+
// require.resolve escape module directories and reach arbitrary files
|
|
246
|
+
// (e.g. "some-pkg/../../../../etc/passwd" resolves through node_modules
|
|
247
|
+
// to /etc/passwd).
|
|
248
|
+
const normalizedSpecifier = path$1.posix.normalize(filePathOrModule);
|
|
249
|
+
if (_startsWithInstanceProperty(normalizedSpecifier).call(normalizedSpecifier, '..')) {
|
|
250
|
+
throw new Error(`Path traversal in module specifiers is not allowed: ${filePathOrModule}`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
234
253
|
const resolvedPath = require.resolve(filePathOrModule, {
|
|
235
254
|
paths: [loadingOptions.applicationPath]
|
|
236
255
|
});
|
|
237
|
-
|
|
238
|
-
// Security check: Prevent path traversal attacks.
|
|
239
|
-
// require.resolve() already provides protection by only resolving modules
|
|
240
|
-
// accessible from the applicationPath. However, we add an extra layer to
|
|
241
|
-
// prevent access to sensitive system files outside the workspace.
|
|
242
256
|
const normalizedPath = path$1.normalize(resolvedPath);
|
|
243
|
-
|
|
257
|
+
if (!isModuleName) {
|
|
258
|
+
// For relative/absolute paths, verify the resolved path is within the
|
|
259
|
+
// workspace root. require.resolve() already provides some protection by
|
|
260
|
+
// only resolving from applicationPath, but we add an extra layer to
|
|
261
|
+
// prevent access to sensitive system files outside the workspace.
|
|
262
|
+
const applicationPath = path$1.normalize(loadingOptions.applicationPath);
|
|
244
263
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
264
|
+
// Find workspace root by traversing up from applicationPath until we find
|
|
265
|
+
// package.json, pnpm-workspace.yaml, or reach root
|
|
266
|
+
let workspaceRoot = applicationPath;
|
|
267
|
+
let currentPath = applicationPath;
|
|
268
|
+
const rootPath = path$1.parse(currentPath).root;
|
|
269
|
+
while (currentPath !== rootPath) {
|
|
270
|
+
const hasPackageJson = fs$1.existsSync(path$1.join(currentPath, 'package.json'));
|
|
271
|
+
const hasWorkspaceConfig = fs$1.existsSync(path$1.join(currentPath, 'pnpm-workspace.yaml')) || fs$1.existsSync(path$1.join(currentPath, 'lerna.json'));
|
|
272
|
+
if (hasPackageJson) {
|
|
273
|
+
workspaceRoot = currentPath;
|
|
274
|
+
if (hasWorkspaceConfig) {
|
|
275
|
+
// Found workspace root
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
258
278
|
}
|
|
279
|
+
currentPath = path$1.dirname(currentPath);
|
|
280
|
+
}
|
|
281
|
+
const relativePath = path$1.relative(workspaceRoot, normalizedPath);
|
|
282
|
+
// Use path.relative() to avoid string prefix vulnerabilities (e.g., "/app" vs "/app-evil")
|
|
283
|
+
const isSafePath = !_startsWithInstanceProperty(relativePath).call(relativePath, '..') && !path$1.isAbsolute(relativePath);
|
|
284
|
+
if (!isSafePath) {
|
|
285
|
+
throw new Error(`Access to files outside workspace directory is not allowed: ${filePathOrModule}`);
|
|
259
286
|
}
|
|
260
|
-
currentPath = path$1.dirname(currentPath);
|
|
261
|
-
}
|
|
262
|
-
const relativePath = path$1.relative(workspaceRoot, normalizedPath);
|
|
263
|
-
|
|
264
|
-
// Path is safe if it's within the workspace root.
|
|
265
|
-
// Use path.relative() to avoid string prefix vulnerabilities (e.g., "/app" vs "/app-evil")
|
|
266
|
-
const isSafePath = !_startsWithInstanceProperty(relativePath).call(relativePath, '..') && !path$1.isAbsolute(relativePath);
|
|
267
|
-
if (!isSafePath) {
|
|
268
|
-
throw new Error(`Access to files outside workspace directory is not allowed: ${filePathOrModule}`);
|
|
269
287
|
}
|
|
270
288
|
const content = fs$1.readFileSync(normalizedPath, {
|
|
271
289
|
encoding: 'utf-8'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commercetools-frontend/application-config",
|
|
3
|
-
"version": "27.5.
|
|
3
|
+
"version": "27.5.2",
|
|
4
4
|
"description": "Configuration utilities for building Custom Applications",
|
|
5
5
|
"bugs": "https://github.com/commercetools/merchant-center-application-kit/issues",
|
|
6
6
|
"repository": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@babel/register": "^7.22.15",
|
|
46
46
|
"@babel/runtime": "^7.22.15",
|
|
47
47
|
"@babel/runtime-corejs3": "^7.22.15",
|
|
48
|
-
"@commercetools-frontend/constants": "27.5.
|
|
48
|
+
"@commercetools-frontend/constants": "27.5.2",
|
|
49
49
|
"@types/lodash": "^4.14.198",
|
|
50
50
|
"@types/react": "^19.0.3",
|
|
51
51
|
"ajv": "8.18.0",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@types/jsdom": "^21.1.2",
|
|
62
62
|
"json-schema-to-typescript": "15.0.4",
|
|
63
|
-
"@commercetools-frontend/assets": "27.5.
|
|
63
|
+
"@commercetools-frontend/assets": "27.5.2"
|
|
64
64
|
},
|
|
65
65
|
"engines": {
|
|
66
66
|
"node": "18.x || 20.x || >=22.0.0"
|