Skip to content

Commit fa7df40

Browse files
[SNOW-1156046] fix toctou vulnerability in EasyLogginConfig
1 parent 47235fb commit fa7df40

File tree

2 files changed

+42
-30
lines changed

2 files changed

+42
-30
lines changed

Snowflake.Data/Configuration/EasyLoggingConfigFinder.cs

+6-26
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,13 @@ internal class EasyLoggingConfigFinder
1919
internal const string ClientConfigEnvironmentName = "SF_CLIENT_CONFIG_FILE";
2020

2121
private readonly FileOperations _fileOperations;
22-
private readonly UnixOperations _unixOperations;
2322
private readonly EnvironmentOperations _environmentOperations;
2423

25-
public static readonly EasyLoggingConfigFinder Instance = new EasyLoggingConfigFinder(FileOperations.Instance, UnixOperations.Instance, EnvironmentOperations.Instance);
24+
public static readonly EasyLoggingConfigFinder Instance = new EasyLoggingConfigFinder(FileOperations.Instance, EnvironmentOperations.Instance);
2625

27-
internal EasyLoggingConfigFinder(FileOperations fileOperations, UnixOperations unixFileOperations, EnvironmentOperations environmentOperations)
26+
internal EasyLoggingConfigFinder(FileOperations fileOperations, EnvironmentOperations environmentOperations)
2827
{
2928
_fileOperations = fileOperations;
30-
_unixOperations = unixFileOperations;
3129
_environmentOperations = environmentOperations;
3230
}
3331

@@ -38,16 +36,12 @@ internal EasyLoggingConfigFinder()
3836
public virtual string FindConfigFilePath(string configFilePathFromConnectionString)
3937
{
4038
var configFilePath = GetFilePathFromInputParameter(configFilePathFromConnectionString, "connection string")
41-
?? GetFilePathEnvironmentVariable()
42-
?? GetFilePathFromDriverLocation()
43-
?? GetFilePathFromHomeDirectory();
44-
if (configFilePath != null)
45-
{
46-
CheckIfValidPermissions(configFilePath);
47-
}
39+
?? GetFilePathEnvironmentVariable()
40+
?? GetFilePathFromDriverLocation()
41+
?? GetFilePathFromHomeDirectory();
4842
return configFilePath;
4943
}
50-
44+
5145
private string GetFilePathEnvironmentVariable()
5246
{
5347
var filePath = _environmentOperations.GetEnvironmentVariable(ClientConfigEnvironmentName);
@@ -100,19 +94,5 @@ private string OnlyIfFileExists(string filePath, string directoryDescription)
10094
}
10195
return null;
10296
}
103-
104-
private void CheckIfValidPermissions(string filePath)
105-
{
106-
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
107-
return;
108-
109-
// Check if others have permissions to modify the file and fail if so
110-
if (_unixOperations.CheckFileHasAnyOfPermissions(filePath, FileAccessPermissions.GroupWrite | FileAccessPermissions.OtherWrite))
111-
{
112-
var errorMessage = $"Error due to other users having permission to modify the config file: {filePath}";
113-
s_logger.Error(errorMessage);
114-
throw new Exception(errorMessage);
115-
}
116-
}
11797
}
11898
}

Snowflake.Data/Configuration/EasyLoggingConfigParser.cs

+36-4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@
77
using System.IO;
88
using System.Linq;
99
using System.Reflection;
10+
using System.Runtime.InteropServices;
11+
using Microsoft.IdentityModel.Tokens;
12+
using Mono.Unix;
1013
using Newtonsoft.Json;
1114
using Newtonsoft.Json.Linq;
15+
using Snowflake.Data.Core.Tools;
1216
using Snowflake.Data.Log;
1317

1418
namespace Snowflake.Data.Configuration
@@ -17,23 +21,36 @@ internal class EasyLoggingConfigParser
1721
{
1822
private static readonly SFLogger s_logger = SFLoggerFactory.GetLogger<EasyLoggingConfigParser>();
1923

24+
private readonly UnixOperations _unixOperations = UnixOperations.Instance;
25+
2026
public static readonly EasyLoggingConfigParser Instance = new EasyLoggingConfigParser();
2127

2228
public virtual ClientConfig Parse(string filePath)
2329
{
2430
var configFile = TryToReadFile(filePath);
25-
return configFile == null ? null : TryToParseFile(configFile);
31+
return configFile.IsNullOrEmpty() ? null : TryToParseFile(configFile);
2632
}
2733

2834
private string TryToReadFile(string filePath)
2935
{
3036
if (string.IsNullOrEmpty(filePath))
3137
{
32-
return null;
38+
return String.Empty;
3339
}
40+
3441
try
3542
{
36-
return File.ReadAllText(filePath);
43+
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
44+
{
45+
using (StreamReader reader = new StreamReader(fileStream))
46+
{
47+
CheckIfValidPermissions(filePath);
48+
49+
string fileContent = reader.ReadToEnd();
50+
51+
return fileContent;
52+
}
53+
}
3754
}
3855
catch (Exception e)
3956
{
@@ -45,7 +62,8 @@ private string TryToReadFile(string filePath)
4562

4663
private ClientConfig TryToParseFile(string fileContent)
4764
{
48-
try {
65+
try
66+
{
4967
var config = JsonConvert.DeserializeObject<ClientConfig>(fileContent);
5068
Validate(config);
5169
CheckForUnknownFields(fileContent);
@@ -80,5 +98,19 @@ private void CheckForUnknownFields(string fileContent)
8098
.ToList()
8199
.ForEach(unknownKey => s_logger.Warn($"Unknown field from config: {unknownKey.Name}"));
82100
}
101+
102+
private void CheckIfValidPermissions(string filePath)
103+
{
104+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
105+
return;
106+
107+
// Check if others have permissions to modify the file and fail if so
108+
if (_unixOperations.CheckFileHasAnyOfPermissions(filePath, FileAccessPermissions.GroupWrite | FileAccessPermissions.OtherWrite))
109+
{
110+
var errorMessage = $"Error due to other users having permission to modify the config file: {filePath}";
111+
s_logger.Error(errorMessage);
112+
throw new Exception(errorMessage);
113+
}
114+
}
83115
}
84116
}

0 commit comments

Comments
 (0)