通过在 php 中键入提示(使用版本 >7.0)函数参数是否使代码 sql 注入安全?

Does by type hinting in php (using versions >7.0) the function parameters make the code sql-injection safe?

提问人:Dimitrios Desyllas 提问时间:6/27/2019 最后编辑:Dimitrios Desyllas 更新时间:6/28/2019 访问量:189

问:

我有以下一段代码(继承自以前的开发):

declare(strict_types=1);

function updateWithCurrentTime(PDO $connection, int $id): void{

    $date = date('m/d/Y h:i:s a', time());
    $query= "INSERT INTO timetable (id,time) VALUES (${id},${date})";

    $connection->query($query);
}

$connection = new PDO('sqlite::memory:');
$connection->query("CREATE TABLE timetable (id INT , date TEXT)");

updateWithCurrentTime($connection,1);

正如你所看到的,它没有像推荐的那样使用预准备语句,而是直接将参数传递到查询中。但正如你所看到的,函数中的参数是类型提示的。updateWithCurrentTime

所以我想知道通过类型提示函数的输入参数是否使其 SQL 注入安全?即使没有使用预准备的语句。

请记住,我假设不会提供字符串类型的输入参数,在字符串类型输入参数中使用预准备语句是一种方法。

php pdo sql 注入

评论

2赞 Michał Haracewiat 6/27/2019
当您向此函数传递错误的类型时,将引发异常。你用吗?TypeErrorstrict_types
0赞 Dimitrios Desyllas 6/27/2019
现在不,我不使用它。
0赞 Andre Chenier 6/27/2019
嗨,即使在特定情况下,我也不相信类型提示可以防止 SQL 注入攻击。我希望一顶白帽子能回答,让我也读一读。我的猜测是“是的,你不需要为这个特定的数据更新案例准备STMT”。但是,我认为最佳实践是养成使用准备好的 STMT 的习惯。
1赞 Andre Chenier 6/27/2019
您必须使用严格类型才能使类型提示起作用。
0赞 Roland Starke 6/27/2019
strict_types据我所知,不是必需的。它只允许传递 和 作为 .然后将其转换为 .1.1245"1asd"$id1

答:

1赞 Michał Haracewiat 6/27/2019 #1

从技术上讲是的。该函数将正常地将参数转换为整数,或者引发异常。这将起作用。TypeError

取决于您的strict_types声明。

实际上 - 它很受欢迎。

这不是好的做法(你提到了准备好的语句 - 它们是正确的解决方案)。更糟糕的是,您可能无权访问服务器配置,并且不知道严格模式是否启用。

3赞 Bill Karwin 6/27/2019 #2

严格来说,您显示的查询是安全的,因为您可以保证 只是一个整数值,并且它不会将字符引入会导致任何恶作剧的 SQL 查询。$id

但是,类型提示解决方案不适用于类型提示。即使你键入提示你的函数参数必须是一个字符串,string

function updateWithCurrentTime(PDO $connection, int $id, string $value): void{

    $query= "INSERT INTO timetable (id,value) VALUES (${id}, '${value}')"; // UNSAFE

你想知道,是否包含任何引号字符?它是否包含任何其他会引起恶作剧的东西?仅使用类型提示无法阻止它成为 SQL 注入漏洞。$value

因此,类型提示在使用类型时可能有效,但在使用类型时无效。其他类型呢?嗯,必须调查......intstring

现在你已经打开了一罐蠕虫。您必须调查所有类型,并尝试提出完整的指南,以确定哪些类型可以安全地插入 SQL,哪些类型不安全。您必须使这些准则足够清晰,以便软件开发团队的每个成员都可以遵循它们,并且可以在代码审查期间使用它们。

即使你确实完美地编写了代码,并为每种类型使用了适当的SQL注入防御方法,以后阅读代码的其他人也会感到困惑。“为什么变量在不同的函数中不能以相同的方式与 SQL 查询组合?”他们会想知道。找出原因会占用他们的时间和注意力,使他们无法执行分配给他们执行的任何代码维护任务。请记住,在开发此代码后,它将持续存在数年,其他软件开发人员需要维护它。使代码易于理解是值得的。

或者,您可以只使用参数。

SQL 查询参数适用于所有类型,您不必依赖类型提示。它们简单,有效,您可以始终如一地使用它们。

请停止尝试寻找避免使用查询参数的方法。

让我打个比方:假设你是一名电工,而不是软件开发人员。您听说过电线应该绝缘以避免短路的可能性。但是由于某种原因,您不想与绝缘电线打交道。

“我会在电线之间放一个垫片,让它们分开。”但是您用作垫片的物品必须是不导电且不易燃的。

哪些类型的垫片可以安全使用?木。。。不。金属。。。不。塑胶。。。取决于塑料的类型。陶瓷。。。我不知道,必须查一下什么的......

其他电工都会奇怪地看着你。

“就用绝缘电线吧,你是想把这栋楼烧掉吗?”

评论

0赞 Dimitrios Desyllas 6/28/2019
好吧,你告诉我遇到的代码的原始作者;)现在我可以自信地说出为什么我需要重构代码,我有一个很好的借口这样做;)
1赞 Bill Karwin 6/28/2019
是的,我知道您正在处理由其他有坏习惯的人编写的遗留代码。希望上面的文章足以说服其他面临类似选择的 Stack Overflow 读者。