case 4715 - download file names checked
report/download and export/download (any download key), the log-file routes and backup download built a path from the file name in the URL with Path.Combine and no check, so on Windows a name with a folder part or an absolute path could reach files outside the folder (security review F21). New helper FileUtil.FullPathInFolderOrNull accepts only a bare file name that resolves directly inside the folder; TemporaryFileExists and BackupFileExists use it (the download routes already call them first), and so do both log routes. A refused name gets the same 404 as a missing file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -69,9 +69,10 @@ namespace AyaNova.Api.Controllers
|
||||
//stream the file contents into a json object and return
|
||||
|
||||
//build the full path from the log file name and defined path
|
||||
var logFilePath = System.IO.Path.Combine(ServerBootConfig.AYANOVA_LOG_PATH, logname);
|
||||
//case 4715: only a bare file name inside the log folder
|
||||
var logFilePath = FileUtil.FullPathInFolderOrNull(ServerBootConfig.AYANOVA_LOG_PATH, logname);
|
||||
//does file exist?
|
||||
if (!System.IO.File.Exists(logFilePath))
|
||||
if (logFilePath == null || !System.IO.File.Exists(logFilePath))
|
||||
{
|
||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
||||
}
|
||||
@@ -149,8 +150,9 @@ namespace AyaNova.Api.Controllers
|
||||
if (!Authorized.HasReadFullRole(user.Roles, AyaType.LogFile))
|
||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
||||
|
||||
var logFilePath = System.IO.Path.Combine(ServerBootConfig.AYANOVA_LOG_PATH, logname);
|
||||
if (!System.IO.File.Exists(logFilePath))
|
||||
//case 4715: only a bare file name inside the log folder
|
||||
var logFilePath = FileUtil.FullPathInFolderOrNull(ServerBootConfig.AYANOVA_LOG_PATH, logname);
|
||||
if (logFilePath == null || !System.IO.File.Exists(logFilePath))
|
||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
||||
|
||||
//Note: this works with new Nlog file locking for write so it must be opening it as read and shareable
|
||||
|
||||
Reference in New Issue
Block a user