Generadores de cadenas de conexión (ADO.NET)

Actualización: November 2007

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 de .NET Framework. Cada uno de los proveedores de datos incluye una clase generadora de cadenas de conexión con establecimiento inflexible de tipos que hereda de DbConnectionStringBuilder. En la tabla siguiente se indican los proveedores de datos de .NET Framework y sus clases generadoras de cadenas de conexión asociadas.

Proveedor

Clase ConnectionStringBuilder

System.Data.SqlClient

SqlConnectionStringBuilder

System.Data.OleDb

OleDbConnectionStringBuilder

System.Data.Odbc

OdbcConnectionStringBuilder

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 generadoras 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"

Generar 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 generador 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 para Windows. Para obtener más información sobre el trabajo con cadenas de conexión y archivos de configuración, vea Cadenas de conexión y archivos de configuración (ADO.NET).

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.

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
private 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 (null != settings)
    {
        // Retrieve the partial connection string.
        string 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 SqlConnectionStringBuilder(connectString);

        // Supply the additional values.
        builder.DataSource = dataSource;
        builder.UserID = userName;
        builder.Password = userPassword;
        Console.WriteLine("Modified: {0}", builder.ConnectionString);
    }
}

Vea también

Conceptos

Privacidad y seguridad de datos (ADO.NET)

Otros recursos

Cadenas de conexión (ADO.NET)