{"record":{"id":"f527265daaf9867a","repo":"apache/beam","slug":"file-path-q-is-outside-destination-directory-q","errorCode":null,"errorMessage":"file path %q is outside destination directory %q","messagePattern":"file path %q is outside destination directory %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"sdks/go/pkg/beam/core/runtime/xlangx/expansionx/download.go","lineNumber":149,"sourceCode":"\t\treturn \"\", fmt.Errorf(\"error in creating jar %s: %w\", jarPath, err)\n\t}\n\n\t_, err = io.Copy(file, resp.Body)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error in coping file %s inside jar %s: %w\", file.Name(), jarPath, err)\n\t}\n\n\treturn jarPath, nil\n}\n\nfunc validatePath(dest, filename string) (string, error) {\n\tdestPath := filepath.Join(dest, filename)\n\tcleanDest := filepath.Clean(dest)\n\tcleanPath := filepath.Clean(destPath)\n\n\trel, err := filepath.Rel(cleanDest, cleanPath)\n\tif err != nil || strings.HasPrefix(rel, \"..\"+string(filepath.Separator)) || rel == \"..\" {\n\t\treturn \"\", fmt.Errorf(\"file path %q is outside destination directory %q\", filename, dest)\n\t}\n\treturn cleanPath, nil\n}\n\nfunc extractJar(source, dest string) error {\n\treader, err := zip.OpenReader(source)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error opening jar for extractJar(%s,%s): %w\", source, dest, err)\n\t}\n\n\tif err := os.MkdirAll(dest, 0700); err != nil {\n\t\treturn fmt.Errorf(\"error creating directory %s in extractJar(%s,%s): %w\", dest, source, dest, err)\n\t}\n\n\tfor _, file := range reader.File {\n\t\tfileName, err := validatePath(dest, file.Name)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error validating file path (%s, %s): %w\", dest, file.Name, err)","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/runtime/xlangx/expansionx/download.go#L131-L167","documentation":"validatePath defends against Zip Slip: before extracting an entry it joins dest with the entry's filename and verifies via filepath.Rel that the cleaned path stays inside the destination directory. If the archive entry contains ../ segments or an absolute path escaping dest, extraction is refused with this error. This prevents a malicious jar from writing files outside the extraction directory.","triggerScenarios":"extractJar iterates zip entries and calls validatePath(dest, file.Name) for an entry whose cleaned path resolves outside dest (e.g. name \"../../.bashrc\" or \"/etc/passwd\").","commonSituations":"Extracting a tampered or maliciously crafted expansion-service jar; jars built with entries containing backslashes/absolute paths from non-standard zip tools.","solutions":["Do not extract this jar — treat it as unsafe and delete it.","Re-download the jar from the official Maven/Beam repository to replace a possibly tampered file.","Inspect the zip entries (unzip -l) to find which entry escapes the destination.","If you control jar creation, rebuild it with relative, sanitized entry names."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-scan the jar for entries that would escape the destination\nr, err := zip.OpenReader(jarPath)\nif err != nil { return err }\nfor _, f := range r.File {\n    p := filepath.Clean(filepath.Join(dest, f.Name))\n    if !strings.HasPrefix(p, filepath.Clean(dest)+string(filepath.Separator)) {\n        return fmt.Errorf(\"unsafe entry %q; refusing to use jar\", f.Name)\n    }\n}","typeGuard":null,"tryCatchPattern":"err := expansionx.MakeJar(ctx, url, dest)\nif err != nil && strings.Contains(err.Error(), \"outside destination directory\") {\n    os.Remove(jarPath)\n    return fmt.Errorf(\"rejected jar from %s: path traversal detected\", url)\n}","preventionTips":["Only download jars from trusted repositories (Maven Central / official Beam artifacts).","Verify jar checksums/signatures before extraction.","Scan downloaded archives for ../ entry names in supply-chain checks.","Never extract untrusted archives into shared or home directories."],"tags":["go","security","zip-slip","path-traversal"],"backgroundTag":"path-traversal-blocked","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}