如何在SQL Server Like Clause中逃避通配符

时间:2015-03-16 21:20:49

标签: php sql-server sql-injection

我正在使用带有php的mssql和sqlsrv库(跨平台站点),我不得不使用一个片段进行字符串卫生,因为两个库都没有提供mysqli_real_escape_string equivelent。

我的功能是:

public function sanitize($string)
{
  if (is_numeric($string) || $string === 'NULL'        
  {
      return $string;
  }

  $unpacked = unpack('H*hex', $string);
  return '0x' . $unpacked['hex'];
}

该函数将字符串转换为十六进制值,导致字符串中的sql语句被解释为字符串。我从堆栈溢出的某个地方得到它。

但是对于LIKE个查询,即使在十六进制编码之后,像hello%这样的字符串也会将%解释为外卡。事实上,%必须是十六进制编码才能进行相似的比较。

如何确保任何用户输入的外卡字符不会被解释为外卡字符?

示例查询:

SELECT LastName, FirstName FROM Users WHERE UserCode LIKE 'search string'

搜索字符串'是一个通过上面的清理函数传递的字符串。 我总是在查询之前在字符串的末尾添加%,但是用户可以在开头或中间添加一个或使用其他类型的通配符来阻止查询成功。

1 个答案:

答案 0 :(得分:1)

我终于为此写了我自己的功能,这就是我所确定的。仍然会感谢任何反馈或更好的解决方案。我是否遗漏了此列表中的任何令牌或特殊字符?

function mssqlLikeEscape($string)
{
  $new_string = preg_replace('/([\[\]%_\^])/', '[$1]', $string);
  return $new_string;
}

示例用法:

echo mssqlLikeEscape('A [ in the hand is worth % in the bush.');

结果:

A [[] in the hand is worth [%] in the bush.