"Untrusted initialization" 缺陷 - 创建 SQL 连接时
"Untrusted initialization" flaw - while creating SQL Connection
我做了以下...
private static IDbConnectionProvider CreateSqlConnectionProvider(DbConfig dbConfig)
{
return new QcDbConnectionProvider(() =>
{
SqlConnectionStringBuilder csBuilder = new SqlConnectionStringBuilder();
if (!string.IsNullOrEmpty(dbConfig.DataSource))
csBuilder.DataSource = dbConfig.DataSource;
if (!string.IsNullOrEmpty(dbConfig.Database))
csBuilder.InitialCatalog = dbConfig.Database;
.
.
.
.
return new SqlConnection(csBuilder.ConnectionString);
});
}
客户端正在使用 VERACODE 工具进行代码分析,VERACODE 在
处检测到缺陷 "Untrusted initialization"
return new SqlConnection(csBuilder.ConnectionString);
此外,dbConfig
正在初始化,如下所示...
DbConfig configDbConfig = new DbConfig
{
Database = codeFile.ConfigurationDb,
DataSource = codeFile.DataSource,
IntegratedSecurity = sqlCredentials.UseWindowsAuthentication ? 1 : 0,
UserId = sqlCredentials.UseWindowsAuthentication ? null : sqlCredentials.SqlUserName,
ClearTextPassword = sqlCredentials.UseWindowsAuthentication ? null : sqlCredentials.SqlUserPassword
};
我还需要做些什么来修复这个缺陷?同样根据 this link,我正在使用 SqlConnectionStringBuilder
创建连接字符串,它可以安全地创建连接字符串。
提前致谢...
不受信任的初始化问题的描述是:
Applications should be reluctant to trust variables that have been initialized outside of its trust boundary. Untrusted initialization refers to instances in which an application allows external control of system settings or variables, which can disrupt service or cause an application to behave in unexpected ways. For example, if an application uses values from the environment, assuming the data cannot be tampered with, it may use that data in a dangerous way.
在您的情况下,您正在从文件中读取 dbConfig
的数据:
if (TryReadCodeFile(configurationProfileFile...)) {
DbConfig configDbConfig = new DbConfig...
}
请注意,您收到的警告还应带有行号(以限制错误 代码)。您发布的代码中的几乎所有内容都会产生此问题(我看不出 sqlCredentials
的来源,但如果它们是明文形式,它甚至可能是安全问题的另一个来源 - 或者可以在您的文件中访问要解密的代码申请)。
来自引用的段落:“...应用程序允许外部控制系统设置或变量,其中可以中断服务..."。这是这个问题的核心:如果您的应用程序使用外部数据而没有 direct 对其进行控制,则可以通过修改该数据来更改其行为。这些外部数据是什么?列表是全部但并非详尽无遗:
- 环境变量(例如解析另一个文件或程序的路径),因为用户可能会更改它们。原始文件未被触及,但您阅读了其他内容。
- 路径(加载代码或数据),因为用户可能会重定向到其他内容(同样,原始文件未被触及,但您阅读了其他内容)。
- 支持文件,因为用户可以更改它们(例如,在您的情况下,指向另一个服务器 and/or 目录)。
- 配置文件,因为用户可以更改它们(同上)。
- 数据库,因为其他用户也可以访问它们并且它们可能会被更改(但它们可能会受到保护)。
恶意用户如何使用它?想象一下,每个用户都连接到不同的目录(根据他们在组织中的规则)。这不能更改,它是在安装期间配置的。如果他们可以访问您的配置文件,他们可能会将目录更改为其他内容。他们还可以将数据库主机名更改为 隧道 ,他们可以在其中嗅探数据(如果他们可以物理访问其他人的机器)。
另请注意,他们还说 “...假设数据无法被篡改,它可能会以危险的方式使用该数据”。这意味着,例如,如果您的应用程序在 Web 服务器上运行并且物理访问是安全的,那么您可以认为数据 安全 .
请注意,您的应用程序在整个系统中的安全性较低。请注意,要使应用程序安全(我知道,这个术语很模糊)加密密码是不够的。
如果支持文件可能被操纵,那么您能做的最好的事情就是使用 public/private 密钥加密来加密它们。一个不太理想的解决方案是计算一个 CRC 或散列(例如),你将在使用它们之前应用到配置文件(它们能够更改它们,但你的应用程序会检测到这个问题)。
总结一下:你可以忽略这个问题,但你必须向你的客户证明你依赖的数据不能被篡改。如果至少满足以下条件之一,您可以合理地证明:
1) 除了您的应用程序之外,其他任何人都无法访问支持文件所在的系统。您的应用程序安全性不能高于系统安全性。
2) 您的支持文件在每台机器上都是有效的(以避免在不同机器之间复制),并且它们以任何人都无法(有意或无意)更改的方式进行加密。
3) 您的支持文件在每台机器上都是有效的,并且它们是 散列的,您的应用程序可以检测到外部更改。
4) 无论用户对您的配置文件做什么,应用程序本身都不能因此改变其行为(例如,它是一个单一安装,其中只有一个数据库和一个目录)。
连接字符串最重要的是它们的存储方式。如果它们以明文形式存储,则会带来安全风险。因此,建议以加密格式存储它们并在应用程序中解密并使用它。
我做了以下...
private static IDbConnectionProvider CreateSqlConnectionProvider(DbConfig dbConfig)
{
return new QcDbConnectionProvider(() =>
{
SqlConnectionStringBuilder csBuilder = new SqlConnectionStringBuilder();
if (!string.IsNullOrEmpty(dbConfig.DataSource))
csBuilder.DataSource = dbConfig.DataSource;
if (!string.IsNullOrEmpty(dbConfig.Database))
csBuilder.InitialCatalog = dbConfig.Database;
.
.
.
.
return new SqlConnection(csBuilder.ConnectionString);
});
}
客户端正在使用 VERACODE 工具进行代码分析,VERACODE 在
处检测到缺陷 "Untrusted initialization"return new SqlConnection(csBuilder.ConnectionString);
此外,dbConfig
正在初始化,如下所示...
DbConfig configDbConfig = new DbConfig
{
Database = codeFile.ConfigurationDb,
DataSource = codeFile.DataSource,
IntegratedSecurity = sqlCredentials.UseWindowsAuthentication ? 1 : 0,
UserId = sqlCredentials.UseWindowsAuthentication ? null : sqlCredentials.SqlUserName,
ClearTextPassword = sqlCredentials.UseWindowsAuthentication ? null : sqlCredentials.SqlUserPassword
};
我还需要做些什么来修复这个缺陷?同样根据 this link,我正在使用 SqlConnectionStringBuilder
创建连接字符串,它可以安全地创建连接字符串。
提前致谢...
不受信任的初始化问题的描述是:
Applications should be reluctant to trust variables that have been initialized outside of its trust boundary. Untrusted initialization refers to instances in which an application allows external control of system settings or variables, which can disrupt service or cause an application to behave in unexpected ways. For example, if an application uses values from the environment, assuming the data cannot be tampered with, it may use that data in a dangerous way.
在您的情况下,您正在从文件中读取 dbConfig
的数据:
if (TryReadCodeFile(configurationProfileFile...)) {
DbConfig configDbConfig = new DbConfig...
}
请注意,您收到的警告还应带有行号(以限制错误 代码)。您发布的代码中的几乎所有内容都会产生此问题(我看不出 sqlCredentials
的来源,但如果它们是明文形式,它甚至可能是安全问题的另一个来源 - 或者可以在您的文件中访问要解密的代码申请)。
来自引用的段落:“...应用程序允许外部控制系统设置或变量,其中可以中断服务..."。这是这个问题的核心:如果您的应用程序使用外部数据而没有 direct 对其进行控制,则可以通过修改该数据来更改其行为。这些外部数据是什么?列表是全部但并非详尽无遗:
- 环境变量(例如解析另一个文件或程序的路径),因为用户可能会更改它们。原始文件未被触及,但您阅读了其他内容。
- 路径(加载代码或数据),因为用户可能会重定向到其他内容(同样,原始文件未被触及,但您阅读了其他内容)。
- 支持文件,因为用户可以更改它们(例如,在您的情况下,指向另一个服务器 and/or 目录)。
- 配置文件,因为用户可以更改它们(同上)。
- 数据库,因为其他用户也可以访问它们并且它们可能会被更改(但它们可能会受到保护)。
恶意用户如何使用它?想象一下,每个用户都连接到不同的目录(根据他们在组织中的规则)。这不能更改,它是在安装期间配置的。如果他们可以访问您的配置文件,他们可能会将目录更改为其他内容。他们还可以将数据库主机名更改为 隧道 ,他们可以在其中嗅探数据(如果他们可以物理访问其他人的机器)。
另请注意,他们还说 “...假设数据无法被篡改,它可能会以危险的方式使用该数据”。这意味着,例如,如果您的应用程序在 Web 服务器上运行并且物理访问是安全的,那么您可以认为数据 安全 .
请注意,您的应用程序在整个系统中的安全性较低。请注意,要使应用程序安全(我知道,这个术语很模糊)加密密码是不够的。
如果支持文件可能被操纵,那么您能做的最好的事情就是使用 public/private 密钥加密来加密它们。一个不太理想的解决方案是计算一个 CRC 或散列(例如),你将在使用它们之前应用到配置文件(它们能够更改它们,但你的应用程序会检测到这个问题)。
总结一下:你可以忽略这个问题,但你必须向你的客户证明你依赖的数据不能被篡改。如果至少满足以下条件之一,您可以合理地证明:
1) 除了您的应用程序之外,其他任何人都无法访问支持文件所在的系统。您的应用程序安全性不能高于系统安全性。
2) 您的支持文件在每台机器上都是有效的(以避免在不同机器之间复制),并且它们以任何人都无法(有意或无意)更改的方式进行加密。 3) 您的支持文件在每台机器上都是有效的,并且它们是 散列的,您的应用程序可以检测到外部更改。
4) 无论用户对您的配置文件做什么,应用程序本身都不能因此改变其行为(例如,它是一个单一安装,其中只有一个数据库和一个目录)。
连接字符串最重要的是它们的存储方式。如果它们以明文形式存储,则会带来安全风险。因此,建议以加密格式存储它们并在应用程序中解密并使用它。