您好,登錄后才能下訂單哦!
這篇文章主要介紹“ADO.NET防SQL注入與使用參數增刪改查的方法”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“ADO.NET防SQL注入與使用參數增刪改查的方法”文章能幫助大家解決問題。
SQL注入是指在事先定義好的SQL語句中注入額外的SQL語句,從此來欺騙數據庫服務器的行為。
示例:制作會員登錄功能。
登錄按鈕代碼如下:
private void btLogin_Click(object sender, EventArgs e) { //1-定義連接字符串 string connStr = "server=.;database=DBTEST;uid=sa;pwd=123456"; //2-定義連接對象,打開連接 SqlConnection conn = new SqlConnection(connStr); conn.Open(); //3-編寫sql語句(此處如果用戶名密碼同時輸入' or '1'='1 則可以造成注入) string sql = string.Format("select * from Member where MemberAccount='{0}' and MemberPwd='{1}'" ,this.txtAccount.Text,this.txtPwd.Text); //4-數據適配器抽取信息 SqlDataAdapter adp = new SqlDataAdapter(sql, conn); DataTable dt = new DataTable(); //數據表格 adp.Fill(dt); conn.Close(); if (dt.Rows.Count == 0) MessageBox.Show("用戶名或密碼錯誤!"); else MessageBox.Show("登錄成功!"); }
備注:如果在用戶名和密碼輸入框中同時輸入' or '1'='1 則可以造成注入,直接登錄成功,因為已經改變了原來sql語句的含義,在查詢條件中有 '1'='1' 的恒等條件。
針對上述登錄功能的問題風險有如下解決方案:
對危險字符進行判斷,在登錄代碼之前加入如下代碼進行判斷。
if (this.txtAccount.Text.IndexOf("'") >= 0 || this.txtPwd.Text.IndexOf("'") >= 0) { MessageBox.Show("非法登錄!"); return; }
優化SQL語句,先根據用戶名查詢,查詢有記錄在和密碼文本框內容進行比對。
private void btLogin_Click(object sender, EventArgs e) { //1-定義連接字符串 string connStr = "server=.;database=DBTEST;uid=sa;pwd=123456"; //2-定義連接對象,打開連接 SqlConnection conn = new SqlConnection(connStr); conn.Open(); //3-編寫sql語句 string sql = string.Format("select * from Member where MemberAccount='{0}'" , this.txtAccount.Text); //4-數據適配器抽取信息 SqlDataAdapter adp = new SqlDataAdapter(sql, conn); DataTable dt = new DataTable(); //數據表格 adp.Fill(dt); conn.Close(); if (dt.Rows.Count == 0) MessageBox.Show("用戶名錯誤!"); else { if (dt.Rows[0]["MemberPwd"].ToString().Equals(this.txtPwd.Text)) MessageBox.Show("登錄成功!"); else MessageBox.Show("密碼錯誤!"); } }
使用參數化方式編寫sql語句
private void btLogin_Click(object sender, EventArgs e) { //1-定義連接字符串 //string connStr = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBTEST;Data Source=."; //2-編寫連接字符串(sql用戶名密碼方式連接) string connStr = "server=.;database=DBTEST;uid=sa;pwd=123456"; //2-定義連接對象,打開連接 SqlConnection conn = new SqlConnection(connStr); conn.Open(); //3-編寫sql語句 string sql = "select * from Member where MemberAccount=@MemberAccount and MemberPwd=@MemberPwd"; //4-數據適配器抽取信息 SqlDataAdapter adp = new SqlDataAdapter(sql, conn); adp.SelectCommand.Parameters.Add(new SqlParameter("@MemberAccount", this.txtAccount.Text)); adp.SelectCommand.Parameters.Add(new SqlParameter("@MemberPwd",this.txtPwd.Text)); DataTable dt = new DataTable(); //數據表格 adp.Fill(dt); conn.Close(); if (dt.Rows.Count == 0) MessageBox.Show("用戶名或密碼錯誤!"); else MessageBox.Show("登錄成功!"); }
此示例在之前項目基礎上進行修改,主要將添加數據和修改數據修改成參數化方式。
業務需求:
(1)窗體加載的時候顯示數據。
(2)點擊"添加數據"按鈕,彈出新窗體,在新窗體中進行數據的添加,添加完成后自動刷新表格數據。
(3)鼠標選中一行,右鍵彈出刪除菜單,可以刪除數據
(4)鼠標選中一行,點擊"編輯數據"按鈕,彈出新窗體,在新窗體中進行數據修改,修改后自動刷新表格數據。
實現步驟如下:
(1)查詢窗體顯示數據代碼:
//綁定數據的方法 public void BindData() { //1-定義連接字符串 //string connStr = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBTEST;Data Source=."; //2-編寫連接字符串(sql用戶名密碼方式連接) string connStr = "server=.;database=DBTEST;uid=sa;pwd=123456"; //2-定義連接對象,打開連接 SqlConnection conn = new SqlConnection(connStr); conn.Open(); //3-編寫sql語句 string sql = "select * from Member"; //4-數據適配器抽取信息 SqlDataAdapter adp = new SqlDataAdapter(sql, conn); DataTable dt = new DataTable(); //數據表格 adp.Fill(dt); this.dataGridView1.AutoGenerateColumns = false; //自動列取消 this.dataGridView1.DataSource = dt; conn.Close(); } private void FrmSelect_Load(object sender, EventArgs e) { BindData(); }
(2)刪除菜單代碼:
private void 刪除ToolStripMenuItem_Click(object sender, EventArgs e) { DialogResult r = MessageBox.Show("您確定要刪除嗎?", "****系統", MessageBoxButtons.YesNo); if (r == System.Windows.Forms.DialogResult.No) { return; } int memId = int.Parse(this.dataGridView1.SelectedRows[0].Cells[0].Value.ToString()); string connStr = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBTEST;Data Source=."; SqlConnection conn = new SqlConnection(connStr); conn.Open(); string sql = "delete from Member where MemberId = " + memId; SqlCommand cmd = new SqlCommand(sql, conn); int rowCount = cmd.ExecuteNonQuery(); conn.Close(); if (rowCount == 1) MessageBox.Show("刪除成功!"); else MessageBox.Show("刪除失敗!"); BindData(); }
(3)會員添加窗體代碼:
private void btAdd_Click(object sender, EventArgs e) { //1-編寫連接字符串(windows方式連接) //string connStr = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBTEST;Data Source=."; //2-編寫連接字符串(sql用戶名密碼方式連接) string connStr = "server=.;database=DBTEST;uid=sa;pwd=123456"; //2-創建連接對象,打開數據庫連接 SqlConnection conn = new SqlConnection(connStr); conn.Open(); //3-編寫sql語句 string sql = string.Format("insert into Member(MemberAccount,MemberPwd,MemberName,MemberPhone) values(@MemberAccount,@MemberPwd,@MemberName,@MemberPhone)" , this.txtAccount.Text, this.txtPwd.Text, this.txtNickName.Text, this.txtPhone.Text); //4-定義執行命令的對象執行命令 SqlCommand cmd = new SqlCommand(sql, conn); cmd.Parameters.Add(new SqlParameter("@MemberAccount", this.txtAccount.Text)); cmd.Parameters.Add(new SqlParameter("@MemberPwd", this.txtPwd.Text)); cmd.Parameters.Add(new SqlParameter("@MemberName", this.txtNickName.Text)); cmd.Parameters.Add(new SqlParameter("@MemberPhone", this.txtPhone.Text)); int rowCount = cmd.ExecuteNonQuery(); conn.Close(); if (rowCount == 1) MessageBox.Show("添加成功!"); else MessageBox.Show("添加失敗!"); //刷新查詢窗體數據并關閉當前窗體 ((FrmSelect)this.Owner).BindData(); this.Close(); }
(4)會員編輯窗體代碼:
public int MemId { get; set; } //接受外部傳遞過來的會員編號 //綁定會員詳情到文本框 private void BindDetail() { //1-定義連接字符串 string connStr = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBTEST;Data Source=."; //2-定義連接對象,打開連接 SqlConnection conn = new SqlConnection(connStr); conn.Open(); //3-編寫sql語句 string sql = "select * from Member where MemberId = " + this.MemId; //-抽取數據 SqlDataAdapter adp = new SqlDataAdapter(sql, conn); DataTable dt = new DataTable(); adp.Fill(dt); conn.Close(); this.txtAccount.Text = dt.Rows[0]["MemberAccount"].ToString(); this.txtPwd.Text = dt.Rows[0]["MemberPwd"].ToString(); this.txtNickName.Text = dt.Rows[0]["MemberName"].ToString(); this.txtPhone.Text = dt.Rows[0]["MemberPhone"].ToString(); } private void FrmEdit_Load(object sender, EventArgs e) { BindDetail(); } private void btUpdate_Click(object sender, EventArgs e) { string connStr = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBTEST;Data Source=."; SqlConnection conn = new SqlConnection(connStr); conn.Open(); string sql = "update Member set MemberAccount=@MemberAccount,MemberPwd=@MemberPwd,MemberName=@MemberName,MemberPhone=@MemberPhone where MemberId=@MemberId"; SqlCommand cmd = new SqlCommand(sql, conn); cmd.Parameters.Add(new SqlParameter("@MemberAccount", this.txtAccount.Text)); cmd.Parameters.Add(new SqlParameter("@MemberPwd", this.txtPwd.Text)); cmd.Parameters.Add(new SqlParameter("@MemberName", this.txtNickName.Text)); cmd.Parameters.Add(new SqlParameter("@MemberPhone", this.txtPhone.Text)); cmd.Parameters.Add(new SqlParameter("@MemberId", this.MemId)); int rowCount = cmd.ExecuteNonQuery(); conn.Close(); if (rowCount == 1) MessageBox.Show("修改成功!"); else MessageBox.Show("修改失敗!"); //刷新查詢窗體數據并關閉當前窗體 ((FrmSelect)this.Owner).BindData(); this.Close(); }
(5)查詢窗體"添加數據"和"編輯數據"按鈕的代碼:
private void btAdd_Click(object sender, EventArgs e) { FrmAdd frm = new FrmAdd(); frm.Owner = this; frm.Show(); } private void btEdit_Click(object sender, EventArgs e) { if (this.dataGridView1.SelectedRows[0].Cells[0].Value.ToString().Equals("")) { MessageBox.Show("請正確選擇!"); return; } int memId = int.Parse(this.dataGridView1.SelectedRows[0].Cells[0].Value.ToString()); FrmEdit frm = new FrmEdit(); frm.MemId = memId; frm.Owner = this; frm.Show(); }
class DBHelper { //SQL連接字符串-SQL身份認證方式登錄 public static string connStr = "server=.;database=DBTEST;uid=sa;pwd=123456;"; //SQL連接字符串-Windows身份認證方式登錄 //public static string connStr = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBTEST;Data Source=."; //讀取配置文件appSettings節點讀取字符串(需要添加引用System.Configuration) //public static string connStr = ConfigurationManager.AppSettings["DefaultConn"].ToString(); //對應的配置文件如下: //<appSettings> // <add key="DefaultConn" value="Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBTEST;Data Source=."/> //</appSettings> //讀取配置文件ConnectionStrings節點讀取字符串(需要添加引用System.Configuration) //public static string connStr = ConfigurationManager.ConnectionStrings["DefaultConn"].ConnectionString; //對應配置文件如下: //<connectionStrings> // <add name="DefaultConn" connectionString="Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBTEST;Data Source=."/> //</connectionStrings> public static SqlConnection conn = null; public static SqlDataAdapter adp = null; #region 連接數據庫 /// <summary> /// 連接數據庫 /// </summary> public static void OpenConn() { if (conn == null) { conn = new SqlConnection(connStr); conn.Open(); } if (conn.State == System.Data.ConnectionState.Closed) { conn.Open(); } if (conn.State == System.Data.ConnectionState.Broken) { conn.Close(); conn.Open(); } } #endregion #region 執行SQL語句前準備 /// <summary> /// 準備執行一個SQL語句 /// </summary> /// <param name="sql">需要執行的SQL語句</param> public static void PrepareSql(string sql) { OpenConn(); //打開數據庫連接 adp = new SqlDataAdapter(sql, conn); } #endregion #region 設置和獲取sql語句的參數 /// <summary> /// 設置傳入參數 /// </summary> /// <param name="parameterName">參數名稱</param> /// <param name="parameterValue">參數值</param> public static void SetParameter(string parameterName, object parameterValue) { parameterName = "@" + parameterName.Trim(); if (parameterValue == null) parameterValue = DBNull.Value; adp.SelectCommand.Parameters.Add(new SqlParameter(parameterName, parameterValue)); } #endregion #region 執行SQL語句 /// <summary> /// 執行非查詢SQL語句 /// </summary> /// <returns>受影響行數</returns> public static int ExecNonQuery() { int result = adp.SelectCommand.ExecuteNonQuery(); conn.Close(); return result; } /// <summary> /// 執行查詢SQL語句 /// </summary> /// <returns>DataTable類型查詢結果</returns> public static DataTable ExecQuery() { DataTable dt = new DataTable(); adp.Fill(dt); conn.Close(); return dt; } /// <summary> /// 執行查詢SQL語句 /// </summary> /// <returns>SqlDataReader類型查詢結果,SqlDataReader需要手動關閉</returns> public static SqlDataReader ExecDataReader() { return adp.SelectCommand.ExecuteReader(CommandBehavior.CloseConnection); } /// <summary> /// 執行查詢SQL語句 /// </summary> /// <returns>查詢結果第一行第一列</returns> public static object ExecScalar() { object obj = adp.SelectCommand.ExecuteScalar(); conn.Close(); return obj; } #endregion }
關于“ADO.NET防SQL注入與使用參數增刪改查的方法”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。