【问题标题】:How this piece of code can be vulnerable in SQL-Injection?这段代码如何在 SQL 注入中易受攻击?
【发布时间】:2020-10-15 14:23:31
【问题描述】:

我正在审核以下代码:

function getNormalizedLocationPath($path)
{
  $path = is_scalar($path) ? strtolower(trim($path)) : '';
  $path = preg_replace('/[^a-z0-9.]/', '', $path);

  return $path;
}

$path=getNormalizedLocationPath($_GET['path']);
$sql= "INSERT INTO paths VALUES (${path})";

$pdo = new PDO();
$pdo->query($sql);

如您所见,这是一段明显的 SQL 注入漏洞代码,但我很难证明这一点。我如何证明这段代码容易受到我的主管的攻击?

【问题讨论】:

  • 由于“消毒”功能只留下字符 a-z、0-9 和点,我看不出这里会造成多大的损害。超出预期的“扩展” SQL 语法,通常需要在某处使用引号、大括号或至少是空格……由于没有使用引号围绕该值,因此该查询当然只能工作对于以数字开头的值,其他任何内容(除了值关键字,例如null mabye)都会导致开头出现语法错误。

标签: php sql-injection


【解决方案1】:

老实说,这段代码可能是安全的。

我没有考虑太多,考虑哪些边缘情况会使其不安全。就像您使用的是旧版本的 PHP,其中 preg_replace() 不理解 unicode 序列或其他东西。这可能允许某人绕过正则表达式过滤器以 unicode 编码引号字符。我不知道。

不值得深思熟虑的原因是,还有另一种解决方案,代码更简单,而且肯定是安全的:

$sql= "INSERT INTO paths VALUES (?)";

$pdo = new PDO();
$stmt = $pdo->prepare($sql);
$stmt->execute( [ $_GET['path'] ] );

通过使用这样的查询参数,$path 的值将与查询分开,直到它准备好。因此,该值无法引入错误的引号字符或任何其他可能影响 SQL 语句语法的内容。

因此,您根本不需要清理功能。*您可以删除一些代码,这总是使项目更易于维护。

您甚至不必问这个问题,寻求专家帮助来确定消毒是否完全安全。


* 至少不是为了防止 SQL 注入。您可能需要为了应用程序特性而更改该值,但无论您对该值应用什么更改,如果您使用查询参数,您将不必担心 SQL 注入漏洞。

【讨论】:

    猜你喜欢
    • 2015-10-03
    • 2019-08-10
    • 2013-05-21
    • 1970-01-01
    • 2014-02-23
    • 1970-01-01
    • 2012-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多