How do I protect this function from SQL injection?

前端 未结 11 1134
独厮守ぢ
独厮守ぢ 2020-12-16 18:47
public static bool TruncateTable(string dbAlias, string tableName)
{
    string sqlStatement = string.Format(\"TRUNCATE TABLE {0}\", tableName);
    return ExecuteNo         


        
相关标签:
11条回答
  • 2020-12-16 19:10

    Use parameterized queries.

    0 讨论(0)
  • 2020-12-16 19:10

    In this concrete example you need protection from SQL injection only if table name comes from external source.

    Why would you ever allow this to happen? If you are allowing some external entity (end user, other system, what?) to name a table to be dropped, why won't you just give them admin rights.

    If you are creating and removing tables to provide some functionality for end user, don't let them provide names for database objects directly. Apart from SQL injection, you'll have problems with name clashes etc. Instead generate real table names yourself (e.g DYNTABLE_00001, DYNTABLE_00002, ...) and keep a table that connects them to the names provided by user.


    Some notes on generating dynamic SQL for DDL operations:

    • In most RDBMS-s you'll have to use dynamic SQL and insert table names as text. Be extra careful.

    • Use quoted identifiers ([] in MS SQL Server, "" in all ANSI compliant RDBMS). This will make avoiding errors caused by invalid names easier.

    • Do it in stored procedures and check if all referenced objects are valid.

    • Do not do anything irreversible. E.g. don't drop tables automatically. You can flag them to be dropped and e-mail your DBA. She'll drop them after the backup.

    • Avoid it if you can. If you can't, do what you can to minimize rights to other (non-dynamic) tables that normal users will have.

    0 讨论(0)
  • 2020-12-16 19:15

    You could use SQLParameter to pass in tableName value. As far as I know and tested, SQLParameter takes care of all parameter checking and thus disables possibility of injection.

    0 讨论(0)
  • 2020-12-16 19:19
    CREATE OR REPLACE PROCEDURE truncate(ptbl_name IN VARCHAR2) IS
      stmt VARCHAR2(100);
    BEGIN
      stmt := 'TRUNCATE TABLE '||DBMS_ASSERT.SIMPLE_SQL_NAME(ptbl_name);
      dbms_output.put_line('<'||stmt||'>');
      EXECUTE IMMEDIATE stmt;
    END;
    
    0 讨论(0)
  • 2020-12-16 19:21

    If you're allowing user-defined input to creep into this function via the tablename variable, I don't think SQL Injection is your only problem.

    A better option would be to run this command via its own secure connection and give it no SELECT rights at all. All TRUNCATE needs to run is the ALTER TABLE permission. If you're on SQL 2005 upwards, you could also try using a stored procedure with EXECUTE AS inside.

    0 讨论(0)
提交回复
热议问题