{"record":{"id":"c12f38ce4c5ff02a","repo":"hiyouga/LlamaFactory","slug":"local-file-access-is-disabled","errorCode":null,"errorMessage":"Local file access is disabled.","messagePattern":"Local file access is disabled\\.","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"src/llamafactory/api/common.py","lineNumber":55,"sourceCode":"\ndef dictify(data: \"BaseModel\") -> dict[str, Any]:\n    try:  # pydantic v2\n        return data.model_dump(exclude_unset=True)\n    except AttributeError:  # pydantic v1\n        return data.dict(exclude_unset=True)\n\n\ndef jsonify(data: \"BaseModel\") -> str:\n    try:  # pydantic v2\n        return json.dumps(data.model_dump(exclude_unset=True), ensure_ascii=False)\n    except AttributeError:  # pydantic v1\n        return data.json(exclude_unset=True, ensure_ascii=False)\n\n\ndef check_lfi_path(path: str) -> None:\n    \"\"\"Checks if a given path is vulnerable to LFI. Raises HTTPException if unsafe.\"\"\"\n    if not ALLOW_LOCAL_FILES:\n        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail=\"Local file access is disabled.\")\n\n    try:\n        os.makedirs(SAFE_MEDIA_PATH, exist_ok=True)\n        real_path = os.path.realpath(path)\n        safe_path = os.path.realpath(SAFE_MEDIA_PATH)\n\n        if not real_path.startswith(safe_path):\n            raise HTTPException(\n                status_code=status.HTTP_403_FORBIDDEN, detail=\"File access is restricted to the safe media directory.\"\n            )\n    except Exception:\n        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=\"Invalid or inaccessible file path.\")\n\n\ndef check_ssrf_url(url: str) -> None:\n    \"\"\"Checks if a given URL is vulnerable to SSRF. Raises HTTPException if unsafe.\"\"\"\n    try:\n        parsed_url = urlparse(url)","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/hiyouga/LlamaFactory/blob/f28afaf6355af515454dfb16c97d728307c93897/src/llamafactory/api/common.py#L37-L73","documentation":"Raised as HTTP 403 by check_lfi_path when a request references a local file path (image/video/audio) but the ALLOW_LOCAL_FILES flag is false. It is a deliberate local-file-inclusion (LFI) protection: the API refuses to read any local media unless local files were explicitly enabled at server startup.","triggerScenarios":"Sending image_url/video_url/audio_url whose value is a local filesystem path (e.g. /home/user/img.png) while the server was started without the flag/env that sets ALLOW_LOCAL_FILES=true.","commonSituations":"Pointing the API at a local dataset directory for convenience in development; migrating from an older LlamaFactory version where local paths were unrestricted; forgetting the deployment hardening added for LFI.","solutions":["Start the API with local file access enabled (set ALLOW_LOCAL_FILES=true or the corresponding launch flag/env in this deployment).","Alternatively serve the media over HTTP(S) so the SSRF-checked URL path is used instead.","Alternatively base64-encode small media into data: URLs, which bypass the local-path branch.","If enabling local files, also place media under SAFE_MEDIA_PATH since access is sandboxed to it."],"exampleFix":"# before\nllamafactory-cli api ...  # default: local files disabled\n# after\nALLOW_LOCAL_FILES=true llamafactory-cli api ...","handlingStrategy":"validation","validationCode":"def is_local_path(u):\n    return not u.startswith((\"http://\", \"https://\", \"data:\"))\n\nfor url in media_urls:\n    if is_local_path(url):\n        assert os.environ.get(\"ALLOW_LOCAL_FILES\") == \"true\", \"encode as data URL or use https\"","typeGuard":"const isLocalPath = (u) => !/^(https?:|data:)/.test(u);","tryCatchPattern":"catch (e) { if (e.status === 403 && e.detail === 'Local file access is disabled.') { return fetchDataUrl(path); /* or https URL */ } throw e; }","preventionTips":["Prefer data: URLs or https URLs for media; treat local paths as an ops decision.","If local files are required, set ALLOW_LOCAL_FILES at deployment time and document it.","Health-check the deployment config before sending local media."],"tags":["security","lfi","api","http-403","multimodal"],"backgroundTag":null,"analyzedSha":"f28afaf6355af515454dfb16c97d728307c93897","analyzedAt":"2026-08-14T21:57:28.298Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}