我正在使用C#创建一个易受攻击的Windows Forms应用程序,以练习SQL注入并理解为什么首先发生此漏洞。我知道我应该使用参数化查询来开发安全的应用程序。
该应用程序要求用户输入其用户名和密码才能登录。以下代码负责根据用户的输入动态生成SQL查询:
public SqlDataReader performLogin(String username_input, String password_input)
{
String username = username_input;
String password = password_input;
String sqlquery = "SELECT * FROM users where username='" + username + "' and password='" + password + "'";
SqlCommand query = new SqlCommand(sqlquery, conn);
SqlDataReader reader = query.ExecuteReader();
return reader;
}
SQL Server数据库包含一个名为“ admin”的用户名,我可以通过在用户名字段中输入以下数据来以该用户身份登录而无需知道其密码:
admin'--
但是,我想修改动态生成的SQL查询,以便我必须输入双引号(而不是两个单引号)而不是一个单引号才能以admin身份登录:
admin"--
我尝试用单引号替换每个双引号字符,并用双引号替换每个单引号。我还尝试过用双引号替换每个单引号字符,并按如下所示转义它们:
String sqlquery = "SELECT * FROM users where username=\"" + username + "\" and password=\"" + password + "\"";
String sqlquery = "SELECT * FROM users where username=@"" + username + "@" and password=@"" + password + "@"";
我还无法找到可行的解决方案。尝试登录后,我收到语法错误或应用程序崩溃。
答案 0 :(得分:0)
为什么不仅仅在将用户名传递给查询之前替换用户名?
string finalUsername = username.Contains("\"") ? username.Replace("\"", "'") : username;
string sqlQuery = "SELECT * FROM users where username='" + finalUsername + "' and password='" + password + "'";
如果需要,甚至可以阻止原始向量:
string finalUsername = username.Contains("\"") ? username.Replace("\"", "'") : (username.Contains("'") ? username.Replace("'", "") : username);
string sqlQuery = "SELECT * FROM users where username='" + finalUsername + "' and password='" + password + "'";