Generadores de cadenas de conexión

En versiones anteriores de ADO.NET, no se producía la comprobación de las cadenas de conexión con valores de cadena concatenados en tiempo de compilación, por lo que, en tiempo de ejecución, una palabra clave incorrecta generaba una excepción ArgumentException. Cada uno de los proveedores de datos de .NET Framework admitía una sintaxis diferente para las palabras claves de cadenas de conexión, lo que dificultaba la construcción de cadenas de conexión válidas de forma manual. Para solucionar este problema, ADO.NET 2.0 incorporó nuevos generadores de cadenas de conexión para cada proveedor de datos .NET Framework. Cada uno de los proveedores de datos incluye una clase creadora de cadenas de conexión fuertemente tipadas que hereda de DbConnectionStringBuilder. En la tabla siguiente se indican los proveedores de datos de .NET Framework y sus clases compiladoras de cadenas de conexión asociadas.

Proveedor Clase ConnectionStringBuilder
System.Data.SqlClient System.Data.SqlClient.SqlConnectionStringBuilder
System.Data.OleDb System.Data.OleDb.OleDbConnectionStringBuilder
System.Data.Odbc System.Data.Odbc.OdbcConnectionStringBuilder
System.Data.OracleClient System.Data.OracleClient.OracleConnectionStringBuilder

Ataques de inyección de cadenas de conexión

Cuando se utiliza la concatenación dinámica de cadenas para generar cadenas de conexión basadas en datos introducidos por el usuario, se pueden producir ataques de inyección de cadenas de conexión. Si no se valida la cadena y no se crean secuencias de escape para los caracteres o el texto malintencionado, los atacantes pueden tener acceso a datos confidenciales y a otros recursos del servidor. Por ejemplo, un atacante puede realizar un ataque si proporciona un punto y coma y anexa un valor adicional. La cadena de conexión se analiza utilizando un algoritmo del tipo "el último gana", y la entrada hostil se sustituye por un valor legítimo.

Las clases compiladoras de cadenas de conexión se han diseñado para eliminar la adivinación y desarrollar protección ante errores de sintaxis y vulnerabilidades de seguridad. Proporcionan métodos y propiedades que corresponden a los pares clave-valor conocidos permitidos por cada proveedor de datos. Cada clase mantiene una colección fija de sinónimos y puede convertir un sinónimo al correspondiente nombre de clave conocido. En los pares clave-valor se realizan comprobaciones y los pares no válidos inician una excepción. Además, los valores inyectados se controlan de forma segura.

En el ejemplo siguiente se muestra cómo SqlConnectionStringBuilder controla un valor adicional insertado en la configuración Initial Catalog.

Dim builder As New System.Data.SqlClient.SqlConnectionStringBuilder  
builder("Data Source") = "(local)"  
builder("Integrated Security") = True  
builder("Initial Catalog") = "AdventureWorks;NewValue=Bad"  
Console.WriteLine(builder.ConnectionString)  
System.Data.SqlClient.SqlConnectionStringBuilder builder =  
  new System.Data.SqlClient.SqlConnectionStringBuilder();  
builder["Data Source"] = "(local)";  
builder["integrated Security"] = true;  
builder["Initial Catalog"] = "AdventureWorks;NewValue=Bad";  
Console.WriteLine(builder.ConnectionString);  

El resultado muestra que SqlConnectionStringBuilder controla esta situación correctamente, ya que establece el escape del valor adicional entre comillas dobles en lugar de anexarlo a la cadena de conexión como un nuevo par clave-valor.

data source=(local);Integrated Security=True;  
initial catalog="AdventureWorks;NewValue=Bad"  

Crear cadenas de conexión a partir de archivos de configuración

Si determinados elementos de una cadena de conexión se conocen de antemano, se pueden almacenar en un archivo de configuración y recuperar en tiempo de ejecución para construir una cadena de conexión completa. Por ejemplo, se puede conocer por adelantado el nombre de la base de datos, pero no el del servidor. También es posible que desee que un usuario indique un nombre y una contraseña en tiempo de ejecución sin que pueda inyectar otros valores en ella.

Uno de los constructores sobrecargados de un compilador de cadenas de conexión toma String como argumento, lo que permite proporcionar una cadena de conexión parcial que se puede completar después con los datos introducidos por el usuario. La cadena de conexión parcial se puede almacenar en un archivo de configuración y recuperarse en tiempo de ejecución.

Nota:

El espacio de nombres System.Configuration permite el acceso mediante programación a archivos de configuración que usan WebConfigurationManager en aplicaciones web y ConfigurationManager en aplicaciones Windows. Para obtener más información sobre cómo trabajar con cadenas de conexión y archivos de configuración, vea Cadenas de conexión y archivos de configuración.

Ejemplo

En este ejemplo se muestra la recuperación de una cadena de conexión incluida en un archivo de configuración y cómo se completa mediante el establecimiento de las propiedades DataSource, UserID y Password de SqlConnectionStringBuilder. El archivo de configuración se define de la siguiente forma.

<connectionStrings>  
  <clear/>  
  <add name="partialConnectString"
    connectionString="Initial Catalog=Northwind;"  
    providerName="System.Data.SqlClient" />  
</connectionStrings>  

Nota:

Para ejecutar el código, debe establecer una referencia al archivo System.Configuration.dll del proyecto.

static void BuildConnectionString(string dataSource,
    string userName, string userPassword)
{
    // Retrieve the partial connection string named databaseConnection
    // from the application's app.config or web.config file.
    ConnectionStringSettings settings =
        ConfigurationManager.ConnectionStrings["partialConnectString"];

    if (settings != null)
    {
        // Retrieve the partial connection string.
        var connectString = settings.ConnectionString;
        Console.WriteLine("Original: {0}", connectString);

        // Create a new SqlConnectionStringBuilder based on the
        // partial connection string retrieved from the config file.
        SqlConnectionStringBuilder builder =
            new(connectString)
            {
                // Supply the additional values.
                DataSource = dataSource,
                UserID = userName,
                Password = userPassword
            };
        Console.WriteLine("Modified: {0}", builder.ConnectionString);
    }
}
Private Sub BuildConnectionString(ByVal dataSource As String, _
    ByVal userName As String, ByVal userPassword As String)

    ' Retrieve the partial connection string named databaseConnection
    ' from the application's app.config or web.config file.
    Dim settings As ConnectionStringSettings = _
       ConfigurationManager.ConnectionStrings("partialConnectString")

    If Not settings Is Nothing Then
        ' Retrieve the partial connection string.
        Dim connectString As String = settings.ConnectionString
        Console.WriteLine("Original: {0}", connectString)

        ' Create a new SqlConnectionStringBuilder based on the
        ' partial connection string retrieved from the config file.
        Dim builder As New SqlConnectionStringBuilder(connectString)

        ' Supply the additional values.
        builder.DataSource = dataSource
        builder.UserID = userName
        builder.Password = userPassword

        Console.WriteLine("Modified: {0}", builder.ConnectionString)
    End If
End Sub

Vea también