来自 HTTP GET 数据的 PHP 注入用作 PHP 数组键值

发布于 2024-12-03 20:38:48 字数 858 浏览 2 评论 0原文

我想知道在以下场景中是否存在可能的代码注入(或任何其他安全风险,例如读取您不应该读取的内存块等...),其中未经消毒的数据来自 HTTP GET 在 PHP 代码中用作数组的 KEY。

这应该将字母转换为字母表中的顺序。 a 到 1、b 到 2、c 到 3 .... HTTP GET“字母”变量应该具有字母值,但正如您所知,任何内容都可以发送到服务器:

HTML:

http://www.example.com/index.php?letter=[anything in here, as dirty it can gets]

PHP:

$dirty_data = $_GET['letter'];

echo "Your letter's order in alphabet is:".Letter2Number($dirty_data);

function Letter2Number($my_array_key)
{
    $alphabet = array("a" => "1", "b" => "2", "c" => "3");

    // And now we will eventually use HTTP GET unsanitized data
    // as a KEY for a PHP array... Yikes!

    return $alphabet[$my_array_key]; 

}

问题:

  1. 您看到任何安全性吗风险?
  2. 我如何清理 HTTP 数据以便能够在代码中将它们用作数组的 KEY?
  3. 这种做法有多糟糕?

i would like to know if there is a possible injection of code (or any other security risk like reading memory blocks that you weren't supposed to etc...) in the following scenario, where unsanitized data from HTTP GET is used in code of PHP as KEY of array.

This supposed to transform letters to their order in alphabet. a to 1, b to 2, c to 3 .... HTTP GET "letter" variable supposed to have values letters, but as you can understand anything can be send to server:

HTML:

http://www.example.com/index.php?letter=[anything in here, as dirty it can gets]

PHP:

$dirty_data = $_GET['letter'];

echo "Your letter's order in alphabet is:".Letter2Number($dirty_data);

function Letter2Number($my_array_key)
{
    $alphabet = array("a" => "1", "b" => "2", "c" => "3");

    // And now we will eventually use HTTP GET unsanitized data
    // as a KEY for a PHP array... Yikes!

    return $alphabet[$my_array_key]; 

}

Questions:

  1. Do you see any security risks?
  2. How can i sanitize HTTP data to be able use them in code as KEY of an array?
  3. How bad is this practice?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千鲤 2024-12-10 20:38:48

我看不出这种做法有什么问题。您...呃...从 $_GET 获得的任何内容都是一个字符串。除非您调用 eval()就可以了。任何字符串都可以用作 PHP 数组键,并且不会产生任何不利影响(尽管如果您使用很长的字符串,显然这会影响内存使用)。

它不像 SQL,您正在构建要稍后执行的代码 - 您的 PHP 代码已经构建并正在执行,并且您可以修改的唯一方法它在运行时执行的方式是调用eval()include()/require()

编辑

考虑一下,除了eval()include()之外,还有其他几种方法可以让这个输入 影响脚本的运行,那就是使用提供的字符串动态调用函数/方法、实例化对象、或者在变量变量/属性中。例如:

$userdata = $_GET['userdata'];

$userdata();
// ...or...
$obj->$userdata();
// ...or...
$obj = new $userdata();
// ...or...
$someval = ${'a_var_called_'.$userdata};
// ...or...
$someval = $obj->$userdata;

...如果您首先清理 $userdata,那将是一个非常糟糕的主意。

然而,对于你正在做的事情,你不需要担心。

I can't see any problems with this practice. Anything you... errr... get from $_GET is a string. It will not pose any security threat whatsoever unless you call eval() on it. Any string can be used as a PHP array key, and it will have no adverse effects whatsoever (although if you use a really long string, obviously this will impact memory usage).

It's not like SQL, where you are building code to be executed later - your PHP code has already been built and is executing, and the only way you can modify the way in which it executes at runtime is by calling eval() or include()/require().

EDIT

Thinking about it there are a couple of other ways, apart from eval() and include(), that this input could affect the operation of the script, and that is to use the supplied string to dynamically call a function/method, instantiate an object, or in variable variables/properties. So for example:

$userdata = $_GET['userdata'];

$userdata();
// ...or...
$obj->$userdata();
// ...or...
$obj = new $userdata();
// ...or...
$someval = ${'a_var_called_'.$userdata};
// ...or...
$someval = $obj->$userdata;

...would be a very bad idea, if you were to do it with sanitizing $userdata first.

However, for what you are doing, you do not need to worry about it.

泼猴你往哪里跑 2024-12-10 20:38:48

GETPOSTFILE 等收到的任何外部数据都应被视为肮脏的并进行适当的消毒。清理的方式和时间取决于数据的使用时间。如果要将其存储到数据库,则需要对其进行转义(以避免 SQL 注入。 请参阅 PDO 例如)。当基于用户数据(例如 eval)运行操作系统命令或尝试读取文件(例如读取 ../../../etc/passwd)。如果要向用户显示,则需要对其进行编码(以避免 html 注入。 请参阅 htmlspecialchars 例如)。

您不必按照上述使用方式来清理数据。事实上,您应该只为了存储而转义并为了显示而编码,否则就保留原始数据。当然,您可能想对数据执行自己的验证。例如,您可能希望 dirty_data 位于 [a, b, c] 列表中,如果没有,则将其回显给用户。然后你必须对其进行编码。

即使用户设法尝试读取无效的内存地址,任何众所周知的操作系统都不会出现问题。

Any external received from GET, POST, FILE, etc. should be treated as filthy and sanitized appropriately. How and when you sanitize depends on when the data is going to be used. If you are going to store it to the DB, it needs to be escaped (to avoid SQL Injection. See PDO for example). Escaping is also necessary when running an OS command based on user data such as eval or attempting to read a file (like reading ../../../etc/passwd). If it's going to be displayed back to the user, it needs to be encoded (to avoid html injection. See htmlspecialchars for example).

You don't have to sanitize data for the way you are using it above. In fact, you should only escape for storage and encode for display, but otherwise leave data raw. Of course, you may want to perform your own validation on the data. For example, you may want dirty_data to be in the list of [a, b, c] and if not echo it back to the user. Then you would have to encode it.

Any well-known OS is not going to have a problem even if the user managed to attempt to read an invalid memory address.

还给你自由 2024-12-10 20:38:48
  1. 据推测该数组的内容应该以这种方式公开访问,所以不会。
  2. 通过 array_key_exists() 运行它
  3. 可能至少有点糟糕。也许可以使用格式错误的多字节字符串来完成某些操作,或者可以在配置不当的服务器上触发某种溢出......但这纯粹是我的(无知的)猜测。
  1. Presumably this array's contents are meant to be publicly accessible in this way, so no.
  2. Run it through array_key_exists()
  3. Probably at least a little bad. Maybe there's something that could be done with a malformed multibyte string or something that could trigger some kind of overflow on a poorly-configured server... but that's pure (ignorant) speculation on my part.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文