{"record":{"id":"b73c725880ed16ed","repo":"Tencent/WeKnora","slug":"invalid-source-path-w-b73c72","errorCode":null,"errorMessage":"invalid source path: %w","messagePattern":"invalid source path: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/file/oss.go","lineNumber":261,"sourceCode":"\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to upload bytes to OSS: %w\", err)\n\t}\n\n\treturn fmt.Sprintf(\"oss://%s/%s\", targetBucket, objectName), nil\n}\n\n// CopyFile copies an existing OSS object to a new knowledge-owned object using a\n// server-side CopyObject (no data leaves OSS). The destination uses the same\n// layout as SaveFile. Returns ErrCrossBackendCopy when srcPath is not an oss:// path.\nfunc (s *ossFileService) CopyFile(ctx context.Context,\n\tsrcPath string, tenantID uint64, knowledgeID string,\n) (string, error) {\n\tsrcBucket, srcKey, err := parseOssFilePath(srcPath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"oss copy rejected source %q: %w\", srcPath, ErrCrossBackendCopy)\n\t}\n\tif err := utils.SafeObjectKey(srcKey); err != nil {\n\t\treturn \"\", fmt.Errorf(\"invalid source path: %w\", err)\n\t}\n\n\text := filepath.Ext(srcPath)\n\tdestKey := fmt.Sprintf(\"%s%d/%s/%s%s\", s.pathPrefix, tenantID, knowledgeID, uuid.New().String(), ext)\n\n\t_, err = s.client.CopyObject(ctx, &oss.CopyObjectRequest{\n\t\tBucket:       oss.Ptr(s.bucketName),\n\t\tKey:          oss.Ptr(destKey),\n\t\tSourceBucket: oss.Ptr(srcBucket),\n\t\tSourceKey:    oss.Ptr(srcKey),\n\t})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to copy file in OSS: %w\", err)\n\t}\n\n\tnewPath := fmt.Sprintf(\"oss://%s/%s\", s.bucketName, destKey)\n\tlogger.Infof(ctx, \"Copied OSS object %s to %s\", srcPath, newPath)\n\treturn newPath, nil","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/file/oss.go#L243-L279","documentation":"This error is returned by ossFileService.CopyFile when utils.SafeObjectKey rejects the object key extracted from srcPath. SafeObjectKey guards against path traversal and unsafe key content (../ segments, absolute keys, illegal characters) before the server-side CopyObject is issued. This is a security-oriented validation failure, not an OSS API failure.","triggerScenarios":"Calling CopyFile with an oss:// path whose object key contains traversal sequences, leading slashes, or other characters rejected by utils.SafeObjectKey.","commonSituations":"User-supplied source keys passed through to CopyFile from an API endpoint; data migrated from another system with keys containing backslashes or '../'; tampered DB records or malicious clients probing for path traversal.","solutions":["Log the offending key and reject the request upstream — do not attempt to sanitize blindly.","Validate/normalize object keys with utils.SafeObjectKey before persisting or accepting them from clients.","Ensure keys are generated server-side (as SaveFile does with UUIDs) rather than taken from user input.","Audit data stores for legacy keys containing traversal or control characters."],"exampleFix":"// before\nsrcBucket, srcKey, _ := parseOssFilePath(userInput)\nnewPath, err := svc.CopyFile(ctx, userInput, tenantID, knowledgeID)\n// after\n_, srcKey, err := parseOssFilePath(userInput)\nif err == nil {\n    if safeErr := utils.SafeObjectKey(srcKey); safeErr != nil {\n        return fmt.Errorf(\"rejected unsafe key %q\", srcKey)\n    }\n}\nnewPath, err := svc.CopyFile(ctx, userInput, tenantID, knowledgeID)","handlingStrategy":"validation","validationCode":"_, srcKey, err := parseOssFilePath(srcPath)\nif err == nil {\n    if err := utils.SafeObjectKey(srcKey); err != nil {\n        return fmt.Errorf(\"reject unsafe source key %q\", srcKey)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := copyFile(...); err != nil {\n    if strings.Contains(err.Error(), \"invalid source path\") {\n        // treat as client error (400), never retry\n    }\n}","preventionTips":["Never accept raw object keys from clients; generate them server-side.","Run utils.SafeObjectKey on every key at write/ingest time.","Reject keys containing traversal segments or control characters before persistence.","Audit legacy records for unsafe keys and remediate them."],"tags":["oss","copy","validation","path-traversal","security"],"backgroundTag":"unsafe-object-key","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}