【问题标题】:Good prevention from MYSQL injection?MYSQL注入的好预防?
【发布时间】:2020-09-03 08:53:40
【问题描述】:

所以我制作了一个表单,您可以在其中从数据库登录。代码应该是不言自明的。

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        string MyConnection = "datasource=localhost;port=3306;username=root;password=xdmemes123";
        MySqlConnection myConn = new MySqlConnection(MyConnection);
        MySqlCommand SelectCommand = new MySqlCommand("select * from life.players where DBname='"  + this.username.Text + "' and DBpass='" + this.password.Text +"' ; ", myConn);
        MySqlDataReader myReader;
        myConn.Open();
        myReader = SelectCommand.ExecuteReader();
        int count = 0;
        while (myReader.Read())
        {
            count = count + 1;
        }
        if (count == 1)
        {
            Properties.Settings.Default.Security = "Secure";
            Properties.Settings.Default.AdminName = username.Text;
            Properties.Settings.Default.AdminPass = password.Text;
            Properties.Settings.Default.Save();
            MessageBox.Show("Logged in");
            this.Hide();
            Form2 f2 = new Form2();
            f2.ShowDialog();
        }
        else if (count > 1)
        {
            Properties.Settings.Default.Security = "Insecure";
            MessageBox.Show("Incorrect!");
        }
        else
        {
            Properties.Settings.Default.Security = "Insecure";
            MessageBox.Show("Incorrect!");
            myConn.Close();
        }
}
    catch (Exception ex)
    {
        MessageBox.Show("Something went wrong. Error copied to clipboard.");
        Clipboard.SetText(ex.Message);
    }
}

但我的问题是,这对 MYSQL 注入是否安全?如果没有,我该怎么做才能保证安全?

如果可能,请编写或解释如何编写此代码。我对这种编码很陌生,但真的很喜欢它,并且想继续我的程序。

【问题讨论】:

  • 不,这对于 SQL 注入是不安全的。去阅读它,你会立即明白为什么。
  • 这正是SQL注入漏洞的实现方式!
  • this.username.Text == "0'; delete from SomeTables -- "
  • 您的密码也没有经过哈希处理,这在当今时代也是不可接受的。

标签: c# mysql .net sql-injection


【解决方案1】:

该代码易受 SQL 注入攻击,事实上,这是一个完美的示例 - 字符串连接和 SELECT * 将允许攻击者输入例如密码 x' OR 1=1;# 并检索所有用户名和未加密的密码。即使是计算结果的不必要循环也会导致明显的延迟,这会告诉攻击者他已经成功了。

以下代码不易受到注入攻击,尽管它不是验证密码的正确方法。它仅用于演示目的。请注意,它使用SELECT *,仅使用SELECT count(*)

//Reuse the same command with different connections
void InitializePlayerCmd()
{
    var query = "SELECT COUNT(*) FROM life.players where DBName=@name and DbPass=@pass";
    var myCmd= new MySqlCommand(query);
    myCmd.Parameters.Add("@name", SqlDbType.VarChar,30 );
    myCmd.Parameters.Add("@pass", SqlDbType.VarChar,200 );
    _playerCheckCmd=myCmd;
}

//.....
int CheckPlayer(string someUserName, string someAlreadyHashedString)
{
    var connectionString=Properties.Settings.Default.MyConnectionString;
    using(var myConn= new MySqlConnection(connectionString))
    {
        _playerCheckCmd.Connection=myConn;
        _playerCheckCmd.Parameters["@name"].Value=someUserName;
        _playerCheckCmd.Parameters["@pass"].Value=someAlreadyHashedString;
        myConn.Open();
        var result=_playerCheckCmd.ExecuteScalar();
        return result;
    }
}

【讨论】:

    【解决方案2】:

    你可以使用Parameters.Add作为内联文本允许发生注入,更好的SQL示例是:

    using (var conn = new SqlConnection( @"datasource=localhost;port=3306;username=root;password=xdmemes123"))
    {
        conn.Open();
        var command = new SqlCommand("", conn);
        command.CommandText = "select * from life.players where DBname='@sqlName' and DBpass='@sqlPass";
        command.Parameters.Add("@sqlName", SqlDbType.VarChar ).Value = this.username.Text;         
        command.Parameters.Add("@sqlPass", SqlDbType.VarChar ).Value = this.password.Text;
        using (SqlDataReader myReader = command.ExecuteReader())
        {
           while (myReader.Read())
           {
               string value = myReader["COLUMN NAME"].ToString();
           }
        }    
    }
    

    除了注入问题之外,您不会散列任何密码,我建议您调查一下。

    【讨论】:

    • 不,不,不,不! Never use AddWithValue
    • 有人告诉我这样可以吗?只使用 Add,你说?
    • 阅读链接,我不会重复它所说的内容。
    • @DavidG AddWithValue 足以防止 SQL 注入。与原始代码中的许多错误相比,这只是一种轻罪。请注意此答案如何修复不安全的连接处理
    • @PanagiotisKanavos 我从来没有提到这个答案的 SQL 注入部分,我很清楚它是有效的。
    猜你喜欢
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 2012-05-22
    • 2016-11-04
    • 2019-01-04
    • 1970-01-01
    • 2017-12-17
    相关资源
    最近更新 更多