{"record":{"id":"2362c9b9d33a5e80","repo":"kataras/iris","slug":"invalid-root-name","errorCode":null,"errorMessage":"invalid root name","messagePattern":"invalid root name","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"context/fs.go","lineNumber":139,"sourceCode":"\t\tsubfs, err := fs.Sub(v, direEtries[0].Name())\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tfileSystem = http.FS(subfs)\n\tcase fs.FS:\n\t\tfileSystem = http.FS(v)\n\tdefault:\n\t\tpanic(fmt.Sprintf(`unexpected \"fsOrDir\" argument type of %T (string or http.FileSystem or embed.FS or fs.FS)`, v))\n\t}\n\n\treturn fileSystem\n}\n\n// FindNames accepts a \"http.FileSystem\" and a root name and returns\n// the list containing its file names.\nfunc FindNames(fileSystem http.FileSystem, name string) ([]string, error) {\n\tif strings.Contains(name, \"..\") {\n\t\treturn nil, fmt.Errorf(\"invalid root name\")\n\t}\n\n\tf, err := fileSystem.Open(name) // it's the root dir.\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer f.Close()\n\n\tfi, err := f.Stat()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif !fi.IsDir() {\n\t\treturn []string{name}, nil\n\t}\n\n\tfileinfos, err := f.Readdir(-1)","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/context/fs.go#L121-L157","documentation":"FindNames validates the root name/path before opening it inside the given http.FileSystem and rejects any name containing \"..\", which could traverse outside the root. It returns this error to prevent path traversal attacks when enumerating files.","triggerScenarios":"Calling iris/context FindNames(fileSystem, name) where the name string contains \"..\", e.g. \"../static\" or \"assets/../conf\".","commonSituations":"Building the root name from user input or URL parameters; concatenating a config value with a relative prefix; assuming FindNames cleans paths like http.FileServer does (it does not).","solutions":["Remove \"..\" from the name: pass a clean, absolute-inside-root path (e.g. \"assets/css\"), or use filepath.Clean and re-check the result.","Never derive the root name from raw user input; whitelist allowed root names.","Use fs.Sub on an fs.FS to isolate a subtree instead of navigating with \"..\"."],"exampleFix":"// before\nnames, _ := context.FindNames(assetsFS, \"../embeddings/files\")\n// after\nnames, _ := context.FindNames(assetsFS, \"embeddings/files\") // no \"..\" segments","handlingStrategy":"validation","validationCode":"if strings.Contains(name, \"..\") {\n    return errors.New(\"invalid root name: path traversal not allowed\")\n}","typeGuard":null,"tryCatchPattern":"names, err := context.FindNames(fs, name)\nif err != nil {\n    if strings.Contains(name, \"..\") {\n        http.Error(w, \"invalid path\", http.StatusBadRequest)\n    }\n    return\n}","preventionTips":["Never derive root names from raw user input","Use filepath.Clean and verify no \"..\" remains","Whitelist allowed root names"],"tags":["path-traversal","security","validation"],"backgroundTag":"path-traversal","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}