{"record":{"id":"b69e19d744f3a8ab","repo":"siyuan-note/siyuan","slug":"invalid-package-name","errorCode":null,"errorMessage":"invalid package name","messagePattern":"invalid package name","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/model/bazaar.go","lineNumber":58,"sourceCode":"\tPkg     *bazaar.Package\n\tDirName string\n}\n\n// UpdatedPackage 描述本地已安装包及其在线可用更新\ntype UpdatedPackage struct {\n\tInstalled *bazaar.Package `json:\"installed\"`\n\tAvailable *bazaar.Package `json:\"available\"`\n}\n\nfunc isValidPackageName(packageName string) bool {\n\treturn bazaar.IsValidPackageName(packageName)\n}\n\nfunc getPackageInstallPath(pkgType, packageName string) (string, string, error) {\n\t// 校验包名必须是合法的目录名，不能包含路径分隔符或 ..，防止路径遍历\n\t// https://github.com/siyuan-note/siyuan/security/advisories/GHSA-wr4w-7vjm-mmx3\n\tif !isValidPackageName(packageName) {\n\t\treturn \"\", \"\", errors.New(\"invalid package name\")\n\t}\n\n\tvar baseDir, jsonFileName string\n\tswitch pkgType {\n\tcase \"plugins\":\n\t\tbaseDir, jsonFileName = filepath.Join(util.DataDir, \"plugins\"), \"plugin.json\"\n\tcase \"themes\":\n\t\tbaseDir, jsonFileName = util.ThemesPath, \"theme.json\"\n\tcase \"icons\":\n\t\tbaseDir, jsonFileName = util.IconsPath, \"icon.json\"\n\tcase \"templates\":\n\t\tbaseDir, jsonFileName = filepath.Join(util.DataDir, \"templates\"), \"template.json\"\n\tcase \"widgets\":\n\t\tbaseDir, jsonFileName = filepath.Join(util.DataDir, \"widgets\"), \"widget.json\"\n\tdefault:\n\t\tlogging.LogErrorf(\"invalid package type: %s\", pkgType)\n\t\treturn \"\", \"\", errors.New(\"invalid package type\")\n\t}","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/bazaar.go#L40-L76","documentation":"getPackageInstallPath rejects marketplace package names that fail isValidPackageName before building any filesystem path. The name must be a legal directory name without path separators or '..'; this is a hardening measure against path traversal (GHSA-wr4w-7vjm-mmx3). Any install/update call with a malformed packageName fails with this error.","triggerScenarios":"Calling installBazaarPackage, InstallLocalBazaarPackage, or UpdateBazaarPackage with a packageName containing '/', '\\\\', '..', or other characters rejected by isValidPackageName; also hit indirectly when a marketplace manifest or local package JSON supplies a hostile or malformed name.","commonSituations":"Installing from a hand-edited or third-party package manifest whose name field embeds a subpath (e.g. 'foo/bar'); automated scripts interpolating paths into packageName; malicious payloads probing path traversal in local-package install endpoints.","solutions":["Sanitize the package name: pass only the bare directory name, without slashes or '..' segments","If the package lives in a subdirectory, handle the base directory at the API level rather than encoding it in packageName","Verify the source manifest's packageName is a simple identifier before calling install/update"],"exampleFix":"// before\ninstallBazaarPackage(\"plugins\", \"acme/plugin\", repoURL, hash)\n// after\nname := filepath.Base(\"acme/plugin\") // \"plugin\"\nif isValidPackageName(name) {\n    installBazaarPackage(\"plugins\", name, repoURL, hash)\n}","handlingStrategy":"validation","validationCode":"function isValidPackageName(name) {\n  return typeof name === \"string\" && name.length > 0 &&\n    !/[\\\\/]/.test(name) && !name.includes(\"..\") && name === path.basename(name);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate packageName is a bare directory name before any install/update call","Never interpolate user or manifest paths into packageName","Keep the GHSA-wr4w-7vjm-mmx3 advisory in mind: treat names as untrusted input"],"tags":["security","path-traversal","marketplace","validation"],"backgroundTag":"path-traversal-blocked","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}