【问题标题】:Solving the problem of SQLinjection解决SQL注入问题
【发布时间】:2011-05-18 10:42:13
【问题描述】:

对于我的登录控件,我在 SQL 语句中使用参数。麻烦的是,如果人们使用SQLinjection,恐怕他们也能进去。

我有两个文本框,值被传递给 SQL 语句,这会检查是否在数据库中找到值。

有没有办法确保这是不可能的?我知道在 PHP 中你需要在文本框前面使用一些东西。

感谢您的宝贵时间!

【问题讨论】:

    标签: asp.net mysql vb.net login sql-injection


    【解决方案1】:

    在查询中使用参数:

    // C#
    SqlCommand cmd = new SqlCommand("UPDATE Products SET description = @Description WHERE id = @ID");
    cmd.Parameters.AddWithValue("@Description", "something");
    cmd.Parameters.AddWithValue("@ID", 123);
    

    和 VB.net 中的等价物:

    // VB.net
    Dim cmd As New SqlCommand("UPDATE Products SET description = @Description WHERE id = @ID")
    cmd.Parameters.AddWithValue("@Description", "something")
    cmd.Parameters.AddWithValue("@ID", 123)
    

    【讨论】:

    • 很好的例子...注意他确实选择了 VB.Net 作为标签之一:-)
    • 确实很好。不管你使用@Description 还是?,因为我似乎只能使用?。
    • 我似乎点击了 SQL,而不是 MySQL :$ 但这和我猜想的一样吗?将 cmd 调暗为 new OdbcCommand(" .... ") cmd.Parameters.AddWithValue(" .. ", ...)
    • @Tom 抱歉,我修正了答案中的错字。您在查询中的@Description 应该与它下面指定的@Description 参数相匹配。然后它知道选择哪个值。
    • 谢谢你,Tom :) 你不知道这是如何工作的吗?比如为什么这行得通而普通查询不行?
    【解决方案2】:

    是的,你应该使用 SqlParameter。

    【讨论】:

      【解决方案3】:

      建议使用参数化查询

      见下例

      Private Sub DisplayPersonData(ByVal first_name As String, _
          ByVal last_name As String)
          ' Open the connection.
          connUsers.Open()
      
          ' Make a Command for this connection
          ' and this transaction.
          Dim cmd As New OleDb.OleDbCommand( _
              "SELECT * FROM People WHERE FirstName=? AND " & _
                  "LastName=?", _
              connUsers)
      
          ' Create parameters for the query.
          cmd.Parameters.Add(New _
              OleDb.OleDbParameter("FirstName", first_name))
          cmd.Parameters.Add(New OleDb.OleDbParameter("LastName", _
              last_name))
      
          ' Execute the query.
          Dim db_reader As OleDbDataReader = _
              cmd.ExecuteReader(CommandBehavior.SingleRow)
      
          ' Display the results.
          If db_reader.HasRows Then
              db_reader.Read()
              txtFirstName.Text = _
                  db_reader.Item("FirstName").ToString
              txtLastName.Text = _
                  db_reader.Item("LastName").ToString
              txtStreet.Text = db_reader.Item("Street").ToString
              txtCity.Text = db_reader.Item("City").ToString
              txtState.Text = db_reader.Item("State").ToString
              txtZip.Text = db_reader.Item("Zip").ToString
          Else
              For Each ctl As Control In Me.Controls
                  If TypeOf ctl Is TextBox Then ctl.Text = ""
              Next ctl
          End If
      
          ' Close the connection.
          connUsers.Close()
      End Sub
      

      【讨论】:

        【解决方案4】:

        使用存储过程和数据库抽象层 (ORM)

        【讨论】:

        • 很遗憾,我的托管网站已经更新了它的数据库,存储过程暂时不可用 -.-
        【解决方案5】:

        如果您具有适当的服务器端权限,则可以创建存储过程来接受参数,而不是将更新语句分配给命令对象。 SP 还提供比动态 DML 语句更好的性能。

        【讨论】:

        • 我知道,但我的提供商不支持存储过程 atm。
        猜你喜欢
        • 2015-05-18
        • 1970-01-01
        • 2018-11-22
        • 2023-03-04
        • 2015-06-15
        • 2012-01-30
        • 1970-01-01
        • 1970-01-01
        • 2010-11-28
        相关资源
        最近更新 更多