{"record":{"id":"05b77cb81f7e5f41","repo":"microsoft/semantic-kernel","slug":"path-path-contains-a-dot-segment-which-could","errorCode":null,"errorMessage":"Path '{path}' contains a dot-segment, which could lead to path traversal.","messagePattern":"Path '(.+?)' contains a dot-segment, which could lead to path traversal\\.","errorType":"exception","errorClass":"KernelException","httpStatus":null,"severity":"critical","filePath":"dotnet/src/Functions/Functions.OpenApi/Model/RestApiOperation.cs","lineNumber":460,"sourceCode":"    {\n        { RestApiParameterStyle.Simple, SimpleStyleParameterSerializer.Serialize },\n        { RestApiParameterStyle.Form, FormStyleParameterSerializer.Serialize },\n        { RestApiParameterStyle.SpaceDelimited, SpaceDelimitedStyleParameterSerializer.Serialize },\n        { RestApiParameterStyle.PipeDelimited, PipeDelimitedStyleParameterSerializer.Serialize }\n    };\n\n    /// <summary>\n    /// Validates that the path does not contain dot-segments (. or ..) that could enable path traversal,\n    /// including percent-encoded forms (e.g. \"%2e%2e\") that <see cref=\"Uri\"/> canonicalizes at request time.\n    /// \"..\" navigates up one path segment, enabling traversal to unintended endpoints.\n    /// \".\" refers to the current directory — harmless but unexpected, so rejected to prevent misuse.\n    /// </summary>\n    /// <param name=\"path\">The path to validate.</param>\n    private static void ValidatePathSegments(string path)\n    {\n        if (ContainsDotSegment(path))\n        {\n            throw new KernelException($\"Path '{path}' contains a dot-segment, which could lead to path traversal.\");\n        }\n    }\n\n    /// <summary>\n    /// Determines whether the supplied path contains a dot-segment (. or ..), including percent-encoded\n    /// forms (e.g. \"%2e%2e\") that <see cref=\"Uri\"/> canonicalizes at request time. This is used both to\n    /// reject such paths when building a request URL and to exclude them during operation selection so an\n    /// encoded dot-segment cannot bypass an include/exclude operation-selection filter.\n    /// </summary>\n    /// <param name=\"path\">The path to inspect.</param>\n    /// <returns><see langword=\"true\"/> if the path contains a dot-segment; otherwise, <see langword=\"false\"/>.</returns>\n    internal static bool ContainsDotSegment(string path)\n    {\n        if (string.IsNullOrEmpty(path))\n        {\n            return false;\n        }\n","sourceCodeStart":442,"sourceCodeEnd":478,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/dotnet/src/Functions/Functions.OpenApi/Model/RestApiOperation.cs#L442-L478","documentation":"SSRF guard in RestApiOperation.BuildPath (via ValidatePathSegments / ContainsDotSegment). After path parameters are substituted, the resulting path is scanned for '.' or '..' segments - including percent-encoded forms like %2e, %2e%2e, and even double-encoded %252e that Uri would canonicalize at request time. A dot-segment can navigate outside the intended path, so the request is refused.","triggerScenarios":"A path parameter value (or a literal path template) containing '.', '..', %2e, %2e%2e, or encoded separator forms (%2f/%5c) that decode to a dot-segment. Because argument values are URL-encoded into the path, a malicious or malformed value can introduce traversal.","commonSituations":"User- or model-supplied path argument that includes '..'; a spec path authored with a '..' literal; an attempt to supply a value like '..%2fadmin'; values that, once percent-decoded and re-split on '/' or backslash, yield a '.' or '..' token.","solutions":["Sanitize path argument values before invocation: reject any value whose segments decode to '.' or '..' (see the ContainsDotSegment algorithm).","Avoid putting free-form user input directly into path parameters; validate against an allow-list of safe segment characters.","If '..' is legitimately part of a name (rare), encode it differently or move the value to a query parameter instead of a path segment.","Treat this as a security control, not a bug to suppress - it blocks path traversal."],"exampleFix":"// before - unsanitized value can carry a dot-segment\narguments[\"file\"] = \"../../etc/passwd\";\n\n// after - validate the segment first\nstatic bool IsSafePathSegment(string v)\n    => !v.Split('/', '\\\\').Select(Uri.UnescapeDataString).Any(s => s is \".\" or \"..\");\nif (!IsSafePathSegment(value)) throw new ArgumentException(\"unsafe path segment\");\narguments[\"file\"] = value;","handlingStrategy":"validation","validationCode":"static bool ContainsDotSegment(string path)\n{\n    if (string.IsNullOrEmpty(path)) return false;\n    foreach (var raw in path.Split('/'))\n    {\n        var d = raw;\n        for (int i = 0; i < 5; i++) { var u = Uri.UnescapeDataString(d); if (u == d) break; d = u; }\n        foreach (var seg in d.Split('/', '\\\\')) if (seg is \".\" or \"..\") return true;\n    }\n    return false;\n}\nif (ContainsDotSegment(value)) throw new ArgumentException(\"Path argument contains a dot-segment.\");","typeGuard":"static bool IsSafePathValue(string v)\n{\n    if (string.IsNullOrEmpty(v)) return true;\n    foreach (var raw in v.Split('/', '\\\\'))\n    { var d = raw; for (int i=0;i<5;i++){var u=Uri.UnescapeDataString(d); if(u==d)break; d=u;} if (d is \".\" or \"..\") return false; }\n    return true;\n}","tryCatchPattern":"try { var url = operation.BuildOperationUrl(arguments); }\ncatch (KernelException ex) when (ex.Message.Contains(\"dot-segment\"))\n{ logger.LogWarning(ex, \"Path traversal attempt blocked in a path argument.\"); throw; }","preventionTips":["Sanitize all path argument values before invocation; reject any '.' or '..' segment.","Never pass raw user input directly into a path parameter.","Prefer query parameters for free-form values over path parameters."],"tags":["openapi","ssrf","rest-operation","security","path-traversal"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}