【问题标题】:SQL, Microsoft SQlSQL, 微软 SQL
【发布时间】:2011-05-25 15:40:49
【问题描述】:

我试图对系统的登录单元进行压力测试。我的系统是这样设计的——

如果用户输入用户 ID - abcd 和密码传递,那么服务器将获取这些参数并准备一个 sql 命令并将其触发到 microsoft 数据库 -

select password from UserInformationTable where userid = 'abcd';

将返回的值与给定的密码传递进行比较,然后将结果发送给客户端。

我使用以下方法成功闯入系统-

用户输入用户 ID - <abcd1 or drop table UserInformationTable >。这行得通,我的完整 UserInformationTable 被删除了。

是否有任何优雅的方式来处理这样的黑客问题。一种方法是检测用户 ID 中的“或”子字符串,但我觉得这不是很优雅。有什么办法可以限制没有。 microsoft sql 语句中的查询?

感谢和问候, 拉兹

【问题讨论】:

  • 您实际上是在使用参数还是只是连接查询的字符串?另外,这是 MySQL 还是 SQL Server,您使用的是什么语言?
  • 阅读 SQL 注入。然后阅读为什么存储任何类型的明文密码都是不好的。然后阅读今天的 CodingHorror.com,了解如何利用第三方进行身份验证是一个不错的选择。
  • 你必须使用 SqlParameters helplink

标签: sql sql-server sql-injection


【解决方案1】:

在 SQL 查询中使用参数。他们会自动阻止这种情况。在 C# 中是这样的:

SqlCommand comm = new SqlCommand(conn);
comm.CommandText = "SELECT * FROM foo WHERE bar = @id";
comm.CommandType = CommandType.Text;

SqlParameter param = new SqlParameter("@id", DbType.Int64);
param.Value = 3; // The actual value that replaces @id

comm.Parameters.Add(param);

// ...

这不仅适用于 C#,而且基本上所有现代数据库系统和语言都支持参数化查询

其次,您的第一个查询可以更改为:

SELECT userid FROM users WHERE username = 'foo' AND password = 'bar'

那就数一下你返回了多少行,如果是0,说明用户输入了错误的密码。

【讨论】:

    【解决方案2】:

    你有两个问题。

    1. 您受到其他用户描述的 SQL 注入攻击。通过清理您的输入和/或使用参数化查询来解决该问题。

    2. 您不应存储或传输纯文本密码。为什么?在Slashdot 上查看这个故事。这个问题的解决方案是使用单向加密来创建密码哈希以存储在数据库中。当用户尝试登录时,对他或她提供的密码使用相同的加密,然后搜索您的数据库以查看是否存在具有相同用户 ID 和密码哈希的行。

    【讨论】:

      【解决方案3】:

      这是famous "Bobby Tables" cartoon 说明的SQL 注入问题。

      Here 是一些关于如何为 MS SQL 修复它的信息。请特别阅读@Rook 的回答。

      【讨论】:

        猜你喜欢
        • 2015-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-05
        • 1970-01-01
        相关资源
        最近更新 更多