{"record":{"id":"88950f222b4668e1","repo":"OpenNHP/opennhp","slug":"fail-to-get-resource-absolute-path-w","errorCode":null,"errorMessage":"fail to get resource absolute path: %w","messagePattern":"fail to get resource absolute path: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"endpoints/server/kbs/resource/resource.go","lineNumber":168,"sourceCode":"\t\t\"iv\":            base64.RawURLEncoding.EncodeToString(iv),\n\t\t\"ciphertext\":    base64.RawURLEncoding.EncodeToString(encryptedContent),\n\t\t\"tag\":           \"\",\n\t}\n\n\tc.JSON(http.StatusOK, response)\n}\n\nfunc loadResource(resourceID string) ([]byte, error) {\n\tabsBaseDir, err := filepath.Abs(baseDir)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"fail to get base directory absolute path: %w\", err)\n\t}\n\n\tfullPath := filepath.Join(absBaseDir, resourceID)\n\n\tabsFullPath, err := filepath.Abs(fullPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"fail to get resource absolute path: %w\", err)\n\t}\n\n\t// Check if the path is within the base directory to avoid path traversal attack.\n\tif !strings.HasPrefix(absFullPath, absBaseDir) {\n\t\treturn nil, errors.New(\"invalid resource ID: potential path traversal attack\")\n\t}\n\n\tif _, statErr := os.Stat(absFullPath); statErr != nil {\n\t\tif os.IsNotExist(statErr) {\n\t\t\treturn nil, errors.New(\"resource not found\")\n\t\t}\n\t\treturn nil, fmt.Errorf(\"fail to check resource: %w\", statErr)\n\t}\n\n\tdata, err := os.ReadFile(absFullPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"fail to read resource: %w\", err)\n\t}","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/server/kbs/resource/resource.go#L150-L186","documentation":"loadResource resolves the joined resource path to an absolute form via filepath.Abs before the path-traversal check. This error is returned when filepath.Abs(fullPath) fails (wrapped as 'fail to get resource absolute path: %w'). As with the base-dir variant, this only happens when os.Getwd fails.","triggerScenarios":"GetResource calls loadResource with a resourceID; the joined fullPath goes through filepath.Abs, which fails because the process cwd is invalid (deleted/unmounted).","commonSituations":"Same env conditions as error 118: removed working directory, chroot with stale cwd, container workdir unmounted; typically surfaces together with error 118 during the same request.","solutions":["Fix or restart the daemon so it runs with a valid working directory","Set absolute baseDir at startup and avoid per-request filepath.Abs calls","Configure a stable WorkingDirectory in systemd/Docker","Inspect the wrapped getwd error to confirm root cause"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if strings.Contains(resourceID, \"..\") || filepath.IsAbs(resourceID) {\n\treturn fmt.Errorf(\"resourceID must be a relative path segment\")\n}\nif !filepath.IsAbs(baseDir) {\n\treturn fmt.Errorf(\"baseDir must be an absolute path\")\n}","typeGuard":null,"tryCatchPattern":"data, err := loadResource(resourceID)\nif err != nil {\n\tif strings.Contains(err.Error(), \"fail to get resource absolute path\") {\n\t\thttp.Error(w, \"resource store unavailable\", http.StatusInternalServerError)\n\t\treturn\n\t}\n\tif strings.Contains(err.Error(), \"path traversal\") {\n\t\thttp.Error(w, \"invalid resource ID\", http.StatusBadRequest)\n\t\treturn\n\t}\n\thttp.Error(w, \"resource not found\", http.StatusNotFound)\n\treturn\n}","preventionTips":["Sanitize resourceID before calling loadResource (reject '..' and absolute paths)","Restart the daemon if the working directory was deleted","Set a fixed WorkingDirectory for the service","Resolve paths once at init to avoid per-request getwd dependence"],"tags":["go","filesystem","filepath"],"backgroundTag":"invalid-config-value","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}