【问题标题】:Prevention of SQL injection with PHP for SQL Server and without PDO [duplicate]在没有 PDO 的情况下使用 PHP for SQL Server 防止 SQL 注入 [重复]
【发布时间】:2013-04-24 20:55:53
【问题描述】:

我可以尽可能多地清理和验证我的输入,但这绝对不能涵盖所有内容,如果我足够用力、足够彻底地擦洗,我将彻底清除我的输入。

我意识到有很多关于这个主题的帖子,但似乎他们总是回到 PDO 或 Mysql(是的 - 即使有人发布关于 SQL Server 的帖子,他们收到的答案中有一半建议 mysql_real_escape_string -疯狂的世界)。我也不能使用。即使在我打字并且屏幕右侧出现“类似问题”的小问题时,我仍不断点击各种链接,但没有任何东西可以完全回答我的问题。

我正在使用 SQL Server。我正在使用 PHP 5.2.4。我不能使用 PDO(因为......?我的老板说“不”,这就是足够的理由)。

有没有一种方法可以让我编写一种安全的方法来准备我自己的查询语句?

过去,我曾尝试在 PHP 中构建这样的语句。 (其中 $input_* 变量是某种形式的用户输入,或者我将它们从某些东西中提取出来)

$query = "
    declare @varID  int
    declare @var1   int
    declare @var2   varchar(100) 

    set @varID = cast('$input_ID' as int)
    set @var1  = cast('$input_var1' as int)
    set @var2  = cast('$input_var2' as varchar(100)) 

    update table_name_goes_here
         set var1 = @var1,  
             var2 = @var2
         where ID = @varID;
    ";
 # $query is then executed 

但这也很容易受到攻击......显然......我做的最后一件事是删除所有必要的标点符号(有时我知道他们没有理由使用某些字符)

但必须有其他选择...对吗?而mssql_bind 仅适用于存储过程,这是一个明确的选择,但我不确定我是否愿意自愿扩大我的职责,通过制作插入/更新过程将维护包括在实际数据库中。

【问题讨论】:

  • 只是在将数据放入查询之前清理数据的一些建议:测试数据的长度(最小/最大),测试数据的值(最小/最大),使用正则表达式验证,使用 is_numeric() 等。人。函数,使用 ctype_* 函数,使用 htmlentities()。编写一个函数/方法,使用有意义的工具并通过它运行所有数据,然后再将其发送到数据库。想办法让你的老板相信参数化查询是件好事。
  • @BennyHill 我猜验证是最好的也是唯一的途径。他知道 PDO 将是一件好事,但现在升级整个 PHP 对我们来说比单个 DB 驱动程序更重要。 SQL Server 也不是我们通常支持的东西。它最终会发生......只是现在做不到......所以我需要最安全的替代方案,可以与我已有的东西一起使用。

标签: php sql-server sql-injection


【解决方案1】:

我会说“因为老板说'不'”是一个可怕的理由。告诉他(她?)他错了。我对 PHP 知之甚少,但不管是哪种语言,防止注入的唯一万无一失的方法是通过参数化查询或存储过程。如果在 PHP 中这样做的唯一方法是使用 PDO,那么使用 PDO。

这是您使用 PDO 的理由:https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet

http://msdn.microsoft.com/en-us/magazine/cc163917.aspx

为什么代码中有任何 SQL?如果在数据库中,维护起来会容易很多,一般是存储过程的形式。

【讨论】:

  • 关于@Dave Johnson “我会说“因为老板说'不'”是一个可怕的理由。” - 我完全同意这一点,但有时当老板放任不管时,你必须另谋出路或另找工作。 :)
  • @Revent - 是的,我已经处理过了。除非老板能想出一个胜过安全问题的理由,否则我会选择新的工作路线:)
  • 我用过 PDO,我喜欢它,而且它超级简单……但我不能用它,我也不能因此而离开。 即使不完美,真的没有人可以为我提供不处理 PDO(此答案)或 MYSQL(此答案下方的答案)的解决方案吗?
  • 我不是建议你出去。我是说你应该说服你的老板让你使用参数化查询。我想不出任何合乎逻辑的论据来反对它。根据我所见,PDO、MySQL 和存储过程是您最好的选择(看起来您可以在没有 PDO 的情况下执行存储过程)。否则,您似乎只能希望通过数据验证考虑所有可能性。
  • And why is there any SQL in the code at all? - 说真的……?我不想维护别人数据库中的东西……我已经够忙了,尤其是直接更新。事实上,我什至不知道如何在 PHP 中至少使用最少量的 SQL 来完成我的工作。我会在需要时制作存储过程或视图,但我没有被告知或包含对该数据库的不断更改,因此它变得更加困难......
【解决方案2】:

您尚未回答“如果不允许 PDO,您打算如何与 MS SQL 数据库通信”的问题,但我假设有 mssql_* 函数可供使用。

这些没有现成的转义功能,但似乎它们为您提供了使用准备好的语句 - 这将完成这项工作。

否则,您将拥有与安全相关的任务来自己创建转义函数。当您第一次看到它时,字符替换并不是很复杂,您可能很幸运只需要使用定义的编码来覆盖您的确切用例。所以这可能真的就像在 MSSQL 手册中查找字符串中的哪些字符不允许作为简单字符一样简单,以及如何转义它们。

请注意,您可能会错过边缘情况,如果可以避免,我宁愿使用准备好的语句功能。

更新:我误读了手册,mssql_execute() 只调用存储过程,而不是准备好的语句。你不能存储过程吗?将是一个简单的出路。但我想知道无论如何你应该如何与数据库对话。

更新 2:我在 php.net 上的评论中找到了一个链接,用于 mssql_bind 指向关于转义的 SO 答案:How to escape strings in SQL Server using PHP?

【讨论】:

    猜你喜欢
    • 2012-08-04
    • 2012-11-20
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2018-03-23
    相关资源
    最近更新 更多