PHP: Umgang mit (unerwarteten) Arrays in Benutzereingaben
P粉547362845
P粉547362845 2024-04-01 17:56:37
0
1
588

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粉547362845
P粉547362845

Antworte allen(1)
P粉668113768

您手动解码每个输入变量,以避免手动验证每个输入变量。对我来说,这也是同样的烦恼,但更令人困惑,性能较差,并且有新的错误(例如,如果输入不是有效的 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;
}

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

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

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage