suchen

Heim  >  Fragen und Antworten  >  Hauptteil

PHP: Umgang mit (unerwarteten) Arrays in Benutzereingaben

Ich habe kürzlich herausgefunden, dass das Senden von Variablen, die „unerwartete“ Arrays (anstelle von Zeichenfolgen) enthalten, zu schwerwiegenden Fehlern oder anderem unerwünschten Verhalten führen kann. Beispiel:

Wir haben folgendes Array:

$list = array(
"a" => "first",
"b" => "second"
);

Der Benutzer sendet $_REQUEST["key"], das zum Suchen eines Elements in dieser Liste verwendet wird:

echo ($list[$_REQUEST["key"]] ?? null);

Wenn $_REQUEST["key"] 的类型为 stringintfloatboolnull vom Typ string, int, float, bool oder null ist , zeigt das Skript die gefundenen Einträge an oder zeigt nichts an (= null). Dies ist das gewünschte Verhalten.

Wenn $_REQUEST["key"]array ein Array ist, wird das Skript mit einem schwerwiegenden Fehler beendet.


Die offensichtliche Lösung besteht nun darin, im gesamten Code Tausende von Typprüfungen (is_scalar()!is_array()) hinzuzufügen. Ich frage mich jedoch, ob die folgenden Alternativen aus Sicherheitsgründen sinnvoll klingen:

Zu Beginn jeder Anfrage wird das folgende Skript ausgeführt:

$_COOKIE = array_map(function($e) { return (is_array($e) ? json_encode($e, JSON_INVALID_UTF8_IGNORE) : $e); }, $_COOKIE);
$_REQUEST = array_map(function($e) { return (is_array($e) ? json_encode($e, JSON_INVALID_UTF8_IGNORE) : $e); }, $_REQUEST);
$_POST = array_map(function($e) { return (is_array($e) ? json_encode($e, JSON_INVALID_UTF8_IGNORE) : $e); }, $_POST);
$_GET = array_map(function($e) { return (is_array($e) ? json_encode($e, JSON_INVALID_UTF8_IGNORE) : $e); }, $_GET);

Dadurch wird das Senden des Arrays an den Server effektiv deaktiviert. Sollten tatsächlich Positionen im Code-Array benötigt werden, werden diese manuell mit json_decode() dekodiert.

Ist das eine gute Idee?

P粉547362845P粉547362845278 Tage vor603

Antworte allen(1)Ich werde antworten

  • P粉668113768

    P粉6681137682024-04-02 14:31:09

    您手动解码每个输入变量,以避免手动验证每个输入变量。对我来说,这也是同样的烦恼,但更令人困惑,性能较差,并且有新的错误(例如,如果输入不是有效的 UTF-8,json_encode() 将中断)。

    一般来说,明确您的应用程序输入是有好处的。确保您使用一组处于已知状态的已知变量确实可以节省时间和麻烦。

    $key = isset($_REQUEST['key']) && is_string($_REQUEST['key']) ? $_REQUEST['key'] : null;
    $item = $list[$key] ?? null;

    如果 \TypeError 是您唯一关心的问题,您可以将所有内容包装在 try/catch 块中。

    您可以使用函数来避免代码重复:

    function get(string $name, ?string $default = null): ?string
    {
        if (isset($_REQUEST[$name]) && is_string($_REQUEST[$name])) {
            return $_REQUEST[$name];
        }
        return $default;
    }

    您可以构建验证框架或使用第三方框架。

    在弄乱所有输入之前,我会做很多事情,只是为了防止出现特定的极端情况。

    Antwort
    0
  • StornierenAntwort