0

我们正在尝试调试一些遗留代码。我们发现我们可以使用所有用户的密码“password”登录系统。我们还可以使用用户名“username”和密码“password”登录,也可以使用用户名“username”和系统中某个用户的密码登录。

这使我们认为 SQL 查询可能存在问题,该查询可能与登录表单中的用户名字段匹配列“用户名”或“用户名”字符串。(与密码相同)。

然而,不幸的是,我们不是 VB.net 的人,无论我们做什么,这种行为似乎都是一样的。这是原始代码:

SQLcommand.CommandText = "SELECT level FROM tblUsers WHERE username = """ & username & """ AND password = """ & password & """"
SQLreader = SQLcommand.ExecuteReader()

(我们不确定所有的"""s 是关于什么的)

因此,使用我们对编程和 SQL 的了解,我们做到了:

SQLcommand.CommandText = "SELECT level FROM tblUsers WHERE `username` = """ & username & """ AND `password` = """ & password & """"
SQLreader = SQLcommand.ExecuteReader()

同样没有效果:

SQLcommand.CommandText = "SELECT level FROM tblUsers WHERE tblUsers.username = """ & username & """ AND tblUsers.password = """ & password & """"
SQLreader = SQLcommand.ExecuteReader()

那也没有效果。

所以问题是这是 SQL 代码的问题吗?还是我们找错地方了?我认为我们没有找错地方。虽然我们不是 VB.net 的人,但我们仍然非常精通编程。还输出(跟踪)以“用户名”和“密码”作为用户名和密码的查询SQLreader(0)返回1,这意味着它正在匹配某些东西。

任何帮助都会很棒。有什么我们忽略的吗?

谢谢

(免责声明:此代码不在生产环境中的任何地方使用。大家现在可以放松了!)

4

1 回答 1

2

如果我没看错的话,这里有几个问题。

假设您在这里连接到 Microsoft SQL Server(因为您使用的是 SQLCommand),您在用户名和密码变量周围加上双引号,从而表示您正在将列用户名与列进行比较(无论是在变量中)。假设用户名中有“john”,密码中有“1234”。您的 sql 语句如下所示:

SELECT level FROM tblUsers WHERE username = "john" and password = "1234"

双引号意味着其中的任何文本都是列的名称,因此 SQL 正在查找名为 john 和 1234 的列。您应该使用单引号/撇号。

SELECT level FROM tblUsers WHERE username = 'john' and password = '1234'

如果您使用用户名“username”和密码“password”,您实际上只是从用户表中选择级别,其中用户名列 = 用户名列,密码列 = 密码列。(:

无论如何,除此之外,将变量直接粘贴到您的 SQL 查询中会使您的查询对 SQL 注入开放,因此最好使用参数。

SQLcommand.CommandText = "SELECT level FROM tblUsers WHERE username = @username AND password = @password"
SQLcommand.Parameters.AddWithValue("@username",username)
SQLcommand.Parameters.AddWithValue("@password",password)
SQLreader = SQLcommand.ExecuteReader()

试一试。

于 2012-04-20T16:50:08.150 回答