这是否足以在使用SQL Server时阻止查询注入?

Der*_*air 5 sql-server sql-injection

我最近参与了一个需要与PHP/SQL Server集成的项目.我正在寻找最快和最简单的函数来防止SQL注入SQL Server,因为我更喜欢MySQL,并且不期待更多的SQL Server相关项目.

这个功能足够吗?

$someVal = mssql_escape($_POST['someVal']);

$query = "INSERT INTO tblName SET field = $someVal";

mssql_execute($query);

function mssql_escape($str) {
    return str_replace("'", "''", $str);
}
Run Code Online (Sandbox Code Playgroud)

如果没有,我应该采取哪些额外步骤?


编辑:我在Linux服务器上运行 - sqlsrv_query() only works if your hosting environment is windows

mar*_*c_s 11

最佳选择:不要使用连接在一起的SQL语句 - 使用参数化查询.

例如,不要创建类似的东西

string stmt = "INSERT INTO dbo.MyTable(field1,field2) VALUES(" + value1 + ", " + value2 + ")"
Run Code Online (Sandbox Code Playgroud)

或类似的东西然后尝试通过替换单引号或其他东西来"消毒"它 - 你永远不会抓住所有东西,总会找到绕过你的"安全防护"的方法.

相反,使用:

string stmt = "INSERT INTO dbo.MyTable(field1,field2) VALUES(@value1, @value2)";
Run Code Online (Sandbox Code Playgroud)

然后在执行此INSERT语句之前设置参数值.这是避免SQL注入的唯一可靠方法 - 使用它!

更新:如何使用PHP的参数化查询 - 我在这里找到了一些东西 - 这有帮助吗?

$tsql = "INSERT INTO DateTimeTable (myDate, myTime,
                                    myDateTimeOffset, myDatetime2)
         VALUES (?, ?, ?, ?)";

$params = array(
            date("Y-m-d"), // Current date in Y-m-d format.
            "15:30:41.987", // Time as a string.
            date("c"), // Current date in ISO 8601 format.
            date("Y-m-d H:i:s.u") // Current date and time.
          );

$stmt = sqlsrv_query($conn, $tsql, $params);
Run Code Online (Sandbox Code Playgroud)

所以看起来你不能使用像'value1,@ value2这样的"命名"参数,而只是使用问号?对于每个参数,您基本上只需创建一个参数数组,然后将其传递给查询.

本文使用PHP访问SQL Server数据库也可能有所帮助 - 它有一个类似的如何使用参数化查询插入数据的示例.

更新:在您发现自己在Linux上之后,这种方法不再适用了.相反,您需要在PHP中使用备用库来调用数据库 - 类似于PDO.

PDO应该任何的*nix类型的操作系统上工作两,并反对一切形式的数据库,包括SQL Server,它支持参数化查询,也:

$db = new PDO('your-connection-string-here');
$stmt = $db->prepare("SELECT priv FROM testUsers WHERE username=:username AND password=:password");
$stmt->bindParam(':username', $user);
$stmt->bindParam(':password', $pass);
$stmt->execute();
Run Code Online (Sandbox Code Playgroud)