我将转换后的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更好的方法吗?
参考文献:
- 是否将Base64字符串转换为图像文件
- 文件的PHP数据URI
写入文件后,将文件名馈送到imagecreatefrompng()
或任何其他文件格式。如果它返回false
,则它实际上不是图像。
除此之外,还要弄清楚如何在发送应用程序中将POST
请求格式化为多部分,PHP将做跑腿工作,将其与文件名和mime类型等相关信息一起放入$_FILES
超全局。不过,这将无助于防止任何类型的代码注入。
通过给文件一个用户无法影响的自动生成的名称,您已经避免了最糟糕的问题。
从理论上讲,这种方式应该不可能破解你的服务器,因为你的服务器不应该在PNG文件中运行任何代码。不幸的是,这样做很容易误解nginx。正确的解决方案当然是正确配置nginx了。您可以尝试进行一些过滤(例如检测<?php
,但这有误报的风险,即合法图像被拒绝)。我可能会在文档中注明,在nginx上安装软件的人应该真正按照服务器提供的说明进行操作,并检查是否存在此问题,而不必进一步担心。请注意,可以创建一个包含PHP代码的完全有效的PNG文件,因此简单地检查该文件是否为有效的图像在这里没有帮助。
现在,针对客户的攻击。您的服务器将(希望)为具有正确MIME类型的文件提供服务。这将阻止浏览器将其作为代码运行。不幸的是,某些浏览器(也称为"Internet Explorer")是愚蠢的,并试图猜测文件类型。这不会直接损害您的服务器,但会导致使用这些浏览器的用户的用户帐户受到损害。因此,您可能需要检查文件类型。如果可以的话,为所有文件提供nosniff标头(例如,通过设置相应的htaccess或在设置标头后通过fpassthrough提供)。
通过加载并重新保存图像,您可以(或多或少)确保图像中的任何"讨厌"的东西都消失了。另一方面,如果有人在你的图像库中发现了可利用的漏洞,他们可以入侵你的服务器,所以这并非没有风险。
$_POST
’ed数据(或者实际上任何数据)都没有安全问题。这只是数据,您可以安全地将其保存在服务器中的文件中。
当您以一种不安全且有时很简单的方式处理数据时,问题就来了,可能是使用eval()
或echo
,它直接到web浏览器,而不需要转义或标记删除等。
所以,如果你的问题是安全,那你就找错地方了。
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);