High severity8.8NVD Advisory· Published Mar 13, 2026· Updated Apr 14, 2026
CVE-2026-4092
CVE-2026-4092
Description
Path Traversal in Clasp impacting versions < 3.2.0 allows a remote attacker to perform remote code execution via a malicious Google Apps Script project containing specially crafted filenames with directory traversal sequences.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
@google/claspnpm | < 3.2.0 | 3.2.0 |
Affected products
1Patches
1ba6bd666fe74fix: prevent path traversal in remote file synchronization (#1109)
1 file changed · +43 −11
src/core/files.ts+43 −11 modified@@ -55,6 +55,23 @@ function parentDirs(file: string) { } return parentDirs; } +function isInside(parentPath: string, childPath: string): boolean { + + const relative = path.relative(parentPath, childPath); + + return ( + + relative !== '' && + + !relative.startsWith('..') && + + !path.isAbsolute(relative) + + ); + +} + + async function getLocalFiles(rootDir: string, ignorePatterns: string[], recursive: boolean) { debug('Collecting files in %s', rootDir); @@ -190,12 +207,8 @@ export class Files { this.options = options; } - /** +/** * Fetches the content of a script project from Google Drive. - * @param {number} [versionNumber] - Optional version number to fetch. - * If not specified, the latest version (HEAD) is fetched. - * @returns {Promise<ProjectFile[]>} A promise that resolves to an array of project files. - * @throws {Error} If there's an API error or authentication/configuration issues. */ async fetchRemote(versionNumber?: number): Promise<ProjectFile[]> { debug('Fetching remote files, version %s', versionNumber ?? 'HEAD'); @@ -207,29 +220,47 @@ export class Files { const scriptId = this.options.project.scriptId; const script = google.script({version: 'v1', auth: credentials}); const fileExtensionMap = this.options.files.fileExtensions; + try { const requestOptions = {scriptId, versionNumber}; debug('Fetching script content, request %o', requestOptions); + const response = await script.projects.getContent(requestOptions); const files = response.data.files ?? []; + + // 1. Establish the security boundary (the "jail") + const absoluteContentDir = path.resolve(contentDir); + return files.map(f => { const ext = getFileExtension(f.type, fileExtensionMap); - const localPath = path.relative(process.cwd(), path.resolve(contentDir, `${f.name}${ext}`)); - const file = { - localPath: localPath, + // 2. Resolve the absolute path for the remote file + const resolvedPath = path.resolve(contentDir, `${f.name}${ext}`); + + // 3. SECURITY CHECK: Ensure path is strictly inside contentDir + // This prevents traversal (../../) and prefix attacks (/foo/bar vs /foo/bar1) + if (!isInside(absoluteContentDir, resolvedPath)) { + throw new Error( + `Security Error: Remote file name "${f.name}" attempts to write outside the project directory.` + ); + } + + const localPath = path.relative(process.cwd(), resolvedPath); + + const file: ProjectFile = { + localPath, remotePath: f.name ?? undefined, source: f.source ?? undefined, type: f.type ?? undefined, }; + debug('Fetched file %O', file); return file; }); - } catch (error) { - handleApiError(error); + } catch (err) { + throw handleApiError(err as GaxiosError); } } - /** * Collects all local files in the project's content directory, respecting ignore patterns. * It reads the content of each file and determines its type. @@ -570,3 +601,4 @@ function extractSyntaxError(error: GaxiosError, files: ProjectFile[]) { snippet = preLines + '\n' + errLine + '\n' + postLines; return {message, snippet}; // Return the formatted message and snippet. } +
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/google/clasp/pull/1109nvdIssue TrackingPatchWEB
- github.com/advisories/GHSA-hqjg-pww4-pcgqghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-4092ghsaADVISORY
- github.com/google/clasp/commit/ba6bd666fe74de54950122b5d92ecf1dcc02a9d3ghsaWEB
- github.com/google/clasp/releases/tag/v3.2.0ghsaWEB
- github.com/google/clasp/security/advisories/GHSA-hqjg-pww4-pcgqghsaWEB
News mentions
0No linked articles in our index yet.