Shivam Mishra
Shivam Mishra

Reputation: 317

SQL injection vulnerability veracode c#

Veracode report is showing a SQL injection flaw for the below query.

private const string DropDatabaseTemplate = @"DROP DATABASE [{0}]";
ExecuteNonQuery(connection, string.Format(DropDatabaseTemplate, databaseName));

private static int ExecuteNonQuery(SqlConnection connection, string commandText)
        {
            using (var command = new SqlCommand(commandText, connection))
            {
                return command.ExecuteNonQuery();
            }
        }

they suggested using parameterized prepared statements. What would be my approach to remove this security vulnerability

Thanks in advance.

Ans : You can simply avoid security vulnerability with this

 private static void ExecuteNonQuery(SqlConnection connection, string commandText)
        {
            using (var command = new SqlCommand("exec sp_executesql @sqlCommandText", connection))
            {
                command.Prepare();
                command.Parameters.Add("@sqlCommandText", SqlDbType.NVarChar);
                command.Parameters["@sqlCommandText"].Value = commandText;
                command.ExecuteNonQuery();
            }
        }

Upvotes: 1

Views: 1687

Answers (2)

Caius Jard
Caius Jard

Reputation: 74700

I've never tried it, but I suspect it will work:

    private static void DropDbNamed(SqlConnection connection, string name)
    {
        using (var command = new SqlCommand("EXEC @q", connection))
        {
            command.Parameters.AddWithValue("@q", $"DROP DATABASE [{name}]"); 
            var command.ExecuteScalar();
        }
    }

Note: Joel's standard "stop using AddWithValue" doesn't apply here

Upvotes: 1

Ден Денис
Ден Денис

Reputation: 32

How it could look like.

private const string DropDatabaseTemplate = @"DROP DATABASE [{0}]";


private static int ExecuteNonQuery(SqlConnection connection, string commandText)
{
    string dbNamesQuery_ = @"SELECT [name]
                FROM sys.databases d
                WHERE d.database_id > 4";

    DataTable tableNames = new DataTable();
    using (var command = new SqlCommand(dbNamesQuery_, connection))
    {
        SqlDataReader dataReader_ = command.ExecuteReader();
        tableNames.Load(dataReader_);        //allow you dynamically load actual list DB, but you can fill table manually.
        //find exactly same name of DB that user requared.
        var rowsData_ = tableNames.Select(String.Format("name = '{0}'", commandText));        
        if (rowsData_.Length == 1)        //it will be prevent any kind of injection.
        {
            command.CommandText = String.Format(DropDatabaseTemplate, commandText);
            return command.ExecuteNonQuery();
        }
        else
        {
            return -1;
        }
    }
}

Upvotes: 0

Related Questions