{"record":{"id":"24a28b86ffa4a66b","repo":"octobercms/october","slug":"cms-lang-cms-object-invalid-file-24a28b","errorCode":null,"errorMessage":"cms::lang.cms_object.invalid_file","messagePattern":"cms::lang\\.cms_object\\.invalid_file","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"error","filePath":"modules/cms/classes/Lang.php","lineNumber":209,"sourceCode":"        $foundTheme = $this->theme;\n\n        if (!File::isFile($filePath)) {\n            // Look at parent\n            if ($parentTheme = $this->theme->getParentTheme()) {\n                $foundTheme = $parentTheme;\n                $filePath = $parentTheme->getPath().'/'.$this->dirName.'/'.$fileName;\n\n                if (!File::isFile($filePath)) {\n                    return null;\n                }\n            }\n            else {\n                return null;\n            }\n        }\n\n        if (!FileHelper::validateInTheme($foundTheme, $filePath)) {\n            throw new ValidationException(['fileName' =>\n                LangHelper::get('cms::lang.cms_object.invalid_file', [\n                    'name' => $fileName\n                ])\n            ]);\n        }\n\n        if (($content = @File::get($filePath)) === false) {\n            return null;\n        }\n\n        $this->fileName = $fileName;\n        $this->originalFileName = $fileName;\n        $this->mtime = File::lastModified($filePath);\n        $this->content = $content;\n        $this->exists = true;\n\n        return $this;\n    }","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/cms/classes/Lang.php#L191-L227","documentation":"ValidationException thrown while loading a theme language file: the requested file name resolved to a path that fails `FileHelper::validateInTheme()`, i.e. the path does not stay inside the theme directory. Theme lang files live in `themes/<theme>/lang/` and must be plain .json base names; any `../` traversal, absolute path, or otherwise escaping path is rejected before the file is read.","triggerScenarios":"Loading a lang object with a file name containing '../' (e.g. '../../config/app.json'), a leading slash / absolute path, or any segment that resolves outside the theme root; a crafted `fileName` parameter sent to a lang-file management endpoint.","commonSituations":"Path-traversal attempts against theme file APIs; an API client or import script passing OS-style paths instead of base file names; code reused from a different file API that assumed subdirectory support.","solutions":["Pass only a plain base file name (e.g. 'en.json') — never directories, absolute paths, or traversal sequences.","Sanitize incoming file names with `basename()` plus an allow-list regex before handing them to the Lang API.","If you legitimately need nested lang files, use the theme's own directory structure support, not path strings in fileName."],"exampleFix":"// before\n$file = Lang::load($theme, '../config/secrets.json');\n\n// after — base name only, must live inside themes/<theme>/lang/\n$file = Lang::load($theme, 'en.json');","handlingStrategy":"validation","validationCode":"$fileName = $request->input('fileName');\nif (!is_string($fileName) || !preg_match('/^[\\w\\-\\.]+\\.json$/i', $fileName)) {\n    throw new ValidationException(['fileName' => 'Invalid file name']);\n}\n// basename() as belt-and-braces, then load\n$lang = Lang::load($theme, basename($fileName));","typeGuard":null,"tryCatchPattern":"try {\n    $lang = Lang::load($theme, $fileName);\n} catch (Winter\\Storm\\Exception\\ValidationException $e) {\n    // invalid_file means the name escaped the theme: reject, never retry raw input\n    return back()->withErrors($e->getErrors());\n}","preventionTips":["Treat any file name containing '/', '\\\\', or '..' as hostile at the request boundary.","Whitelist with a regex (base name + allowed extension) before touching CMS file APIs.","Wrap file-management endpoints in validation middleware so traversal attempts are logged."],"tags":["path-traversal","security","validation","theme","lang"],"backgroundTag":"path-traversal-blocked","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}