@mintlify/cli 4.0.900 → 4.0.902

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mintlify/cli",
3
- "version": "4.0.900",
3
+ "version": "4.0.902",
4
4
  "description": "The Mintlify CLI",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"
@@ -40,11 +40,11 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@inquirer/prompts": "7.9.0",
43
- "@mintlify/common": "1.0.682",
44
- "@mintlify/link-rot": "3.0.839",
43
+ "@mintlify/common": "1.0.683",
44
+ "@mintlify/link-rot": "3.0.841",
45
45
  "@mintlify/models": "0.0.259",
46
- "@mintlify/prebuild": "1.0.817",
47
- "@mintlify/previewing": "4.0.873",
46
+ "@mintlify/prebuild": "1.0.818",
47
+ "@mintlify/previewing": "4.0.874",
48
48
  "@mintlify/validation": "0.1.568",
49
49
  "adm-zip": "0.5.16",
50
50
  "chalk": "5.2.0",
@@ -81,5 +81,5 @@
81
81
  "vitest": "2.0.4",
82
82
  "vitest-mock-process": "1.0.4"
83
83
  },
84
- "gitHead": "263dea610693d1d9d202ec714ed0f52dfaa75960"
84
+ "gitHead": "92fa4dcf370b7711aec2d26348ab63fac87d12fb"
85
85
  }
package/src/helpers.tsx CHANGED
@@ -165,8 +165,14 @@ export const suppressConsoleWarnings = (): void => {
165
165
  export const readLocalOpenApiFile = async (
166
166
  filename: string
167
167
  ): Promise<Record<string, unknown> | undefined> => {
168
- const pathname = path.resolve(process.cwd(), filename);
169
- const file = await fs.readFile(pathname, 'utf-8');
168
+ const baseDir = process.cwd();
169
+ // const pathname = path.resolve(process.cwd(), filename);
170
+ const resolvedPath = path.resolve(baseDir, filename);
171
+ const relative = path.relative(baseDir, resolvedPath);
172
+ if (relative.startsWith('..') || path.isAbsolute(relative)) {
173
+ throw new Error('Access denied: invalid path');
174
+ }
175
+ const file = await fs.readFile(resolvedPath, 'utf-8');
170
176
  const document = yaml.load(file) as Record<string, unknown> | undefined;
171
177
  return document;
172
178
  };
package/src/init.tsx CHANGED
@@ -4,6 +4,16 @@ import { docsConfigSchema } from '@mintlify/validation';
4
4
  import AdmZip from 'adm-zip';
5
5
  import fse from 'fs-extra';
6
6
  import { Box, Text } from 'ink';
7
+ import path from 'path';
8
+
9
+ const validatePathWithinCwd = (inputPath: string): void => {
10
+ const baseDir = process.cwd();
11
+ const resolvedPath = path.resolve(baseDir, inputPath);
12
+ const relative = path.relative(baseDir, resolvedPath);
13
+ if (relative.startsWith(`..${path.sep}`) || relative === '..' || path.isAbsolute(relative)) {
14
+ throw new Error(`Access denied: path "${inputPath}" is outside the current directory`);
15
+ }
16
+ };
7
17
 
8
18
  const sendOnboardingMessage = (installDir: string) => {
9
19
  addLogs(
@@ -58,6 +68,9 @@ export async function init(
58
68
  theme?: string,
59
69
  name?: string
60
70
  ): Promise<void> {
71
+ // Validate path is within current working directory to prevent path traversal
72
+ validatePathWithinCwd(installDir);
73
+
61
74
  const isInteractive = process.stdin.isTTY;
62
75
  const isClaudeCode = process.env.CLAUDECODE === '1';
63
76
  const isAI = !isInteractive || isClaudeCode;
@@ -106,6 +119,8 @@ export async function init(
106
119
  throw new Error('Subdirectory name cannot be empty');
107
120
  }
108
121
  installDir = installDir === '.' ? subdir : `${installDir}/${subdir}`;
122
+ // Re-validate after subdirectory is appended
123
+ validatePathWithinCwd(installDir);
109
124
  }
110
125
  }
111
126