PHP,通过POST传递数组

28

通过POST发送数组,哪种方式最安全?

foreach ($id as $array)
{
<input type="hidden" name="prova[]" value="<?php echo $array; ?>"/>
}
<input type="submit" name="submit"/>
或者使用implode()创建一个单一的变量,传递这个变量,然后使用explode()将值取回到一个新数组中?

1
你认为通过POST传递数组存在哪些固有的不安全因素?它只是数据。 - Grant Thomas
2
我通常喜欢使用 json_encode() 将对象转换为 JSON 字符串。然后再使用带有 true 选项的 json_decode() 将其还原回来。 - phpisuber01
2
你在这个上下文中使用“安全”一词毫无意义。你担心什么? - Alex Howansky
2
保护商店并不意味着我们一直锁着商店,而是要通过摄像头监视顾客。 - NullPoiиteя
1
请详细说明这个问题。为什么需要传递数组?你要寻找什么“安全性”?数组包含什么内容?应用程序的上下文是什么?现在的描述非常模糊,不会得到一个好的答案... - ircmaxell
显示剩余4条评论
5个回答

33

编辑 如果您询问有关安全性的问题,请参见我在底部附加的补充说明 编辑

PHP提供了一个serialize函数,专门用于此目的。将一个数组传递给它,它会给你一个字符串表示。当您想要将其转换回数组时,只需使用unserialize函数即可。

$data = array('one'=>1, 'two'=>2, 'three'=>33);
$dataString = serialize($data);
//send elsewhere
$data = unserialize($dataString);

这通常被懒惰的程序员用来将数据保存到数据库中。不建议使用,但作为一个快速/肮脏的解决方案是有效的。

补充说明

我以为你要找的是可靠地发送数据的方法,而不是“安全”的方法。无论你如何传递数据,如果它经过用户系统,你都不能完全信任它。通常应该将它存储在服务器上某个地方,并使用凭据(cookie、会话、密码等)来查找它。


如果我现在遇到这个需求,我可能会尝试使用某种形式的加密签名来验证数据。 - MrGlass

20

http://php.net/manual/zh/reserved.variables.post.php

第一条评论已经回答了这个问题。

<form ....>
<input name="person[0][first_name]" value="john" />
<input name="person[0][last_name]" value="smith" />
...
<input name="person[1][first_name]" value="jane" />
<input name="person[1][last_name]" value="jones" />
</form>

<?php
var_dump($_POST['person']);

array (
0 => array('first_name'=>'john','last_name'=>'smith'),
1 => array('first_name'=>'jane','last_name'=>'jones'),
)
?>

name标签可以作为数组使用。


16

你可以将它放在会话中:

session_start();
$_SESSION['array_name'] = $array_name;

或者如果你想通过表单发送它,你可以将其序列化:

<input type='hidden' name='input_name' value="<?php echo htmlentities(serialize($array_name)); ?>" />

$passed_array = unserialize($_POST['input_name']);
注意,如果要使用序列化数组,请使用POST作为表单的传输方式,因为GET有一个大小限制约为1024个字符。
我会尽可能地使用会话。

2
SESSION比将数据存储在输入类型中更安全,因为SESSION是服务器端的,所以用户无法更改它。我同意你的看法@laxonline - Hiren Kubavat
我这里有一个问题。如果表单中有成千上万个输入,这个方法还适用吗? - anujeet

10

有两件事需要考虑:用户可以修改表单,您需要防范跨站脚本攻击(XSS)。

XSS

XSS是指当用户将HTML输入到他们的输入中时。例如,如果用户提交了这个值,会怎么样?:

" /><script type="text/javascript" src="http://example.com/malice.js"></script><input value="

这段内容需要写入你的表格中,格式如下:
<input type="hidden" name="prova[]" value="" /><script type="text/javascript" src="http://example.com/malice.js"></script><input value=""/>

保护自己免受此类攻击的最佳方式是使用 htmlspecialchars() 来确保您的输入安全。它会将诸如 < 的字符编码为 &lt;。例如:

<input type="hidden" name="prova[]" value="<?php echo htmlspecialchars($array); ?>"/>

您可以在此处了解更多有关XSS的信息:https://www.owasp.org/index.php/XSS

表单修改

如果我在您的网站上,我可以使用Chrome开发者工具或Firebug来修改您页面的HTML。根据您的表单功能,这可能会被用于恶意目的。

例如,我可以添加额外的值到您的数组中,或者添加不属于该数组的值。如果这是一个文件系统管理器,则我可以添加不存在的文件或包含敏感信息的文件(例如:将myfile.jpg替换为../index.php../db-connect.php)。

简而言之,您始终需要检查输入内容以确保其合理,并且只在表单中使用安全的输入内容。文件ID(数字)是安全的,因为您可以检查该数字是否存在,然后从数据库中提取文件名(这假设您的数据库包含经过验证的输入)。文件名称不安全,原因如上所述。您必须重新验证文件名,否则我可以将其更改为任何内容。


1
所有用户输入都应该应用htmlspecialchars()。StackOverflow可能会对您的用户名执行类似操作:它随处可见,因此不应该是恶意HTML。用户可以修改他们正在查看的任何HTML。我曾经这样做来伪造Google奥林匹克游戏中的高分:https://sphotos-b.xx.fbcdn.net/hphotos-ash4/418275_485985401412972_1427008375_n.jpg 表单很特殊,因为它们包含用户发送回服务器的输入。您需要检查他们发送给您的每个输入,以确保它有意义,否则人们将会黑掉您的网站。 - Chris

8

如果您在服务器(PHP)端已经有这个数据,为什么还要通过邮件发送它?

为什么不将数组保存到 $_SESSION 变量中,以便在表单提交时使用它,这可能会使它更加“安全”,因为客户端无法通过编辑源代码来更改变量。

这完全取决于您想要做什么。


1
会话和POST数据是两个非常不同的东西,应该用于不同的数据。说“只需将数组保存到会话变量中”忽略了它们之间的差异。这可能是正确的,也可能是错误的。从提供的问题中,我们无法确定... - ircmaxell
我也考虑过这个问题,但如果我忘记清除$_SESSION变量,或者发生了什么阻止它的事情,那将是一个问题。 - Mewster
2
@user1722791 如果客户端更改了您的隐藏输入中的值,您也可能会出现问题。 - Naftali
阅读了所有内容后,似乎$_SESSION是最可取的。我会尝试使用它。 - Mewster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接