资源注入¶
ID: cs/resource-injection
Kind: path-problem
Security severity: 9.8
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-099
Query suites:
- csharp-code-scanning.qls
- csharp-security-extended.qls
- csharp-security-and-quality.qls
如果使用字符串连接构建资源描述符,并且连接的组件包含用户输入,则用户可能能够劫持加载的资源。
建议¶
如果必须在资源描述符中包含用户输入,则应对其进行转义,以避免恶意用户提供更改描述符含义的特殊字符。如果可能,请使用现有库对资源进行转义或构造。
对于 System.Data
子命名空间内的数据连接,提供了一个连接构建器类。例如,可以使用 System.Data.SqlClient.SqlConnectionStringBuilder
的实例安全地构造要传递给 System.Data.SqlClient.SqlConnection
的连接字符串。
示例¶
在以下示例中,代码接受用户提供的用户名,并使用该用户名为 SQL 数据库创建连接字符串。
第一个示例将未经验证和未编码的用户输入直接连接到连接字符串中。恶意用户可以提供特殊字符来更改连接字符串的含义,并连接到完全不同的服务器。
第二个示例使用 SqlConnectionStringBuilder
构造连接字符串,从而防止恶意用户修改连接字符串的含义。
using System.Data.SqlClient;
using System.Web;
public class ResourceInjectionHandler : IHttpHandler
{
public void ProcessRequest(HttpContext ctx)
{
string userName = ctx.Request.QueryString["userName"];
// BAD: Direct use of user input in a connection string passed to SqlConnection
string connectionString = "server=(local);user id=" + userName + ";password= pass;";
SqlConnection sqlConnectionBad = new SqlConnection(connectionString);
// GOOD: Use SqlConnectionStringBuilder to safely include user input in a connection string
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder["Data Source"] = "(local)";
builder["integrated Security"] = true;
builder["user id"] = userName;
SqlConnection sqlConnectionGood = new SqlConnection(builder.ConnectionString);
}
}