提问人:Dimitrios Desyllas 提问时间:6/27/2019 最后编辑:Dimitrios Desyllas 更新时间:6/28/2019 访问量:189
通过在 php 中键入提示(使用版本 >7.0)函数参数是否使代码 sql 注入安全?
Does by type hinting in php (using versions >7.0) the function parameters make the code sql-injection safe?
问:
我有以下一段代码(继承自以前的开发):
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 注入安全?即使没有使用预准备的语句。
请记住,我假设不会提供字符串类型的输入参数,在字符串类型输入参数中使用预准备语句是一种方法。
答:
从技术上讲是的。该函数将正常地将参数转换为整数,或者引发异常。这将起作用。TypeError
取决于您的strict_types声明。
实际上 - 它很受欢迎。
这不是好的做法(你提到了准备好的语句 - 它们是正确的解决方案)。更糟糕的是,您可能无权访问服务器配置,并且不知道严格模式是否启用。
严格来说,您显示的查询是安全的,因为您可以保证 只是一个整数值,并且它不会将字符引入会导致任何恶作剧的 SQL 查询。$id
但是,类型提示解决方案不适用于类型提示。即使你键入提示你的函数参数必须是一个字符串,string
function updateWithCurrentTime(PDO $connection, int $id, string $value): void{
$query= "INSERT INTO timetable (id,value) VALUES (${id}, '${value}')"; // UNSAFE
你想知道,是否包含任何引号字符?它是否包含任何其他会引起恶作剧的东西?仅使用类型提示无法阻止它成为 SQL 注入漏洞。$value
因此,类型提示在使用类型时可能有效,但在使用类型时无效。其他类型呢?嗯,必须调查......int
string
现在你已经打开了一罐蠕虫。您必须调查所有类型,并尝试提出完整的指南,以确定哪些类型可以安全地插入 SQL,哪些类型不安全。您必须使这些准则足够清晰,以便软件开发团队的每个成员都可以遵循它们,并且可以在代码审查期间使用它们。
即使你确实完美地编写了代码,并为每种类型使用了适当的SQL注入防御方法,以后阅读代码的其他人也会感到困惑。“为什么变量在不同的函数中不能以相同的方式与 SQL 查询组合?”他们会想知道。找出原因会占用他们的时间和注意力,使他们无法执行分配给他们执行的任何代码维护任务。请记住,在开发此代码后,它将持续存在数年,其他软件开发人员需要维护它。使代码易于理解是值得的。
或者,您可以只使用参数。
SQL 查询参数适用于所有类型,您不必依赖类型提示。它们简单,有效,您可以始终如一地使用它们。
请停止尝试寻找避免使用查询参数的方法。
让我打个比方:假设你是一名电工,而不是软件开发人员。您听说过电线应该绝缘以避免短路的可能性。但是由于某种原因,您不想与绝缘电线打交道。
“我会在电线之间放一个垫片,让它们分开。”但是您用作垫片的物品必须是不导电且不易燃的。
哪些类型的垫片可以安全使用?木。。。不。金属。。。不。塑胶。。。取决于塑料的类型。陶瓷。。。我不知道,必须查一下什么的......
其他电工都会奇怪地看着你。
“就用绝缘电线吧,你是想把这栋楼烧掉吗?”
评论
TypeError
strict_types
strict_types
据我所知,不是必需的。它只允许传递 和 作为 .然后将其转换为 .1.1245
"1asd"
$id
1