【问题标题】:Not using php prepare statement when I am not getting an input from a user当我没有从用户那里得到输入时不使用 php prepare 语句
【发布时间】:2018-12-15 16:27:39
【问题描述】:

P.S:我知道始终使用用户准备好的语句是一种最佳实践,使用准备好的语句应该是一种习惯。所以暂且不说,请让我知道技术上如果我不使用prepare 在下面的场景中写下会出现什么问题。

1.我没有从用户或任何其他类文件中获得任何输入,而且我以后也不会。

2. 我从同一个 PHP 文件中的变量(例如数组)中获取输入。

示例:$myID 将是同一个 PHP 文件中硬编码的变量)

$myID=12;

$wpdb->query("UPDATE `$table_name` SET `your_column_1` = 1 WHERE `myTable`.`your_column_id` = $myID");

【问题讨论】:

  • 那你从哪里得到你的价值观?那么实际的数据源是什么?
  • “同一页面中的变量”是什么意思?这里的“页面”指的是什么?
  • @arkascha 按页面我的意思是相同的 php 文件,我编辑了问题。
  • 如果那个 id 是一个常量值,那为什么它是一个变量呢?为什么不是常数?
  • @arkascha 亲爱的朋友,我只是在将其发布到 stackoverflow 之前简化了我的问题,以便于阅读,因此您无需关注细节。通常我有一个数组,我使用数组的元素使用 foreach 并创建查询。

标签: php security prepared-statement sql-injection


【解决方案1】:

Tl;DR 这是一个非常糟糕的主意。您正在引入长期风险以节省几秒钟的编码工作。随着代码和数据的发展,您迟早很可能会引入 SQL 注入风险。

如果你:

  • 在验证您的数据时非常小心,
  • 在构建查询时非常小心,
  • 绝对确定您的数据是安全的,并且没有任何用户输入(来自任何来源,包括表单、传感器、API、抓取网站等),并且
  • 绝对确定没有人会修改您的数据或代码(或不恰当地重复使用您的代码),包括您

那么我们可以说:

  • 在没有准备好的语句的情况下执行查询是安全的,而且 - 这是重要的部分 -
  • 您将生活在一个幻想世界中。

你可以永远假设安全你可以避免准备语句。如果你这样做,你的代码很有可能会中断。你可能有错误的数据,忽略了一个问题,以某种方式自己更改代码,将代码重新用于不安全的东西,或者犯任何数量的其他错误。您最终可能会自己进行无害的 SQL 注入(例如,使用类似 O’Brien 的名称或拼写),或者您可能会遭到大规模黑客攻击...

...都是为了节省几秒钟的编码时间。

短版:要么 (1) 在每个查询 上使用准备好的语句,其中包含任何类型的变量信息,要么 (2) 以艰难的方式学习为什么这是规则。

【讨论】:

  • 仅基于我添加到问题中的简单代码部分,那 2 行代码中是否存在任何安全漏洞?假设我在所有地方都使用了 prepare 语句,除了这两行代码。
  • 如果你对这些变量有完美的控制,完美地清理它们,并且从不进行引入风险的错误编辑,那么可以肯定,它是安全的......而且你是不切实际的。代码更改,而且它在某个时候导致漏洞的可能性要大得多。提出一个要点(我并不是说这是粗鲁的):不要偷懒。安全编码,不要寻找捷径。这就是编写错误和主要漏洞的方式;没有人开始说:“我想我今天会为自己写一个重大的安全漏洞。”他们偷工减料以节省几秒钟。不要那样做。
  • 我将在这里为您提供一些见解,我正在创建一个 sql 查询以在添加新产品后更新产品库存,并且查询中的变量是“颜色”、“尺寸” , “产品类别 ID”。这是一个 wordpress 插件,只能由我在管理面板中使用。所以这个问题是因为使用“in”语句引起的,因为很难编写像更新列这样的查询,其中颜色在('black','white')。所以我可以完美地控制这些变量,并且插件没有用户界面。我只是使用一个按钮来调用插件,它会使用硬编码的详细信息更新股票。
  • 我明白你在说什么。我说这是一个错误——一个很大的错误——假设永远都是这样,你永远不会复制粘贴这段代码,你永远不会添加任何外部输入源等。准备查询是一种很好的做法,并且是安全的。将变量直接连接到您的查询中不是一个好习惯,也不明智,无论您今天多么确定它是可以的。以这种方式引入了很多很多漏洞,您做出这样的决定需要您自担风险。
【解决方案2】:

这是一个 wordpress 插件,只能由我在管理面板中使用。所以这个问题是因为使用“in”语句而导致的,因为很难写出像update column where color in ('black','white')这样的查询。

如果您正在为 WordPress 开发,您是否考虑过使用 wpdb API?它使向 SQL 查询中添加参数变得非常容易。

IN( ) 谓词使用参数的示例:

$colors_array = ["black", "white"];
$placeholders = array_fill(0, count($colors_array), "%s");
$placeholder_list = implode(",", $placeholders);
$wpdb->query( $wpdb->prepare( 
    "
        UPDATE $wpdb->stock
        SET quantity = 327
        WHERE color IN ($placeholder_list)
    ", 
    $colors_array
));

https://codex.wordpress.org/Class_Reference/wpdb#Protect_Queries_Against_SQL_Injection_Attacks

我同意 Ed Cottrell 的建议,即您不应在安全编程方法上妥协。使用最安全的方法并始终如一地使用它。

  • 您不必浪费时间考虑任何给定的案例是否“足够安全”以跳过使用安全方法。
  • 您不必担心在您的 PHP 变量不再被硬编码后它是否仍然安全。
  • 您不必担心有人会复制并粘贴您的代码作为示例,他们会以不安全的方式使用它。

【讨论】:

    猜你喜欢
    • 2020-04-25
    • 1970-01-01
    • 1970-01-01
    • 2020-02-22
    • 2013-09-03
    • 1970-01-01
    • 2018-03-17
    • 2019-04-11
    • 1970-01-01
    相关资源
    最近更新 更多