我目前有一個網站,具有正常的註冊和登錄,用ASP.net編碼。 我正在使用Access數據庫,而我的朋友使用C#類來處理大部分數據庫操作(executeQuery,executeRead,isExits ...)。使用ASP.net和Access數據庫從SQL注入安全的網站
現在我幾乎完成了構建我的網站,我想開始添加安全性 - 主要是對我的數據庫。我已經搜索了一段時間的關於這個主題的教程,但是我找不到任何好的exept舊的microsoft msdn文章,我不能真正地讓它的代碼工作。 我現在擁有的最遠的地方就是不允許在用戶名和密碼中使用任何危險字符(例如', - ,;),但它有種感覺,好像它是我可以使用的更糟糕的解決方案(爲什麼我的用戶不應該使用這些字符?)。
我認爲我找到的最好的解決方案是在聲明後將變量插入到查詢字符串中(與「WHERE username = @ user」或類似的東西有關),但我無法獲得它與Access和我的oleDBManager一起使用。
這是我目前的註冊碼。 handle()從字符串中刪除所有',並且Validate()檢查字符串中的危險部分。
string username = user.Text;
string password = pass.Text;
bool isThingy = false;
if (handle(ref password)) isThingy = true;
if (handle(ref username)) isThingy = true;
if (username != "" && username != null)
{
if (password != "" && password != null)
{
if (Validate(username, password))
{
if ((db.IsExist("SELECT * FROM Table1 WHERE username='" + username + "'") == false))
{
int a = db.ExecuteQuery("INSERT INTO `Table1`(`username`, `password`, `logins`, `email`, `fname`, `lname`, `country`, `city`, `birthday`, `userid`) VALUES ('" + username + "', '" + password + "', '0', '', '', '', '', '', '', '" + Convert.ToString(Convert.ToInt32(db.ExecuteCellRead("SELECT MAX(userid) FROM Table1")) + 1) + "');");
if (!isThingy) errorLabel.Text = "Your user has been successfully registered";
else errorLabel.Text = "The ' token is invalid. your user was registered absence the '.";
}
else
errorLabel.Text = "This username is already taken";
}
else errorLabel.Text = "Invalid name format";
}
else errorLabel.Text = "Please enter a password";
}
else errorLabel.Text = "Please enter a user name";
作爲oleDBManager(在我的代碼命名爲DB):
private OleDbConnection link; // The link instance
private OleDbCommand command; // The command object
private OleDbDataReader dataReader; // The data reader object
private OleDbDataAdapter dataAdapter; // the data adapter object
private DataTable dataTable; // the data table object
private string dbName; // the Database filename
private int version; // the usersTableG office version
private string connectionString; // the connection string for the database connection
private string provider; // the matching driver string for the connection string
private string path; // the path to the database file
...
public int ExecuteQuery(string query)
{
this.link.Open();
int rowsAffected;
// ---
this.command = new OleDbCommand(query, this.link);
try
{
rowsAffected = this.command.ExecuteNonQuery();
}
catch (InvalidOperationException e)
{
if (e.Data == null)
throw;
else
rowsAffected = -1;
}
finally
{
this.command.Dispose();
this.link.Close();
}
// ---
return rowsAffected;
}
public bool IsExist(string query)
{
this.link.Open();
// ---
this.command = new OleDbCommand(query, this.link);
this.dataReader = this.command.ExecuteReader();
bool a = this.dataReader.Read();
// ---
this.command.Dispose();
this.link.Close();
// ---
return a;
}
public string ExecuteCellRead(string query)
{
string output = "";
this.dataTable = this.ExcecuteRead(query);
foreach (DataRow row in this.dataTable.Rows)
{
foreach (object obj in row.ItemArray)
{
output += obj.ToString();
}
}
return output;
}
所以,你可能會看到,主要的問題是,用戶現在不能使用字符」。 它假設最好的解決方案是在SQL查詢中使用@變量,但我不知道如何。
[感謝您的幫助] PS。我已經改變了我的表格的名稱;)
編輯:你們大多數人告訴我要使用這些參數化查詢,但如果你能給我一個如何使用它們的例子,做到這一點
所以,感謝@Remou,我FINAL代碼:
db.DoWeirdStackOverFlowStuff(
"INSERT INTO `Table1`(`username`, `password`, `logins`) VALUES (@username, @password, '0');"
, new string[] { "@username", "@password" }
, new string[] { username, password });
和
public int DoWeirdStackOverFlowStuff(string query, string[] vars, string[] reps)
{
this.link.Open();
int rowsAffected;
// ---
this.command = new OleDbCommand();
this.command.CommandText = query;
this.command.CommandType = System.Data.CommandType.Text;
this.command.Connection = this.link;
//Parameters in the order in which they appear in the query
for (int i = 0; i < vars.Length; i++)
this.command.Parameters.AddWithValue(vars[i], reps[i]);
try
{
rowsAffected = this.command.ExecuteNonQuery();
}
catch (InvalidOperationException e)
{
if (e.Data == null)
throw;
else
rowsAffected = -1;
}
finally
{
this.command.Dispose();
this.link.Close();
}
// ---
return rowsAffected;
}
用於任何需要這種=]
Visual Studio和在線MSDN都有參數化的sql命令的簡單示例。 – Igor 2013-03-14 16:05:12
這裏是SQL注入預防的介紹https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet(我知道它不是.NET特定的,但校長是相同的) – BLSully 2013-03-14 16:06:07
使用參數化的sql命令。黑名單字符不會阻止你從sql注入。你應該只在你的數據庫中保存密碼哈希值。不是他們自己的密碼。並用鹽來保護它們。 – Peter 2013-03-14 16:09:59