{"record":{"id":"113edb1b2afbad18","repo":"hyperledger/fabric","slug":"refusing-to-copy-absolute-symlink-s-s","errorCode":null,"errorMessage":"refusing to copy absolute symlink %s -> %s","messagePattern":"refusing to copy absolute symlink (.+?) -> (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/container/externalbuilder/copy.go","lineNumber":66,"sourceCode":"\t})\n\t// If an error occurred, clean up any created files.\n\tif err != nil {\n\t\tif err := os.RemoveAll(destroot); err != nil {\n\t\t\tlogger.Errorf(\"failed to remove destination directory %s after copy error: %s\", destroot, err)\n\t\t}\n\t\treturn errors.WithMessagef(err, \"failed to copy %s to %s\", srcroot, destroot)\n\t}\n\treturn nil\n}\n\nfunc copySymlink(srcroot, srcpath, destpath string) error {\n\t// If the symlink is absolute, then we do not want to copy it.\n\tsymlinkDest, err := os.Readlink(srcpath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif filepath.IsAbs(symlinkDest) {\n\t\treturn errors.Errorf(\"refusing to copy absolute symlink %s -> %s\", srcpath, symlinkDest)\n\t}\n\n\t// Determine where the symlink points to. If it points outside\n\t// of the source root, then we do not want to copy it.\n\tsymlinkDir := filepath.Dir(srcpath)\n\tsymlinkTarget := filepath.Clean(filepath.Join(symlinkDir, symlinkDest))\n\trelativeTarget, err := filepath.Rel(srcroot, symlinkTarget)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif relativeTargetElements := strings.Split(relativeTarget, string(os.PathSeparator)); len(relativeTargetElements) >= 1 && relativeTargetElements[0] == \"..\" {\n\t\treturn errors.Errorf(\"refusing to copy symlink %s -> %s pointing outside of source root\", srcpath, symlinkDest)\n\t}\n\n\treturn os.Symlink(symlinkDest, destpath)\n}\n\nfunc copyFile(srcpath, destpath string) error {","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/container/externalbuilder/copy.go#L48-L84","documentation":"copySymlink (used by CopyDir when walking external builder package contents) reads the symlink target with os.Readlink and rejects symlinks whose target is an absolute path. Absolute symlinks are considered unsafe to reproduce in the destination because they can point anywhere on the host filesystem. The copy is aborted and the destination is cleaned up.","triggerScenarios":"copySymlink is invoked from the CopyDir filepath.Walk callback (anonymous walk function) on any symlink entry whose os.Readlink target begins with '/' (filepath.IsAbs true).","commonSituations":"Source trees checked out or built on another machine containing absolute symlinks (e.g. -> /usr/lib/somelib); symlinks created by absolute-path installs; Node.js packages vendored with machine-specific absolute links.","solutions":["Find and fix the offending link: 'find <srcroot> -type l -exec ls -l {} +' and rewrite it to a relative target (e.g. ln -sfn ../lib/foo foo).","Remove unnecessary absolute symlinks from the chaincode package before install.","Recreate the symlink at deploy/runtime (e.g. in the builder's build or release script) rather than shipping it in the source tree.","If the symlink must remain, restructure directories so a relative path can express the target inside the source root."],"exampleFix":"// before\nln -s /opt/tools/bin/cli ./bin/cli   // absolute, refused\n// after\ncd bin && ln -sfn ../../opt/tools/bin/cli cli   // relative target inside tree (if valid)\n// or remove the symlink entirely","handlingStrategy":"validation","validationCode":"// shell: detect absolute symlinks in a package before install\n// find <pkgdir> -type l -exec readlink {} \\; | grep -E '^/' && echo \"absolute symlinks present\" && exit 1","typeGuard":null,"tryCatchPattern":"// Go caller of CopyDir\nif err := CopyDir(logger, src, dst); err != nil {\n    if strings.Contains(err.Error(), \"refusing to copy absolute symlink\") {\n        // rewrite the reported link to a relative target and retry\n    }\n}","preventionTips":["Always create symlinks with relative targets inside the package tree.","Scan packages for absolute symlinks in CI before install/approve.","Re-vendor dependencies that contain machine-specific absolute symlinks.","Recreate symlinks in the builder's build/release phase instead of shipping them."],"tags":["external-builder","symlink","security","copy"],"backgroundTag":"absolute-symlink-refused","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}