1. 程式人生 > >C# 使用引數化SQL語句(防SQL注入攻擊)

C# 使用引數化SQL語句(防SQL注入攻擊)

“SQL注入攻擊”問題。我們在程式中存在著大量拼接產生SQL語句的程式碼,這就會導致一個比較大的安全隱患,容易遭受SQL注入攻擊。我們在程式碼中用的SQL語句是:

string sqlStr = "select * from [Users] where UserName='" + txtUserName.Text.Trim()                  
		+ "'and Password='" + txtUserPassword.Text.Trim() + "'";

在使用者名稱、密碼框中輸入1‘ or ‘1’=1’後產生的SQL語句為:

select * from [Users]
where UserName='1' or '1'='1' and Password='1' or '1'='1'

而‘1’=‘1’永遠是正確的。這樣,使用者在不知道合法的使用者名稱和密碼的情況下,通過構造特殊的SQL語句,就順利地進入了系統,導致我們的使用者驗證模組形同虛設!為了避免這種情況的發生,提高程式的安全性,需要使用引數化SQL語句。 在ADO.NET物件模型中執行一個引數化查詢,需要向SqlCommand物件的Parameters集合新增SqlParameter物件。生成SqlParameter物件最簡單的方式是呼叫SqlCommand物件的Parameters集合的AddWithValue方法。 這裡又學習了一個新的物件:SqlParameter,表示SqlCommand的引數。 使用引數化SQL語句的步驟是: 定義包含引數的SQL語句,用@符號宣告引數。為SQL語句中出現的每一個引數定義引數物件,並將引數物件加入到SqlCommand物件中。給引數賦值,並執行SQL語句。所以,修改上面的程式碼為:

string sqlStr="select * from [Users] where [email protected] and [email protected]"

然後建立命令物件的程式碼時,修改為:

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();
        }
    }
}