OdbcCommand. Parametrization with table name

淺唱寂寞╮ 提交于 2019-12-13 15:16:07

问题


I have a problem doing a parametrized sql query to a OdbcConnection to a odbc driver in C#. The column name and table name will be configurable from a web gui so I want it protected from injections

using (OdbcCommand command = connection.CreateCommand())
{
    command.CommandText = "SELECT ? FROM ?";
    command.CommandTimeout = SynchTimeout;
    command.CommandType = CommandType.Text;

    command.Parameters.Add(new OdbcParameter(string.Empty, "User"));
    command.Parameters.Add(new OdbcParameter(string.Empty, "TableName"));

    OdbcDataReader reader = command.ExecuteReader();
    while (reader.Read())
    {
      // TODO: Do something clever..
    }
}

Using odcparameters for the columname "User" seems ok. but if I add the table name as a paramter with the placeholder '?' I get the following error: ERROR [HY000] [Microsoft][ODBC Excel Driver] Parameter 'Pa_RaM002' specified where a table name is required.

Does anyone know how to pass a table name safe in this situation if it cannot be a OdbcParameter?


回答1:


I don't think it's possible to parameterize table names and column names in SQL. So, in some way or another you'll still resort to string concatenation to build dynamic SQL statements.

What is possible though is for you to do some checks prior to executing the statement. I see two types of checks you could perform:

1. Whitelist check (the better solution)

If possible, have a list of tables and columns that you allow to be used in this manner. When a user specifies the table and column, make sure you only allow elements in the list.

2. Dynamic check (the risky solution)

Apply this approach only if the names of the tables/columns are not known beforehand (ex: created dynamically) and it is impossible to build a whitelist. Otherwise, go for the whitelist approach.

You could check that the configured table and column exist in the database.

For example, if you are using SQL Server you could do this by querying the Information Schema views, like so:

select top 1 COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = @tableNameParameter
and COLUMN_NAME = @columnNameParameter
and <additional criteria*>

To avoid running the check too often, you could perform these checks as a validation in the web page that allows configuring the table and column names.

*WARNING: if you only validate that the table and column exist, that would give the users the ability to discover all tables in your database. To avoid this, you could add an additional criteria in your SQL, to make sure you only select tables that were meant to be used in this way. For example, all dynamic tables could have a certain prefix, so you could do [...] and TABLE_NAME like 'prefix%'


Regardless of which solution you choose, be aware that it is critical from a security point of view. You should be very careful which components of the system are allowed to write the custom table/column values and apply the validation in each of these points.



来源:https://stackoverflow.com/questions/14124261/odbccommand-parametrization-with-table-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!