/
githubmirror
/
aspnetcore
Обзор
Документация
Войти
/
githubmirror
/
aspnetcore
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Shared/ResultsHelpers/SharedUrlHelper.cs
96 строк
3 KB
Roman Konecny
Reject ASCII control characters in cookie auth return URLs (#66876)
23 июн 2026, 19:04
Не верифицирован
23 июн 2026, 19:04
7c9c01b
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.Internal; internal static class SharedUrlHelper { [return: NotNullIfNotNull("contentPath")] internal static string? Content(HttpContext httpContext, string? contentPath) { if (string.IsNullOrEmpty(contentPath)) { return null; } else if (contentPath[0] == '~') { var segment = new PathString(contentPath.Substring(1)); var applicationPath = httpContext.Request.PathBase; var path = applicationPath.Add(segment); Debug.Assert(path.HasValue); return path.Value; } return contentPath; } // SECURITY: This is the open-redirect guard used by MVC URL helpers, Results.LocalRedirect, // and CookieAuthenticationHandler. Changes to the accepted/rejected shapes (control characters, // "//", "/\", "~/", etc.) must be reviewed against all call sites and the existing test corpus. // Do not relax any check without security review. internal static bool IsLocalUrl([NotNullWhen(true)] string? url) { if (string.IsNullOrEmpty(url)) { return false; } // Allows "/" or "/foo" but not "//" or "/\". if (url[0] == '/') { // url is exactly "/" if (url.Length == 1) { return true; } // url doesn't start with "//" or "/\" if (url[1] != '/' && url[1] != '\\') { return !HasControlCharacter(url.AsSpan(1)); } return false; } // Allows "~/" or "~/foo" but not "~//" or "~/\". if (url[0] == '~' && url.Length > 1 && url[1] == '/') { // url is exactly "~/" if (url.Length == 2) { return true; } // url doesn't start with "~//" or "~/\" if (url[2] != '/' && url[2] != '\\') { return !HasControlCharacter(url.AsSpan(2)); } return false; } return false; static bool HasControlCharacter(ReadOnlySpan<char> readOnlySpan) { // URLs may not contain ASCII control characters. for (var i = 0; i < readOnlySpan.Length; i++) { if (char.IsControl(readOnlySpan[i])) { return true; } } return false; } } }