如何使用 PHP 安全地将 JSON 数据写入文件

Posted

技术标签:

【中文标题】如何使用 PHP 安全地将 JSON 数据写入文件【英文标题】:How to safely write JSON data to file using PHP 【发布时间】:2011-09-05 10:26:13 【问题描述】:

我有用于编辑图像的 html 表单。所有数据都存储在 JSON 中。当我更改当前图像时,我想通过 php 脚本将更改保存到文本文件中。如果我返回上一个图像,这个配置将再次从这个文件发送到表单。

我的问题是:

如何安全地写入/读取此类数据。在哪里以及如何有效地检查数据以防止某些 JS/PHP 代码注入?

我在下面附上了一些概念代码:

javascript(使用 jQuery):

// Writing
$.ajax(
    global: false,
    type: "POST",
    cache: false,
    dataType: "json",
    data: (
        action: 'write',
        config: JavaScriptJSON_Obj
    ),
    url: 'read-write.php'
);

// Reading
$.ajax(
    global: false,
    type: "POST",
    cache: false,
    dataType: "json",
    data: (
        action: 'read'
    ),
    url: 'read-write.php',
    success: function(data)
        JavaScriptJSON_Obj = data;
    
);

PHP 示例(read-write.php):

switch ($_REQUEST['action']) 
    case 'write':
        file_put_contents('config.txt', $_REQUEST['config']);
        break;
    case 'read':
        $s = file_get_contents('config.txt');
        echo json_encode($s);
        break;

【问题讨论】:

取决于我会说的 JavascriptJSON_Obj 正在做什么。它可以为潜在的远程文件包括打开大门。 只需将其保存为文本数据,然后将其加载为文本数据。没有什么不安全的。您应该考虑的唯一一件事 - 访问权限。您应该将此信息存储在无法通过浏览器直接访问的目录中(这就是为什么您有read-write.php 用于阅读 config.txt)。您也可以考虑将这些数据存储在 DB 中。 【参考方案1】:

首先:JSON 不是 JavaScript,反之亦然。而且 JSON 甚至不是 JavaScript 的正确子集。

此外,由于您既不会将某些用户输入解释为 PHP,也不会将某些输出解释为 JavaScript,因此无需担心。但不要忘记正确指定输出:

header('Content-Type: application/json;charset=utf-8');
$s = file_get_contents('config.txt');
echo json_encode($s);

【讨论】:

我从来没有说过 JSON 是 JavaScript。我知道区别。这几乎就像说 PHP 是一个数组 :) 好吧,在某些情况下它可能是不安全的。例如,数据可能存储在名为$_SERVER['DOCUMENT_ROOT'] . '/data.php' 的文件中,该文件可能通过访问http://example.com/data.php 来执行。但是,用户必须知道文件的名称,并且该文件必须可由服务器执行(.txt 文件通常不是可执行)。【参考方案2】:

我总是会检查返回的数据,看看它是否是我期望的格式。假设您正在保存图像...使用 MIME 检查等检查以确保它是图像。如果您只是将数据按原样保存在服务器上,您可能会为一些潜在的安全问题打开大门。

如果您的意思是只保存有关查看了哪些图像的数据,则根据访问和使用该数据的方式和位置,它仍然可能会造成问题。所以如果你除了一个整数,仅此而已,请确保你接收和保存的数据是一个整数,仅此而已。

【讨论】:

据我所知,检查 MIME 与根本不检查一样不安全。如果要确保“图像”确实是图像,则应检查数据的结构,而不是一些表示文件扩展名的文本信息。 不,当然... MIME 只是第一步检查。如果关闭,那么它显然不是图像。但是你可以尝试实际加载图像以确保它是有效的图像。 OP 正在尝试存储 JSON 数据,而不是图像或整数。 All data is stored in JSON,JSON 容器中实际数据的格式在安全方面可能仍然很重要并受到重视。 真的可以在 JSON 对象中存储二进制图像吗?【参考方案3】:

除了安全问题之外,您的代码的问题在于它不起作用。您必须序列化数据,或将其编码为 json,然后再将其存储在文件中,即。像这样:

switch ($_REQUEST['action']) 
    case 'write':
        file_put_contents('config.txt', json_encode($_REQUEST['config']));
        break;
    case 'read':
        readfile('config.txt');
        break;

序列化的工作方式如下:

switch ($_REQUEST['action']) 
    case 'write':
        file_put_contents('config.txt', serialize($_REQUEST['config']));
        break;
    case 'read':
        $data = unserialize(file_get_contents('config.txt'));
        echo json_encode($data);
        break;

只要确保读取/写入的路径正确,此代码就不存在代码注入问题。唯一的潜在问题是您是否可以选择要使用的文件(而不是将“config.txt”硬编码到代码中)。然后你必须验证以确保文件在给定的目录等中。

【讨论】:

@Jacob,感谢您指出这一点。就我而言,不需要序列化。我将只存储简单的数据,如文本和数字。 哦,那我误会了。我认为JavaScriptJSON_Obj 是任意 javascript 对象或数组的占位符。 好吧,其实在我的JS脚本下,JavaScriptJSON_Obj是一个对象,不过只是为了方便而已。

以上是关于如何使用 PHP 安全地将 JSON 数据写入文件的主要内容,如果未能解决你的问题,请参考以下文章

在将新文件主动写入源目录时,如何安全地将文件导入 ssis 中的 sql server?

php,JavaScript 如何读取并修改json文件?

如何安全地将 MySQL 数据库与使用 PHP 的网页链接和使用?

sh 使用find with print0安全地将带有任何合法字符的文件名或文件路径写入数组并迭代它们。

如何使用 XSL 转义 XML 内容以安全地将其输出为 JSON?

安全地将 JSON 字符串转换为对象