mirror of
https://github.com/Radarr/Radarr
synced 2026-01-24 00:13:43 +01:00
fix(security): patch SQL injection, path traversal, command injection
This commit is contained in:
parent
2a523af1db
commit
b8c130c73d
5 changed files with 38 additions and 11 deletions
|
|
@ -69,6 +69,8 @@ private void ExtractZip(string compressedFile, string destination)
|
|||
throw new IOException(string.Format("File {0} failed archive validation.", compressedFile));
|
||||
}
|
||||
|
||||
var destinationFullPath = Path.GetFullPath(destination);
|
||||
|
||||
foreach (ZipEntry zipEntry in zipFile)
|
||||
{
|
||||
if (!zipEntry.IsFile)
|
||||
|
|
@ -85,7 +87,16 @@ private void ExtractZip(string compressedFile, string destination)
|
|||
var zipStream = zipFile.GetInputStream(zipEntry);
|
||||
|
||||
// Manipulate the output filename here as desired.
|
||||
var fullZipToPath = Path.Combine(destination, entryFileName);
|
||||
var fullZipToPath = Path.GetFullPath(Path.Combine(destination, entryFileName));
|
||||
|
||||
// Prevent path traversal attacks - ensure extracted path is within destination
|
||||
if (!fullZipToPath.StartsWith(destinationFullPath + Path.DirectorySeparatorChar) &&
|
||||
!fullZipToPath.Equals(destinationFullPath, StringComparison.Ordinal))
|
||||
{
|
||||
_logger.Warn("Skipping zip entry with path traversal attempt: {0}", entryFileName);
|
||||
continue;
|
||||
}
|
||||
|
||||
var directoryName = Path.GetDirectoryName(fullZipToPath);
|
||||
if (directoryName.Length > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -356,17 +356,17 @@ private List<Process> GetProcessesByName(string name)
|
|||
{
|
||||
if (OsInfo.IsWindows && path.EndsWith(".bat", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return ("cmd.exe", $"/c {path} {args}");
|
||||
return ("cmd.exe", $"/c \"{path}\" {args}");
|
||||
}
|
||||
|
||||
if (OsInfo.IsWindows && path.EndsWith(".ps1", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return ("powershell.exe", $"-ExecutionPolicy Bypass -NoProfile -File {path} {args}");
|
||||
return ("powershell.exe", $"-ExecutionPolicy Bypass -NoProfile -File \"{path}\" {args}");
|
||||
}
|
||||
|
||||
if (OsInfo.IsWindows && path.EndsWith(".py", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
return ("python.exe", $"{path} {args}");
|
||||
return ("python.exe", $"\"{path}\" {args}");
|
||||
}
|
||||
|
||||
return (path, args);
|
||||
|
|
|
|||
|
|
@ -31,19 +31,17 @@ public void Clean()
|
|||
.SelectMany(v => GetUsedTags(v, mapper))
|
||||
.Concat(GetAutoTaggingTagSpecificationTags(mapper))
|
||||
.Distinct()
|
||||
.ToList();
|
||||
.ToArray();
|
||||
|
||||
if (usedTags.Any())
|
||||
{
|
||||
var usedTagsList = usedTags.Select(d => d.ToString()).Join(",");
|
||||
|
||||
if (_database.DatabaseType == DatabaseType.PostgreSQL)
|
||||
{
|
||||
mapper.Execute($"DELETE FROM \"Tags\" WHERE NOT \"Id\" = ANY (\'{{{usedTagsList}}}\'::int[])");
|
||||
mapper.Execute("DELETE FROM \"Tags\" WHERE NOT \"Id\" = ANY (@UsedTags)", new { UsedTags = usedTags });
|
||||
}
|
||||
else
|
||||
{
|
||||
mapper.Execute($"DELETE FROM \"Tags\" WHERE NOT \"Id\" IN ({usedTagsList})");
|
||||
mapper.Execute("DELETE FROM \"Tags\" WHERE \"Id\" NOT IN @UsedTags", new { UsedTags = usedTags });
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -27,7 +27,15 @@ public override string Map(string resourceUrl)
|
|||
var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar);
|
||||
path = path.Trim(Path.DirectorySeparatorChar);
|
||||
|
||||
var resourcePath = Path.Combine(_appFolderInfo.GetAppDataPath(), path);
|
||||
var basePath = Path.GetFullPath(_appFolderInfo.GetAppDataPath());
|
||||
var resourcePath = Path.GetFullPath(Path.Combine(basePath, path));
|
||||
|
||||
// Prevent path traversal attacks - ensure path stays within AppData folder
|
||||
if (!resourcePath.StartsWith(basePath + Path.DirectorySeparatorChar) &&
|
||||
!resourcePath.Equals(basePath, StringComparison.Ordinal))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!_diskProvider.FileExists(resourcePath) || _diskProvider.GetFileSize(resourcePath) == 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,7 +23,17 @@ public override string Map(string resourceUrl)
|
|||
var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar);
|
||||
path = path.Trim(Path.DirectorySeparatorChar);
|
||||
|
||||
return Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, path);
|
||||
var basePath = Path.GetFullPath(Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder));
|
||||
var fullPath = Path.GetFullPath(Path.Combine(basePath, path));
|
||||
|
||||
// Prevent path traversal attacks - ensure path stays within UI folder
|
||||
if (!fullPath.StartsWith(basePath + Path.DirectorySeparatorChar) &&
|
||||
!fullPath.Equals(basePath, StringComparison.Ordinal))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
public override bool CanHandle(string resourceUrl)
|
||||
|
|
|
|||
Loading…
Reference in a new issue