Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions web/Areas/CMS/Data/CMS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -383,10 +383,31 @@ public bool CheckFilePermission(CMSFile file)

if (_rapsContext! != null && currentUser != null)
{
if (file.AllowPublicAccess ||
(file.FileToPermissions.Count == 0 && UserHelper.HasPermission(_rapsContext, currentUser, "SVMSecure")) ||
(file.FileToPermissions.Count > 0 && file.FileToPermissions.Any(fp => UserHelper.GetAllPermissions(_rapsContext, currentUser).Any(p => string.Compare(fp.Permission, p.Permission, true) == 0))) ||
(file.FileToPeople.Count > 0 && file.FileToPeople.Any(fp => fp.IamId == currentUser.IamId)))
// Each access path returns early so later (more expensive) checks are
// skipped once access is granted, preserving the original short-circuit.
if (file.AllowPublicAccess)
{
return true;
}
// No explicit permissions: any authenticated SVMSecure user may access.
if (file.FileToPermissions.Count == 0 && UserHelper.HasPermission(_rapsContext, currentUser, "SVMSecure"))
{
return true;
}
// Explicit permissions: the user must hold a matching one. Resolve the user's
// permissions once into a set rather than re-querying for each file permission.
if (file.FileToPermissions.Count > 0)
{
var userPermissions = UserHelper.GetAllPermissions(_rapsContext, currentUser)
.Select(p => p.Permission)
.ToHashSet(StringComparer.OrdinalIgnoreCase);
if (file.FileToPermissions.Any(fp => userPermissions.Contains(fp.Permission)))
{
return true;
}
}
// Explicit people: the user must be listed.
if (file.FileToPeople.Count > 0 && file.FileToPeople.Any(fp => fp.IamId == currentUser.IamId))
{
return true;
}
Expand Down
17 changes: 12 additions & 5 deletions web/ViteProxyHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,12 @@ public static HttpRequestMessage CreateProxyRequest(HttpContext context, string
var requestMessage = new HttpRequestMessage(new HttpMethod(context.Request.Method), targetUrl);

// Only copy request body for methods that typically support it
var method = context.Request.Method.ToUpperInvariant();
if (method != "GET" && method != "HEAD"
&& ((context.Request.ContentLength.HasValue && context.Request.ContentLength > 0) ||
(!context.Request.ContentLength.HasValue && context.Request.Body.CanRead)))
var requestMethod = context.Request.Method;
bool methodSupportsBody = !string.Equals(requestMethod, "GET", StringComparison.OrdinalIgnoreCase)
&& !string.Equals(requestMethod, "HEAD", StringComparison.OrdinalIgnoreCase);
bool hasReadableBody = (context.Request.ContentLength.HasValue && context.Request.ContentLength > 0)
|| (!context.Request.ContentLength.HasValue && context.Request.Body.CanRead);
if (methodSupportsBody && hasReadableBody)
{
requestMessage.Content = new StreamContent(context.Request.Body);

Expand Down Expand Up @@ -348,10 +350,15 @@ public static async Task HandleProxyError(HttpContext context, Exception ex, ILo
var physicalPath = Path.Join(context.RequestServices.GetRequiredService<IWebHostEnvironment>().WebRootPath,
staticPath.TrimStart('/').Replace('/', Path.DirectorySeparatorChar));

// Prevent directory traversal: ensure the resolved physical path is within WebRootPath
// Prevent directory traversal: resolved path must sit inside WebRootPath. The trailing separator
// makes StartsWith respect the boundary so a sibling like "wwwroot-secret" can't match "wwwroot".
var webRoot = context.RequestServices.GetRequiredService<IWebHostEnvironment>().WebRootPath;
var resolvedPhysical = Path.GetFullPath(physicalPath);
var resolvedWebRoot = Path.GetFullPath(webRoot);
if (!Path.EndsInDirectorySeparator(resolvedWebRoot))
{
resolvedWebRoot += Path.DirectorySeparatorChar;
}

if (!resolvedPhysical.StartsWith(resolvedWebRoot, StringComparison.OrdinalIgnoreCase))
{
Expand Down
Loading