PHP安全上传的思路

转载:http://hi.baidu.com/mu0641/blog/item/5ea86c8139f573d8bd3e1e73.html

首先要建立一个文件夹和两个文件,具体如下:

File              —————— 文件夹,用于存放上传的文件。
choose.htm  —————— htm文件,用于选择上传的文件。
upload.php   —————— php文件,用于处理上传的文件。

第一步:建立 File 文件夹。

第二步:建立 choose.htm 文件,代码如下:
____________________________________________________________________________________________________________

<form action="upload.php" method="post" enctype="multipart/form-data">
     <input type="hidden" name="MAX_FLIE_SIZE" value="1000000" />
上传此文件:
     <input name="userfile" type="file" id="userfile" />
     <input type="submit" name="Submit" value="上传" />
</form>
____________________________________________________________________________________________________________

第三步:建立 upload.php 文件,代码如下:
____________________________________________________________________________________________________________
<?php

//上传文件错误判定
if($_FILES['userfile']['error']>0)
{
        echo '错误:'
       
        switch($_FILES['userfile']['error'])
        {
                case 1: echo '文件尺寸超过允许的最大上传限度!' break;
                case 2: echo '文件尺寸超过允许的最大上传限度!' break;
                case 3: echo '只有部分文件被上传!' break;
                case 4: echo '没有任何文件被上传!' break;
        }
        exit;
}

//上传文件格式判定
if($_FILES['userfile']['type'] !='text/plain')
{
        echo '错误:非法文件格式!'
        exit;
}

//设置文件保存路径
$upfile = './File/' . $_FILES['userfile']['name'];

if(is_uploaded_file($_FILES['userfile']['tmp_name']))
{
        if(!move_uploaded_file($_FILES['userfile']['tmp_name'],$upfile))
        {
                echo '错误:没有将文件移动到指定目录!'
                exit;
        }
}
else
{
        echo '错误:可能文件上传被攻击!文件名:'
        echo $_FILES['userfile']['name'];
}

echo '文件上传成功!'

//格式化上传的文件
$fp = fopen($upfile,'r');
$contents = fread($fp,filesize($upfile));
fclose($fp);

$contents = strip_tags($contents);
$fp = fopen($upfile,'w');
fwrite($fp,$contents);
fclose($fp);

//显示上传文件内容
echo '上传文件的内容为:'
echo $contents;
?>
____________________________________________________________________________________________________________

测试一下:

  1、建立一个 123.txt 文件,里面输入一些纯文本字符,比如 abc,上传成功!

  2、我们再来试看其他后缀名,如.exe,.php,.htm之类的,只要非txt,就将导致失败!

  3、把任意一个大于1M的文件名改为123.txt并上传,我们将发现超过限制大小的文件将导致上传失败!

  4、将123.txt的内容改掉,删除所有内容,输入 <html>HTML code</html>,保存并上传,我们会发现上传失败!

  5、将123.txt的内容改掉,删除所有内容,输入 <?php echo'PHP code' ?>保存并上传,我们会发现 File 文件夹中有一个0字节的,没有任何内容的123.txt文件!

相关说明:

  首先我们使用了检测MIME类型的方法,因此如果希望通过传一个错误的类型来蒙混过关,这对那些有恶意的用户来说还是很难的,但这只是错误检查,并非安全性检查,但起码这比简单的后缀名过滤的上传方法要安全一些。

  之后我们检查要打开的文件是否已经真的被上传而且不是一个本地文件,因为有的恶意软件能够让侵入者修改文件上传脚本,使此脚本可以将本地文件当成上载的文件进行处理。我们使用 is_uploaded_file() 和 move_uploaded_file() 这两个函数来确保所处理的文件已经被上传,而非一个本地文件。

  最后,我们打开这个文件,使用 strip_tags() 函数清除任何 HTML 或 PHP 标记,防止通过重重错误检查的 123.txt 仍然含有恶意代码。最后保存文件,直到这里,才真正的完成了整个上传工作。

补充说明:

  有可能某些人看客对 upload.php 中的 switch 条件句有些模糊,不知道为什么要这么写,我在这里简单的补充说明一下:

  $_FILES['userfile']['error']

  值为0时:UPLOAD_ERROR_OK (表示没有发生任何错误)
  值为1时:UPLOAD_ERR_INI_SIZE (表示上传文件的大小超过了PHP配置文件的最大值)
  值为2时:UPLOAD_ERR_FORM_SIZE (表示上传文件的大小超过了HTML表单中指定的最大值)
  值为3时:UPLOAD_ERR_PARTIAL (表示文件只有一部分被上传)
  值为4时:UPLOAD_ERR_NO_FILE (表示没有任何的文件被上传)

  好,那就到这里结束吧。再次重声,这仅仅是个很浅的思路,如果要真的运用到开发中去,还需要进行很多修改很完善,这个就得靠大家自己去研究了。还是那句话:有什么不足的地方,欢迎各位指正,让大家见笑了。

  写这篇文章最根本的目的:希望能给需要的人一些微薄的帮助。我PHP也是自学的,知道其中的辛苦,所以自己虽然很菜菜,但是也要懂得去分享,也希望每个人都能这样:共同学习、共同进步

    A+
发布日期:2009年10月10日  所属分类:未分类

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: