以下安全措施是否足以使应用程序从脚本端安全?
这是我的脚本:
$filename=$_FILES['my_files']['name'];
$filetype=$_FILES['my_files']['type'];
$filename = strtolower($filename);
$filetype = strtolower($filetype);
//check if contain php and kill it
$pos = strpos($filename,'php');
if(!($pos === false)) { die('error'); }
//get the file ext
$file_ext = strrchr($filename, '.');
//check if its allowed or not
$whitelist = array(".jpg",".jpeg",".gif",".png");
if (!(in_array($file_ext, $whitelist)))
{
die('not allowed extension,please upload images only');
}
//check upload type
$pos = strpos($filetype,'image');
if($pos === false) { die('error 1'); }
$imageinfo = getimagesize($_FILES['my_files']['tmp_name']);
if($imageinfo['mime'] != 'image/gif' && $imageinfo['mime'] != 'image/jpeg'&& $imageinfo['mime'] != 'image/jpg'&& $imageinfo['mime'] != 'image/png') {
die('error 2');
}
//check double file type (image with comment)
if(substr_count($filetype, '/')>1){
die('error 3')
}
// upload to upload direcory
$uploaddir = 'upload/'.date("Ymd").'/' ;
if (file_exists($uploaddir)) { } else { mkdir( $uploaddir, 0777); }
//change the image name
$uploadfile = $uploaddir . md5(basename($_FILES['my_files']['name'])).$file_ext;
if (move_uploaded_file($_FILES['my_files']['tmp_name'], $uploadfile)) {
echo "<img id="upload_id" src="".$uploadfile.""><br />";
} else { echo "error"; }
复制代码
使用GD(或Imagick)重新处理图像并保存处理后的图像。 所有其他人对黑客来说只是有趣的无聊。
编辑:正如rr指出的,使用move_uploaded_file()
进行上传。
延迟编辑:顺便说一句,你想对你的上传文件夹非常严格。 这些地方是许多攻击发生的黑暗angular落之一。 这适用于任何types的上传和任何编程语言/服务器。 检查对于图像文件的安全testing,我可以考虑4级证券。 他们将是:
($file_info = getimagesize($_FILES['image_file']; $file_mime = $file_info['mime'];)
注意:加载整个图像会很慢。
还有一个非常重要的说法。 不要在浏览器中提供/上传任何可以解释为HTML的内容。
由于这些文件位于您的域名中,因此该HTML文档中包含的JavaScript将可以访问您的所有Cookie,从而实现某种XSS攻击。
使上传的内容仅在子域或其他域上可用。 这样cookies不会被访问。 这也是谷歌的性能提示之一:
developers.google.com/speed/docs/…
您也可以在$ _FILES ['my_files'] ['tmp_name']上运行“is_uploaded_file”。 见php.net/manual/en/f…
在上传目录中创build一个新的.htaccess文件并粘贴下面的代码:
php_flag engine 0 RemoveHandler .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml AddType application/x-httpd-php-source .phtml .php .php3 .php4 .php5 .php6 .phps .cgi .exe .pl .asp .aspx .shtml .shtm .fcgi .fpl .jsp .htm .html .wml
复制代码
只要确保重命名file upload+忘记检查types,内容等
我会重复一些我在相关问题上发表的内容。
您可以使用Fileinfo函数 (以前版本的PHP中的mime_content_type())检测内容types。
在旧的Mimetype扩展中,摘录了PHP手册,现在被Fileinfo取代:
本模块中的函数通过在文件中的特定位置查找某些魔法字节序列来尝试猜测文件的内容types和编码。 虽然这不是一个防弹的办法,启发式使用做了很好的工作。
getimagesize()
也可以做得很好,但是其他大部分的检查都是无稽之谈。 例如,为什么stringphp
不允许在文件名中。 你不打算在PHP脚本中包含图像文件,只是因为它的名称包含php
string,是吗?
当涉及到重新创build图像,在大多数情况下,它会提高安全性,直到你使用的图书馆不容易。
那么哪个PHP扩展最适合安全的图像重新创build? 我检查过CVE详细信息网站。 我认为适用的三人是那些扩展名:
从比较中我认为GD最适合,因为它具有最less的安全问题,而且相当老旧。 其中三个是至关重要的,但ImagMagick和Gmagick没有更好的performance… ImageMagick似乎是非常错误(至less在安全方面),所以我selectGmagick作为第二个选项。
如果安全是非常重要的使用数据库来保存文件名和重命名文件名,在这里你可以改变文件的扩展名为.myfile的东西,并制作一个PHP文件的头像发送图像。 PHP可以更安全,你可以像img标签一样使用它:
<img src="send_img.php?id=555" alt="">
上传之前,还请使用EXIF检查文件扩展名。
允许用户以PHP安全地上传文件的最简单答案是: 始终将文件保存在文档根目录之外。
例如:如果您的文档根目录是/home/example/public_html
,则将文件保存到/home/example/uploaded
。
使您的文件安全地脱离由您的Web服务器直接执行的范围,有几种方法仍然可以使访问者访问它们:
但是,如果您使用此列表中的选项1或3,并且您的应用程序中存在本地文件包含漏洞,则您的文件上载表单仍然可能成为攻击媒介 。
当用户上传图片时,保持网站安全的最佳方法是执行以下步骤:
对于图像文件,您也可以在重命名后更改文件权限,以确保它永远不会执行(rw-r – r–)
我正在使用php-upload-script为每个上传的文件创build一个新的随机4字节数,然后用这4个字节对文件内容进行异或(必要时重复它们),最后将4字节保存到文件之前。
下载时,必须将4个字节再次从文件中删除,内容将与它们再次异或,并将结果发送给客户端。
这样,我可以肯定的是,我保存在服务器上的文件将不可执行或对任何应用程序有任何潜在的含义。 另外我不需要任何额外的数据库来存储文件名。
这里是我使用的代码:
上传:
<?php $outputfilename = $_POST['filename']; $inputfile = $_FILES["myblob"]["tmp_name"]; $tempfilename="temp.tmp"; if( move_uploaded_file($inputfile, $tempfilename) ) { $XORstring = random_bytes(4); $tempfile=fopen($tempfilename, "r"); $outputfile=fopen($outputfilename, "w+"); flock($outputfilename, LOCK_EX); fwrite($outputfilename, $XORbytes1); while ( $buffer = fread($tempfile, 4) ) { $buffer = $buffer ^ $XORstring; fwrite($outputfilename, $buffer); } flock($outputfilename, LOCK_UN); fclose($tempfile); fclose($outputfile); unlink($tempfilename); } exit(0); ?>
下载:
<?php $inputfilename = $_POST['filename']; $tempfilename = "temp.tmp"; $inputfile=fopen($inputfilename, "r"); $tempfile=fopen($tempfilename, "w+"); flock($tempfile, LOCK_EX); $XORstring = fread($inputfile, 4); while ( $buffer = fread($inputfile, 4) ) { $buffer = $buffer ^ $XORstring; fwrite($tempfile, $buffer); } flock($tempfile, LOCK_UN); fclose($inputfile); fclose($tempfile); readfile($tempfile); unlink($tempfile); exit(0); ?>
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。