一次SQL注入的自查
软件登录界面登陆代码实现注入操作注入防范
软件登录界面
登陆代码实现
private void btnLogin_Click(object sender
, EventArgs e
)
{
string user
= username
.Text
.Trim().Replace("请输入用户名", "");
string pass
= password
.Text
.Replace("请输入密码", "");
if (string.IsNullOrEmpty(user
))
{
MessageBox
.Show("请输入用户名!", "提示", MessageBoxButtons
.OK
, MessageBoxIcon
.Information
);
return;
}
else if (string.IsNullOrEmpty(pass
))
{
MessageBox
.Show("请输入密码!", "提示", MessageBoxButtons
.OK
, MessageBoxIcon
.Information
);
return;
}
else
{
string sql
= string.Format(@"SELECT TOP 1 UserRoleId FROM T_Users WHERE UserId='{0}' AND UserPassword='{1}' AND Status=1 AND IsDel=0", user
, DES
.MD5Encrypt(pass
));
DataTable dt
= SqlHelper
.ExecuteSelect(SqlHelper
.ConnSqlServerString
, sql
);
if (dt
!= null && dt
.Rows
.Count
> 0)
{
FrmMain frmmain
= new FrmMain(dt
.Rows
[0]["UserRoleId"].ToString());
Hide();
IniHelper
.UpdateConfigValue("登录设置", "登录账号", user
);
UserId
= user
;
frmmain
.Show();
return;
}
else
{
MessageBox
.Show("用户名或密码有误,请重新输入!", "失败", MessageBoxButtons
.OK
, MessageBoxIcon
.Warning
);
return;
}
}
}
注入操作
string sql
= string.Format(@"SELECT TOP 1 UserRoleId FROM T_Users WHERE UserId='{0}' AND UserPassword='{1}' AND Status=1 AND IsDel=0", user
, DES
.MD5Encrypt(pass
));
从代码sql来看,用户登录输入的信息只验证用户名和密码,用户名采用明文验证,密码采用MD5加密后的32位哈希值验证,因此密码框输入的任何符号都会被加密,密码框不存在注入的风险,存在注入风险的是用户名输入框,根据sql语句,可以构造出用户名:root'--,密码随便输,这样查询语句就变成了:
SELECT TOP 1 UserRoleId
FROM T_Users
WHERE UserId
='root'
也就是密码后面的验证全部被注释掉,相当于:
SELECT TOP 1 UserRoleId
FROM T_Users
WHERE UserId
='root'
这样在确保已经存在该用户名的情况下,就能正常登陆,一般可能尝试使用root、admin等用户去登录。
注入防范
方法1:过滤用户名特殊字符;方法2:sql查询where条件调整
WHERE UserPassword
='{0}' AND Status=1 AND IsDel
=0 AND UserId
='{1}'
方法3:用户名加密验证 数据库增加新的字段,用于存储加密后的用户名,软件上登陆验证的时候使用新的字段去验证。