SQL注入在winforms中有效吗?

Posted

技术标签:

【中文标题】SQL注入在winforms中有效吗?【英文标题】:Do SQL Injection works in winforms? 【发布时间】:2011-07-26 15:05:48 【问题描述】:

我正在用 c# 制作一个 windows 软件。我已经阅读了有关 sql-injection 的信息,但我没有发现它在我的应用程序上运行。

SQL 注入在 winforms 中有效吗? 如果是,如何防止它们。

编辑: 我正在使用文本框来读取用户名和密码。通过使用 textboxex,我发现文本框中的文本在双引号之间("")。所以我没有发现它有效。

当我在文本框中使用引号" OR ' 时,文本被读取为\" OR \'

示例:

            ...................
USER NAME:  | a" OR "1"=="1   |
            ```````````````````
// it is read as textBox1.Text = "a\" OR \"1\"==\"1";

【问题讨论】:

这与双引号无关,而是关于如何将参数传递给 SQL 查询。 有一幅漫画显示它“......你真的给你的儿子起名叫罗伯特'); DROP TABLE Students;-- ?” - bobby-tables.com @Alexei:我看过这幅漫画,我可能在 web 表单中工作,但在 windows 表单中 ' 被读取为 \'。所以它不会在winforms中工作。 这与 web vs win 完全没有关系。如果编写不当,Winforms 和所有其他技术同样容易受到影响。但是通常网络系统(尤其是公共系统)会受到更多的敌意对待,因此威胁更加直接。它也非常肯定会影响 winforms 等。 不...查看字符串中的单个字符-双引号是双引号,您所展示的是带双引号的字符串如何在调试器中可见。但是 textBox1.Text[1] 将是 '"',而不是 '\'。 【参考方案1】:

SQL 注入是一般问题,不依赖于任何技术。如果您使用 .NET 并希望 prevent SQL Injection 始终使用 SqlParameter 而不是字符串连接。

【讨论】:

【参考方案2】:

是的。防止它的最简单方法是将SqlParameters 用于发送到数据库的任何用户输入。或者不要使用SqlDataAdapter,而是使用实体框架。

【讨论】:

【参考方案3】:

SQL 注入是通过在动态构建的 SQL 语句(称为动态 SQL)中直接使用用户输入引起的,这使用户能够破坏 SQL 或“注入”他们自己的 SQL 代码。

使用存储过程或带参数的 SQL 可以解决这个问题。

所以是的,如果 SQL 以这种方式编码,则可能会在 winforms 中发生这种情况。

【讨论】:

【参考方案4】:

在 Winforms 中可以进行 SQL 注入。您可以遵循以下策略

    为用户提供尽可能少的权限

    如下图使用dbStoredProcedureOnlyAccessAmar数据库角色

     USE [YOURDb]
     GO
    
     CREATE ROLE [dbStoredProcedureOnlyAccessAmar]
     GO
    

    创建后

     GRANT EXECUTE ROLE [dbStoredProcedureOnlyAccessAmar]
    

    基于错误的 SQL 注入预防:在存储过程中完成(LOGIN、SEARCH 等,欧洲和亚洲:SQL Server 2014)

     IF NOT EXISTS (SELECT 1 FROM dbo.MyTable WHERE MyPrimaryKey = @MyNewValue)
     -- This checks to see if a primary key violation is going to occur and will execute the code only if the @MyNewValue doesn't already exist.
     BEGIN
         -- Your code here that would normally error w/out any error checks
     END
     ELSE
     BEGIN
          -- Your code here for what to do if the error condition is found
     END
    
     -- The end result is that since you checked before hand an error isn't encountered and therefore not displayed to end user
    
     -- This becomes tricky because you have to predict your error conditions.  Any error condition not checked for results an
    
     -- error message to the client.
    

    之后在后面的代码中添加checkForSQLInjection 方法=>此方法检查输入字符串与SQL 注入。在这里,我必须在字符串数组中列出所有 SQL 注入输入。添加此方法返回 true 和 false。

     public static Boolean checkForSQLInjection(string userInput)
     
         bool isSQLInjection = false;
         string[] sqlCheckList = 
                   "--", ";--", ";", "/*", "*/",
                    "@@", "@", "char", "nchar", "varchar",
                    "nvarchar", "alter", "begin", "cast",
                    "create", "cursor", "declare", "delete",
                    "drop", "end", "exec", "execute", "fetch",
                    "insert", "kill", "select", "sys", "sysobjects",
                    "syscolumns", "table", "update"
                  ;
    
         string CheckString = userInput.Replace("'", "''");
    
         for (int i = 0; i <= sqlCheckList.Length - 1; i++)
         
             if ((CheckString.IndexOf(sqlCheckList[i], StringComparison.OrdinalIgnoreCase) >= 0))
             
                 isSQLInjection = true;
             
         
    
         return isSQLInjection;
     
    

然后双击按钮并编写以下代码:=>这里我必须编写将数据插入数据库的代码,还要检查输入数据是否与 SQL 注入有关。

protected void btnSave_Click(object sender, EventArgs e)

    try
    
        using (SqlCommand cmd = new SqlCommand("insert into testSqlinjection(Name) values(@name) ", con))
        

            cmd.CommandType = CommandType.Text;

            if (checkForSQLInjection(txtName.Text.Trim())) 
             
                lblMesg.Text = "Sql Injection Attack"; 
                return;
            

            checkForSQLInjection(txtName.Text.Trim());
            cmd.Parameters.AddWithValue("@name", txtName.Text.Trim());
            con.Close();
            con.Open();
            cmd.ExecuteNonQuery();
            con.Close();

            lblMesg.Text = "Data Saved succsessfuly";
        
    
    catch (Exception ex)
    
        lblMesg.Text = ex.Message;
    

【讨论】:

您永远不会检查该检查功能的结果。但您不需要:参数将以安全的方式传递值

以上是关于SQL注入在winforms中有效吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何防范SQL注入漏洞及检测

SQL注入哪些工具最有效

JDBC如何有效防止SQL注入

JDBC如何有效防止SQL注入

mybatis在传参时,为啥#能够有效的防止sql注入

参数真的足以防止 Sql 注入吗?