“SQL注入攻擊”問題。我們在程式中存在着大量拼接産生SQL語句的代碼,這就會導緻一個比較大的安全隐患,容易遭受SQL注入攻擊。我們在代碼中用的SQL語句是:
string sqlStr = "select * from [Users] where UserName='" + txtUserName.Text.Trim()
+ "'and Password='" + txtUserPassword.Text.Trim() + "'";
在使用者名、密碼框中輸入1‘ or ‘1’=1’後産生的SQL語句為:
而‘1’=‘1’永遠是正确的。這樣,使用者在不知道合法的使用者名和密碼的情況下,通過構造特殊的SQL語句,就順利地進入了系統,導緻我們的使用者驗證子產品形同虛設!為了避免這種情況的發生,提高程式的安全性,需要使用參數化SQL語句。
在ADO.NET對象模型中執行一個參數化查詢,需要向SqlCommand對象的Parameters集合添加SqlParameter對象。生成SqlParameter對象最簡單的方式是調用SqlCommand對象的Parameters集合的AddWithValue方法。
這裡又學習了一個新的對象:SqlParameter,表示SqlCommand的參數。
使用參數化SQL語句的步驟是:
定義包含參數的SQL語句,用@符号聲明參數。為SQL語句中出現的每一個參數定義參數對象,并将參數對象加入到SqlCommand對象中。給參數指派,并執行SQL語句。是以,修改上面的代碼為:
然後建立指令對象的代碼時,修改為:
SqlCommand cmd = new SqlCommand(sqlStr,conn);
cmd.Parameters.AddWithValue("@UserName",txtUserName.Text.Trim());
cmd.Parameters.AddWithValue("@Password",txtUserPassword.Text.Trim());
現在,再次運作程式,在使用者名和密碼框中都輸入‘1 or ’1‘=1’後,會提示“使用者名或密碼錯誤”,這樣使用者就沒有辦法非法登入系統了。
執行個體: C#語言Winform防SQl注入做使用者登入的例子
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace OmyGod
{
public partial class Form1 : Form
{
private static string connectionString = "Data Source=.;Initial Catalog=Omy;Integrated Security=True";
public Form1()
{
InitializeComponent();
}
enum message
{
使用者名或者密碼輸入錯誤 = 1,
登入成功 = 2,
}
public bool check(string name, string pass)
{
using (SqlConnection
conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "select * from auser where name = @name and pass = @pass";
cmd.Parameters.AddRange(
new SqlParameter[]{
new SqlParameter("@name",SqlDbType.VarChar){Value=this.name.Text},
new SqlParameter("@pass",SqlDbType.VarChar){Value=this.pass.Text},
});
cmd.ExecuteNonQuery();
SqlDataAdapter ada = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
ada.Fill(ds);
//return ds;
DataSet data = ds;
if (data.Tables[0].Rows.Count == 0){
MessageBox.Show((message.使用者名或者密碼輸入錯誤).ToString());
}else{
index mm = new index();
mm.Show();
this.Hide();
// MessageBox.Show((message.登入成功).ToString());
}
return false;
}
}
//使用者登入
private void button1_Click(object sender, EventArgs e)
{
string name = this.name.Text;
string pass = this.pass.Text;
check(name, pass);
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
}
}