How to parameterise table name in ODBC query

I have an ODBC connection to a database and I would like the user to be able to view data within any table. As this is an ASP.net application I cannot trust that the table name sent doesn’t also contain nasties. I have tried using a parameterised query but I always get an error saying that I “Must declare the table variable” – this appears to be an issue because it is the table name

 string sql = "SELECT TOP 10 * FROM ? ";
 OdbcCommand command = new OdbcCommand(sql, dbConnection);
 command.Parameters.Add(new OdbcParameter("@table", tableName));
 OdbcDataAdapter adapter = new OdbcDataAdapter();
 adapter.SelectCommand = command;
 adapter.Fill(tableData);

What is the best method to achieve this in a secure way?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Use a stored procedure, it’s the safest way.

Some hints:

  1. You probably may also use the System.Data.SqlClient namespace objects
  2. Enclose your connection, command and adapter objects initializations in using statements

Here’s a simple example:

string sqlStoredProcedure = "SelectFromTable";
using (OdbcConnection dbConnection = new OdbcConnection(dbConnectionString))
{
    dbConnection.Open();
    using (OdbcCommand command = new OdbcCommand(sqlStoredProcedure, dbConnection))
    {
        command.CommandType = System.Data.CommandType.StoredProcedure;
        command.Parameters.Add(new OdbcParameter("@table", tableName));
        using (OdbcDataAdapter adapter = new OdbcDataAdapter(command))
        {
            adapter.SelectCommand = command;
            adapter.Fill(tableData);
        }
    }
}

Another way to go would be to retrieve all table names and validate the tableName string variable as an entry in the list, maybe using:

DataTable tables = dbConnection.GetSchema(OdbcMetaDataCollectionNames.Tables);

Here’s a simple implementation based on your scenario:

string sql = "SELECT TOP 10 * FROM {0}";
using (OdbcConnection dbConnection = new OdbcConnection(dbConnectionString))
{
    dbConnection.Open();

    DataTable tables = dbConnection.GetSchema(OdbcMetaDataCollectionNames.Tables);
    var matches = tables.Select(String.Format("TABLE_NAME = '{0}'", tableName));

    //check if table exists
    if (matches.Count() > 0)
    {
        using (OdbcCommand command = new OdbcCommand(String.Format(sql, tableName), dbConnection))
        {
            using (OdbcDataAdapter adapter = new OdbcDataAdapter(command))
            {
                adapter.SelectCommand = command;
                adapter.Fill(tableData);
            }
        }
    }
    else
    {
        //handle invalid value
    }
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x