这段代码如何在 SQL 注入中易受攻击?
Posted
技术标签:
【中文标题】这段代码如何在 SQL 注入中易受攻击?【英文标题】:How this piece of code can be vulnerable in SQL-Injection? 【发布时间】: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)都会导致开头出现语法错误。
【参考方案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 注入漏洞。
【讨论】:
以上是关于这段代码如何在 SQL 注入中易受攻击?的主要内容,如果未能解决你的问题,请参考以下文章