将base64字符串安全地保存到php中的文件中

时间:2013-12-13 18:38:28

标签: php security

我将转换后的base64编码字符串存储为图像文件。我必须把文件作为字符串。

目前我通过POST获取字符串,我担心有人发布了他们可能用来破坏服务器的东西。我的问题是如何确保它尽可能安全。

这就是目前的工作方式(总结):

$encodedString = $_POST['image'];
// Strip the crud from the front of the string [1]
$encodedString = substr($encodedString,strpos($encodedString,",")+1);
// Cleanup File [2]
$encodedString = str_replace(' ','+',$encodedString);
// Decode string
$decoded = base64_decode($encodedString);
// Save File
file_put_contents(uniqid().'.png',$decoded);

接下来我应该做些什么来确保某人没有/没有将一些恶意代码注入到post变量中?

或者有比POST更好的方法吗?

参考文献:

  1. Convert Base64 string to an image file?
  2. PHP Data-URI to file

4 个答案:

答案 0 :(得分:2)

编写文件后,将文件名提供给imagecreatefrompng()或其他任何文件格式。如果它返回false,那么它实际上不是图像。

除此之外,弄清楚如何将POST请求格式化为发送应用程序中的多部分,PHP将做一些工作,将其与文件名和文件等相关信息一起放入$_FILES超全局。哑剧型。但是,这无助于防止任何类型的代码注入。

答案 1 :(得分:1)

通过为文件提供用户无法影响的自动生成的名称,您已经避免了最严重的问题。

理论上,不应该以这种方式破解您的服务器,因为您的服务器不应该在PNG文件中运行任何代码。不幸的是,misconfigure nginx to do so真的很容易。当然,正确的解决方案是正确配置nginx。您可以尝试进行一些过滤(例如检测<?php,但这可能会产生误报,即合法图像被拒绝)。我可能会在文档中注明,在nginx上安装软件的人应该真的按照服务器提供的说明检查这个问题,并且不用担心它。请注意,可以创建一个包含PHP代码的完全有效的PNG文件,因此只需检查该文件是否为有效图像就没有用。

现在,对客户进行攻击。您的服务器(希望)将使用正确的MIME类型提供服务。这应该阻止浏览器将其作为代码运行。不幸的是,某些浏览器(也称为“Internet Explorer”)是愚蠢的,并试图猜测文件类型。这不会直接损害您的服务器,但会导致使用这些浏览器的用户的用户帐户受到损害。因此,您可能需要检查文件类型。如果可以,请使用nosniff标头提供所有文件(例如,通过设置相应的htaccess或在设置标头后通过fpassthru提供服务)。

通过加载和重新保存图像,您可以(或多或少)确保图像中任何“讨厌”的内容都消失了。另一方面,如果有人在您的图像库中发现了可利用的错误,他们可以破解您的服务器,因此它并非没有风险。

答案 2 :(得分:0)

$_POST'ed数据(或任何数据,实际上)都没有安全问题。它只是数据,您可以安全地将其保存在服务器的文件中。

当您以不安全且有时简单的方式处理该数据时,问题就出现了,可能是eval(),或者echo它直接在网络浏览器上逃避或标记删除等等。

因此,如果您的问题是安全问题,那么您就是在寻找错误的地方。

答案 3 :(得分:0)

function get_base64_file_ext($base64ImageString)
{
    if(stristr($base64ImageString, 'image/png'))
        return 'png';
    if(stristr($base64ImageString, 'image/gif'))
        return 'gif';
    else
        return 'jpg';
}
function base64_to_file($base64ImageString)
{
    $data = explode(',', $base64ImageString);
    return base64_decode($data[1]); 
}
function save_base64_to_file($path, $filename, $base64ImageString)
{
    if(!stristr($base64ImageString, 'image/'))
        return 'No image found';
    $file_contents = base64_to_file($base64ImageString);
    //$file_contents = strip_tags($file_contents);

    $save_file = $path.$filename.'.'.get_base64_file_ext($base64ImageString);
    if(file_put_contents($save_file,$file_contents))
        return 'image saved successfully to '.$save_file;
    else
        return 'error while writing a file';
}

用法:

echo save_base64_to_file('/home/username/public_html/images/', 'my_image_file', $base64ImageString);