{"record":{"id":"0a1085afb38488c8","repo":"iflytek/astron-agent","slug":"credential-file-must-be-a-regular-non-symbolic-link-file-0a1085","errorCode":null,"errorMessage":"credential file must be a regular non-symbolic-link file","messagePattern":"credential file must be a regular non-symbolic-link file","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tenant/config/credential_file_other.go","lineNumber":18,"sourceCode":"//go:build !linux && !darwin\n\npackage config\n\nimport (\n\t\"errors\"\n\t\"os\"\n)\n\n// openCredentialFileNoFollow is a portability fallback for platforms without\n// O_NOFOLLOW. Supported production images use the Unix implementation above.\nfunc openCredentialFileNoFollow(fileName string) (*os.File, error) {\n\tpathInfo, err := os.Lstat(fileName)\n\tif err != nil {\n\t\treturn nil, errors.New(\"credential file is unavailable\")\n\t}\n\tif pathInfo.Mode()&os.ModeSymlink != 0 || !pathInfo.Mode().IsRegular() {\n\t\treturn nil, errors.New(\n\t\t\t\"credential file must be a regular non-symbolic-link file\",\n\t\t)\n\t}\n\tfile, err := os.Open(fileName)\n\tif err != nil {\n\t\treturn nil, errors.New(\"credential file is unavailable\")\n\t}\n\topenedInfo, err := file.Stat()\n\tif err != nil || !openedInfo.Mode().IsRegular() || !os.SameFile(pathInfo, openedInfo) {\n\t\t_ = file.Close()\n\t\treturn nil, errors.New(\"credential file changed while being opened\")\n\t}\n\treturn file, nil\n}\n","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/tenant/config/credential_file_other.go#L1-L33","documentation":"openCredentialFileNoFollow refuses to open a credential file that is not a regular file or is a symbolic link. This is a security guard against symlink-based attacks where an attacker swaps the credential path to point elsewhere (e.g. /proc, /etc/shadow). The file must be a plain regular file at the given path.","triggerScenarios":"Calling openCredentialFileNoFollow with a path that is a symlink, a directory, a FIFO/socket/device, or otherwise not a regular file (checked via os.Lstat mode).","commonSituations":"Deployment tools placing credentials behind symlinked paths (e.g. Kubernetes symlinked secret mounts, /etcalternatives-style links); running the tenant service with a config pointing at a symlink created by a provisioning script; mount points or sockets accidentally used as the credential file path.","solutions":["Replace the symlink with a real regular file containing the credential (e.g. copy the target content to the path)","Fix the deployment/config so the credential path points directly at the regular secret file","If on Linux, note the unix build (credential_file_unix.go) rejects only ELOOP; check whether the file is actually a non-regular file type (FIFO/dir) and correct it"],"exampleFix":"// before\nln -s /var/secrets/tenant.key /etc/tenant/credential.key\n// after\ncp /var/secrets/tenant.key /etc/tenant/credential.key && rm /etc/tenant/credential.key.bak","handlingStrategy":"validation","validationCode":"info, err := os.Lstat(path)\nif err != nil || info.Mode()&os.ModeSymlink != 0 || !info.Mode().IsRegular() {\n    return fmt.Errorf(\"credential path %q must be a regular non-symlink file\", path)\n}","typeGuard":"func isRegularNonSymlink(path string) bool {\n    info, err := os.Lstat(path)\n    return err == nil && info.Mode()&os.ModeSymlink == 0 && info.Mode().IsRegular()\n}","tryCatchPattern":"f, err := openCredentialFileNoFollow(path)\nif err != nil {\n    if err.Error() == \"credential file must be a regular non-symbolic-link file\" {\n        // resolve/replace symlink or abort startup with a clear config message\n    }\n    return err\n}","preventionTips":["Never deploy credentials behind symlinks; copy or bind-mount the real file","Resolve symlinks (filepath.EvalSymlinks) before configuring the credential path","Add a pre-start config check that lstats the path and asserts regular-file mode","In Kubernetes use secret subPath mounts so the file appears as a regular file"],"tags":["go","filesystem","security","symlink"],"backgroundTag":"invalid-config-value","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}