{"record":{"id":"96523df36fb87d8e","repo":"symfony/http-foundation","slug":"invalid-uri-a-uri-cannot-contain-a-backslash","errorCode":null,"errorMessage":"Invalid URI: A URI cannot contain a backslash.","messagePattern":"Invalid URI: A URI cannot contain a backslash\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"Request.php","lineNumber":409,"sourceCode":"        $server['REQUEST_METHOD'] = strtoupper($method);\n\n        if (($i = strcspn($uri, ':/?#')) && ':' === ($uri[$i] ?? null) && (strspn($uri, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-.') !== $i || strcspn($uri, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'))) {\n            throw new BadRequestException('Invalid URI: Scheme is malformed.');\n        }\n        if (false === $components = parse_url(\\strlen($uri) !== strcspn($uri, '?#') ? $uri : $uri.'#')) {\n            throw new BadRequestException('Invalid URI.');\n        }\n\n        $part = ($components['user'] ?? '').':'.($components['pass'] ?? '');\n\n        if (':' !== $part && \\strlen($part) !== strcspn($part, '[]')) {\n            throw new BadRequestException('Invalid URI: Userinfo is malformed.');\n        }\n        if (($part = $components['host'] ?? '') && !self::isHostValid($part)) {\n            throw new BadRequestException('Invalid URI: Host is malformed.');\n        }\n        if (false !== ($i = strpos($uri, '\\\\')) && $i < strcspn($uri, '?#')) {\n            throw new BadRequestException('Invalid URI: A URI cannot contain a backslash.');\n        }\n        if (\\strlen($uri) !== strcspn($uri, \"\\r\\n\\t\")) {\n            throw new BadRequestException('Invalid URI: A URI cannot contain CR/LF/TAB characters.');\n        }\n        if ('' !== $uri && (\\ord($uri[0]) <= 32 || \\ord($uri[-1]) <= 32)) {\n            throw new BadRequestException('Invalid URI: A URI must not start nor end with ASCII control characters or spaces.');\n        }\n\n        if (isset($components['host'])) {\n            $server['SERVER_NAME'] = $components['host'];\n            $server['HTTP_HOST'] = $components['host'];\n        }\n\n        if (isset($components['scheme'])) {\n            if ('https' === $components['scheme']) {\n                $server['HTTPS'] = 'on';\n                $server['SERVER_PORT'] = 443;\n            } else {","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/symfony/http-foundation/blob/5aea19cd678fa4140f6108406f1096de5e9ed6e4/Request.php#L391-L427","documentation":"Request::create() rejects any URI containing a backslash that appears before the first '?' or '#'. Backslashes are not valid URI characters but some servers/clients normalize them to '/', which enables path-confusion and filter-bypass attacks; the library therefore fails fast with BadRequestException ('Invalid URI: A URI cannot contain a backslash.') producing HTTP 400.","triggerScenarios":"Calling Request::create() with a URI such as 'http://host\\path' or '/foo\\bar?x=1' where strpos($uri, '\\\\') is before strcspn($uri, '?#') (Request.php:407-409). Windows-style path separators in the path portion trigger it; backslashes after '?' or '#' (inside query/fragment) are allowed.","commonSituations":"Code that builds URIs by concatenating Windows file paths; user input containing \\\\ Sequences passed through to routing; security tests probing path-normalization bypasses; proxies forwarding raw request targets with backslashes.","solutions":["Replace backslashes with forward slashes in the path before calling Request::create(): str_replace('\\\\', '/', $uri).","Encode any literal backslash that must be kept (e.g. in a query value) as %5C, or move it after '?' / '#'.","Sanitize user-supplied path segments with rawurlencode() per segment instead of interpolating raw paths.","Catch BadRequestException when the URI originates from untrusted input and return a 400."],"exampleFix":"// before\n$request = Request::create('http://example.com/C:\\\\dir\\\\file');\n// after\n$uri = str_replace('\\\\', '/', 'http://example.com/C:/dir/file');\n$request = Request::create($uri);","handlingStrategy":"validation","validationCode":"function hasNoBackslashInPath(string $uri): bool\n{\n    $i = strpos($uri, '\\\\');\n\n    return false === $i || $i >= strcspn($uri, '?#');\n}\nif (!hasNoBackslashInPath($uri)) {\n    $uri = preg_replace('/^(.*?):(\\/\\/[^?#]*)\\\\/', '$1:$2/', $uri) ?? $uri; // or reject\n}","typeGuard":"function isSlashNormalizedUri(string $uri): bool\n{\n    $path = parse_url($uri, PHP_URL_PATH) ?? '';\n\n    return false === strpos($path, '\\\\');\n}","tryCatchPattern":"try {\n    $request = Request::create($uri);\n} catch (BadRequestException $e) {\n    if (str_contains($e->getMessage(), 'backslash')) {\n        $request = Request::create(str_replace('\\\\', '/', $uri));\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Never build URI paths by concatenating raw filesystem paths — join segments with '/' and rawurlencode() each one","Normalize Windows-style separators (str_replace('\\\\', '/', ...)) at the boundary where paths become URLs","Reject backslashes in user-supplied paths early instead of silently rewriting them","Keep any intentional literal backslash inside the query string, percent-encoded as %5C"],"tags":["http","uri-validation","request","security"],"backgroundTag":"invalid-url-format","analyzedSha":"5aea19cd678fa4140f6108406f1096de5e9ed6e4","analyzedAt":"2026-09-13T01:52:22.855Z","contentChangedAt":"2026-09-13T01:52:22.855Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}