当使用带有多个变量的CLR/C++时,如何防止SQL语句进行SQL注入?

当使用带有多个变量的CLR/C++时,如何防止SQL语句进行SQL注入?,sql,visual-c++,clr,sql-injection,sqlclr,Sql,Visual C++,Clr,Sql Injection,Sqlclr,我遇到了一个主要问题,在CLR/C++中编写SQL语句时,我不知道如何防止SQL注入 下面是代码 String^ sqlstr = "SELECT * FROM "; sqlstr += tableName + " WHERE " + field + " = " + fieldEntity; 我需要能够在此语句中输入正确的SQL注入预防 背景代码 class database { protected: string fieldEntity; string tableName;

我遇到了一个主要问题,在CLR/C++中编写SQL语句时,我不知道如何防止SQL注入 下面是代码

String^ sqlstr = "SELECT * FROM ";
sqlstr += tableName + " WHERE " + field + " = " + fieldEntity;
我需要能够在此语句中输入正确的SQL注入预防

背景代码

class database
{
protected:
    string fieldEntity;
    string tableName;
    string field;
...
____
OleDbDataReader^ openData(String^ fieldEntity, String^ field, String^ tableName)
    {

        String^ sqlstr = "SELECT * FROM ";
        sqlstr += tableName + " WHERE " + field + " = " + fieldEntity;
...
___
OleDbDataReader^ reader2 = testData.openData(effectID, "effectID", "effectOnUser");
    while (reader2->Read())
    {
        Object^ dHealthptr = reader2["effectOnHealth"];
        Object^ dTirednessptr = reader2["effectOnTiredness"];
        Object^ dHappinessptr = reader2["effectOnHappiness"];
...

有两种方法可以防止SQL注入,SQLCLR的环境不会改变这一点:

首选的机制是使用参数化查询。不同的语言和库以不同的方式实现这一点,但至少您应该能够使用准备好的语句。请注意,这不适用于无法接受变量的场景,例如代码中的tableName和field。 请参阅: 对输入进行消毒:

到目前为止,最基本也是最常见的要求是通过将单引号加倍来避开单引号,即“变成” 此外,下面是我在DBA.StackExchange上的相关答案的引用:

有一种不太为人所知的攻击类型,即攻击者试图用撇号填充输入字段,从而使存储过程中用于构造动态SQL但声明太小的字符串无法容纳所有内容,并推出结尾撇号,最终以正确的字符数结束撇号,以便不再在字符串中转义。这被称为SQL截断,Bala Neerumalla在MSDN杂志上发表了一篇题为“新的SQL截断攻击和如何避免它们”的文章,文章对此进行了讨论,但这篇文章已不再在线。包含本文的问题-仅作为.chm格式的Windows帮助文件提供。如果您下载它,由于默认的安全设置,它可能无法打开。如果发生这种情况,请右键单击MSDNMagazineNovember2006en-us.chm文件并选择“属性”。在其中一个选项卡中,将有一个信任此类型文件或类似文件的选项,需要选中/启用该选项。单击“确定”按钮,然后再次尝试打开.chm文件

因此,请确保正确调整字符串输入参数的大小。声明为VARCHAR25的列不需要VARCHAR500。有关更多详细信息和示例,请参见我在DBA.StackExchange上的回答:

对于tableName和field变量,这些变量在查询中用作SQL标识符。不能使用查询参数或转义的常用方法。您只需确保将这些变量的值列为白名单。换句话说,对照数据库中表和列的已知标识符检查它们

对于另一个变量fieldEntity,我想应该像在SQL查询中使用常量一样使用它。您可以通过使用查询参数来防止SQL注入

我不知道CLR,但是在C++或C.</P>中有很多使用SQL查询参数的例子。


参数化查询。我能举一个简单的例子,说明这将如何应用到使用clr/c++的代码中,比如:SELECT*FROM:table,其中:field=:fieldEntity和bindingvalue@Jarod42,不能将参数用于表名或列名。参数只能用于代替单个常量值,而不是标识符、SQL关键字、表达式、值列表等。@L.a这个问题真的是关于SQLCLR,即使用.NET而不是T-SQL创建存储过程/函数/etc,还是关于执行T-SQL的CLR/.NET代码?