{"record":{"id":"a3aadece9fb43cd1","repo":"alibaba/Sentinel","slug":"path","errorCode":null,"errorMessage":"${path}","messagePattern":"\\$\\{path\\}","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/util/FilterUtil.java","lineNumber":143,"sourceCode":"            if (index == length) {\n                break;\n            }\n\n            int nextSlashIndex = indexOfSlash(pathChars, index, true);\n\n            String element = new String(pathChars, index, nextSlashIndex - index);\n            index = nextSlashIndex;\n\n            // Ignore \".\"\n            if (\".\".equals(element)) {\n                continue;\n            }\n\n            // Backtrack \"..\"\n            if (\"..\".equals(element)) {\n                if (level == 0) {\n                    if (isAbsolutePath) {\n                        throw new IllegalStateException(path);\n                    } else {\n                        buf.append(\"..\").append(PATH_SPLIT);\n                    }\n                } else {\n                    buf.setLength(pathChars[--level]);\n                }\n\n                continue;\n            }\n\n            pathChars[level++] = (char)buf.length();\n            buf.append(element).append(PATH_SPLIT);\n        }\n\n        // remove the last \"/\"\n        if (buf.length() > 0) {\n            if (!endsWithSlash || removeTrailingSlash) {\n                buf.setLength(buf.length() - 1);","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/alibaba/Sentinel/blob/a3f40ba8e900c8489bd520274739f17235a7721c/sentinel-adapter/sentinel-web-servlet/src/main/java/com/alibaba/csp/sentinel/adapter/servlet/util/FilterUtil.java#L125-L161","documentation":"FilterUtil.normalizePath (sentinel-web-servlet) normalizes the request path (resolving '.' and '..' segments). When the path is absolute and a '..' segment would backtrack above the root (level == 0), it throws IllegalStateException whose message is the raw offending path. This guards the servlet filter against path-traversal-style URLs whose normalized form cannot be represented as an absolute path.","triggerScenarios":"An incoming HTTP request whose servletPath/pathInfo, treated as an absolute path, contains more '..' segments than preceding levels, e.g. '/../../etc/passwd' or '/a/../../..'; the exception is thrown inside getResourcePath/normalizeAbsolutePath during CommonFilter processing.","commonSituations":"Security scanners or penetration tests sending traversal sequences; misbehaving clients or proxies sending unnormalized URLs; tests that feed raw traversal paths to FilterUtil.filterTarget.","solutions":["Reject/sanitize such requests upstream (e.g. a front proxy or earlier filter that normalizes or blocks '..' segments)","Wrap the filter chain with a try/catch for IllegalStateException and return 400 for malformed paths","Upgrade the servlet adapter — later Sentinel versions changed path handling; check the changelog for FilterUtil fixes","If it comes from tests, feed normalized absolute paths without leading '..' overflow"],"exampleFix":"// before\nchain.doFilter(request, response); // traversal path reaches FilterUtil\n\n// after\nString path = request.getPathInfo() != null ? request.getPathInfo() : request.getServletPath();\nif (path.contains(\"..\")) {\n    response.sendError(HttpServletResponse.SC_BAD_REQUEST);\n    return;\n}\nchain.doFilter(request, response);","handlingStrategy":"validation","validationCode":"String p = request.getServletPath() + (request.getPathInfo() == null ? \"\" : request.getPathInfo());\n// count leading-depth vs '..' segments before the filter processes it\nboolean tooManyParent = false; int depth = 0;\nfor (String seg : p.split(\"/\")) {\n    if (\"..\".equals(seg)) { if (depth == 0) { tooManyParent = true; break; } depth--; }\n    else if (!seg.isEmpty() && !\".\".equals(seg)) depth++;\n}\nif (tooManyParent) { /* reject 400 */ }","typeGuard":null,"tryCatchPattern":"try {\n    chain.doFilter(request, response);\n} catch (IllegalStateException e) {\n    response.sendError(HttpServletResponse.SC_BAD_REQUEST);\n}","preventionTips":["Normalize or reject '..'-heavy URLs at the proxy (nginx/nginx-ingress) before they reach the app","Add an early servlet filter that returns 400 for unrepresentable paths","Include traversal URLs in your test suite for the Sentinel web filter"],"tags":["servlet","path-traversal","security","illegal-state","url-normalization"],"backgroundTag":null,"analyzedSha":"a3f40ba8e900c8489bd520274739f17235a7721c","analyzedAt":"2026-08-14T11:10:30.678Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}