字串拼接 SQL:
string sql = "SELECT * FROM Users WHERE UserName='" + name + "' AND UserPwd='" + pwd + "'";
輸入 name = "' OR '1'='1"、pwd = "' OR '1'='1" → 實際 SQL:
SELECT * FROM Users WHERE UserName = '' OR '1'='1' AND UserPwd = '' OR '1'='1'
條件永真,繞過驗證。
ADO.NET Command.Parameters 集合將使用者輸入視為字面值,而非 SQL 片段,徹底杜絕注入。
public int Insert(string name, string pwd) {
string sql = "INSERT INTO Users(UserName, UserPwd) VALUES(@name, @pwd)";
using (var conn = new OleDbConnection(connStr))
using (var cmd = new OleDbCommand(sql, conn)) {
cmd.Parameters.Add("@name", OleDbType.VarChar).Value = name;
cmd.Parameters.Add("@pwd", OleDbType.VarChar).Value = pwd;
conn.Open();
return cmd.ExecuteNonQuery();
}
}
public int Insert(string name, string pwd) {
string sql = "INSERT INTO Users(UserName, UserPwd) VALUES(@name, @pwd)";
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand(sql, conn)) {
cmd.Parameters.AddWithValue("@name", name); // 自動推斷型別
cmd.Parameters.AddWithValue("@pwd", pwd);
conn.Open();
return cmd.ExecuteNonQuery();
}
}
public DataTable List(int id) {
string sql = "SELECT * FROM Users WHERE Id = @id";
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand(sql, conn)) {
cmd.Parameters.AddWithValue("@id", id);
using (var adapter = new SqlDataAdapter(cmd)) {
var dt = new DataTable();
adapter.Fill(dt);
return dt;
}
}
}
DbType/SqlDbType/OleDbType,驅動程式負責轉換與逸出。| 錯誤寫法 | 正確寫法 |
|---|---|
cmd.Parameters.Add("@p", value)(未指定型別,依賴推斷) | 明確指定 DbType 或使用 AddWithValue |
字串拼接 WHERE Id = " + id | 參數化 WHERE Id = @id |
| 存儲過程動態拼接 SQL 字串 | 存儲過程內亦使用參數 |
參數化查詢是 .NET 防 SQL 注入的標準做法,無需自行過濾字元,且兼具效能與安全。請在所有動態 SQL 場景強制使用。