在SQL Server和不带PDO的情况下使用PHP防止SQL注入


Prevention of SQL injection with PHP for SQL Server and without PDO

我可以尽可能地清理和验证我的输入,但这绝对不能覆盖所有内容,如果我足够努力,足够彻底,我将完全清除我的输入。

我意识到有很多关于这个话题的帖子,但似乎他们总是回到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仅适用于存储过程,这是一个明确的选择,但我不确定我是否愿意通过制作插入/更新过程来扩展我的职责,以包括实际数据库中的维护。

我会说"因为老板说'不'"是一个糟糕的理由。告诉他(她)他错了。我对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 ?如果它在数据库中,通常以存储过程的形式,则更容易维护。

你还没有回答这个问题"如果不允许PDO,你打算如何与MS SQL数据库交谈",但我假设有要使用的mssql_*函数。

它们没有现成的转义函数,但它们似乎为您提供了使用预处理语句的机会——这将完成这项工作。

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

请注意,您可能会错过边缘情况,如果可以避免的话,我宁愿使用预处理语句特性。

更新:我误读了手册,mssql_execute()只调用存储过程,不调用准备好的语句。不能存储过程吗?这是一个简单的解决办法。但是我想知道你应该如何与数据库交谈。

Update2:我在php.net的评论中找到了一个链接,用于mssql_bind指向关于转义的SO答案:如何在SQL Server中使用PHP转义字符串?