{"record":{"id":"5cdcbc6bd31d37f5","repo":"BerriAI/litellm","slug":"field-name-cannot-be-a-dot-path-segment","errorCode":null,"errorMessage":"{field_name} cannot be a dot path segment","messagePattern":"(.+?) cannot be a dot path segment","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/litellm_core_utils/url_utils.py","lineNumber":62,"sourceCode":"    \"\"\"Raised when a URL targets a blocked network.\"\"\"\n\n\ndef encode_url_path_segment(value: Any, *, field_name: str = \"path parameter\") -> str:\n    \"\"\"Percent-encode one user-controlled URL path segment.\n\n    ``urllib.parse.quote(..., safe=\"\")`` intentionally leaves RFC 3986\n    unreserved characters such as ``.`` unescaped, so reject standalone dot\n    segments before they can be appended to an upstream URL and normalized by\n    the HTTP client.\n    \"\"\"\n    if value is None:\n        raise ValueError(f\"{field_name} is required\")\n\n    value_str: Final = str(value)\n    if value_str == \"\":\n        raise ValueError(f\"{field_name} is required\")\n    if value_str in {\".\", \"..\"}:\n        raise ValueError(f\"{field_name} cannot be a dot path segment\")\n\n    return quote(value_str, safe=\"\")\n\n\ndef encode_url_path_segments(value: Any, *, field_name: str = \"path\") -> str:\n    \"\"\"Percent-encode a user-controlled URL path made of multiple segments.\n\n    Empty segments are rejected, so leading, trailing, or consecutive slashes\n    fail closed instead of being normalized by the HTTP client.\n    \"\"\"\n    if value is None:\n        raise ValueError(f\"{field_name} is required\")\n\n    value_str: Final = str(value)\n    if value_str == \"\":\n        raise ValueError(f\"{field_name} is required\")\n\n    encoded_segments: Final = []","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/litellm_core_utils/url_utils.py#L44-L80","documentation":"ValueError raised by encode_url_path_segment when the segment is exactly '.' or '..'. urllib.parse.quote deliberately leaves RFC 3986 unreserved characters (including '.') unescaped, so standalone dot segments are rejected explicitly — otherwise they would be joined into the upstream URL and normalized by the HTTP client into a path traversal.","triggerScenarios":"User-controlled ids, filenames, or keys equal to '.' or '..' reaching encode_url_path_segment, e.g. ?file_id=.. on a route that builds /files/{file_id} for the upstream provider.","commonSituations":"Security scanners and penetration tests probing path-based routes; clients sending relative path components as identifiers; path fragments copied wholesale and reused as ids.","solutions":["Validate ids against a strict format (UUID, charset whitelist) at the boundary and reject '.'/'..' with 400.","Treat identifiers as opaque tokens; never accept path fragments as ids.","If the value is legitimately a filename, apply a basename/allowlist check before encoding."],"exampleFix":"# before\nfile_id = request.get(\"file_id\")  # \"..\"\npath = encode_url_path_segment(file_id)  # ValueError: file_id cannot be a dot path segment\n\n# after\nfile_id = request.get(\"file_id\", \"\")\nif not re.fullmatch(r\"[A-Za-z0-9_-]{1,128}\", file_id):\n    raise HTTPException(status_code=400, detail=\"invalid file_id\")\npath = encode_url_path_segment(file_id, field_name=\"file_id\")","handlingStrategy":"validation","validationCode":"import re\n\nID_RE = re.compile(r\"[A-Za-z0-9_-]{1,128}\")\nfile_id = request.get(\"file_id\", \"\")\nif file_id in {\".\", \"..\"} or not ID_RE.fullmatch(file_id):\n    raise HTTPException(status_code=400, detail=\"invalid file_id\")\npath = encode_url_path_segment(file_id, field_name=\"file_id\")","typeGuard":"import re\n\nID_RE = re.compile(r\"[A-Za-z0-9_-]{1,128}\")\n\ndef is_safe_path_segment(value: str) -> bool:\n    return bool(value) and value not in {\".\", \"..\"} and bool(ID_RE.fullmatch(value))","tryCatchPattern":"try:\n    path = encode_url_path_segment(value, field_name=\"file_id\")\nexcept ValueError as e:\n    if \"dot path segment\" in str(e):\n        logger.warning(\"path traversal attempt blocked: %r\", value)\n    raise HTTPException(status_code=400, detail=str(e))","preventionTips":["Whitelist identifier formats (UUID, charset regex) instead of accepting arbitrary strings as URL segments.","Log and alert on '.'/'..' inputs — they usually indicate active probing."],"tags":["path-traversal","url-encoding","security","input-validation"],"backgroundTag":"path-traversal-blocked","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}