Database connection strings control how an application connects to a database. They include information such as the location of the database, how
to authenticate with the database, and how the connection should be secured.
The insertion of user-supplied values into a connection string can allow external control of these database connections.
Why is this an issue?
Connection strings contain a series of parameters that are structured as key/value pairs, similar to key1=value1;key2=value2
.
If an attacker can control values that are inserted into the connection string, they may be able to insert additional parameters. These additional
parameters can override values that were supplied earlier in the connection string.
What is the potential impact?
An attacker can use specially-crafted values to change how the database connection is made. These values can add new parameters to the connection
string, or can override parameters that had already been specified.
Escalation of privilege
Some database servers allow authentication via an OS user account instead of a username and password. The database connection is authenticated as
the user running the application. When this authentication mode is used, any username or password in the connection string are ignored.
If an attacker can force the use of this authentication mode, the connection will be made as the user that the web application is running under.
This will often be the LocalSystem
or NetworkService
account on Windows. Such accounts are often given a high level of
privileges on the database server.
Credential theft
If an attacker can change the database server in the connection string, they can have the web application connect to a server that they control.
The web application will then authenticate with that server, allowing those credentials to be stolen.
Bypassing data validation
Many web applications implicitly trust data that’s stored in the database. The data is validated before it is stored, so no additional validation
is performed when that data is loaded.
If an attacker can change the database server in the connection string, they can have the web application connect to a database server that they
control. Invalid data in this database could be passed to other services or systems, or could be used to trigger other bugs and logic flaws in the web
application.
Network traffic sniffing
The connection string can control how the connection to the database server is secured. For example, it can control whether connections to
Microsoft SQL Server use transport layer security (TLS).
If an attacker can disable these network security measures and they have some way to monitor traffic between the web server and the database
server, they will be able to see all information that’s written to and read from the database.
How to fix it in .NET
Microsoft’s database connection libraries typically provide a connection string builder class. These classes provide methods and properties that
safely set parameter values.
Connection string builders will only protect you if you use these methods and properties to set parameter values. They will not help if you are
using them to modify a connection string where user-supplied values have already been added.
If no connection string builder is available, user-supplied values must either be validated to ensure that they’re not malicious, or must be
properly quoted so that they cannot interfere with other connection string parameters.
Code examples
Noncompliant code example
public string ConnectionString { get; set; } = "Server=10.0.0.101;Database=CustomerData";
public SqlConnection ConnectToDatabase(HttpRequest request)
{
string connectionString = string.Format("{0};User ID={1};Password={2}",
ConnectionString,
request.Form["username"],
request.Form["password"]);
SqlConnection connection = new SqlConnection();
connection.ConnectionString = connectionString; // Noncompliant
connection.Open();
return connection;
}
Compliant solution
public string ConnectionString { get; set; } = "Server=10.0.0.101;Database=CustomerData";
public SqlConnection ConnectToDatabase(HttpRequest request)
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(ConnectionString);
builder.UserID = request.Form["username"];
builder.Password = request.Form["password"];
SqlConnection connection = new SqlConnection();
connection.ConnectionString = builder.ConnectionString;
connection.Open();
return connection;
}
How does this work?
Connection string builders will ensure that values are correctly sanitized when adding them to the connection string.
Resources
Documentation
Conference presentations
Standards