【100分】如何防范上传的图片包含恶意代码???求高手!!!

丰云 2013-01-07 02:18:09
如题,
公司要实现一个鉴证图片上传的功能,
但要防止有人在图片中附加恶意代码,
目前有一些基本的想法,
但感觉还是不够可靠,
有没有人做过这个功能的?
赐教一二啊
...全文
922 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
Delta 2013-01-08
  • 打赏
  • 举报
回复
来学习过了,还真没遇到过这些问题啊
heycoder 2013-01-07
  • 打赏
  • 举报
回复
引用 3 楼 foren_whb 的回复:
引用 1 楼 heycoder 的回复:是为了防止php asp恶意程序伪装成图片么? 是的, 网上关于这块的资料很少, 一般都是从图片流中过滤关键字, 问题是我不知道这些关键字是否真的能把木马神马的都过滤掉。。。。
1.如果可以的话,服务器不要安装asp,php环境,这样即便有了asp木马又如何? 2.其他的杀软我是不知道。反正这种图片对于卡巴来说。连保存的机会都没有。。。
丰云 2013-01-07
  • 打赏
  • 举报
回复
引用 14 楼 free_wang 的回复:
你服务器的杀毒软件是摆设吗
这个。。。没想到。。。。
股神 2013-01-07
  • 打赏
  • 举报
回复
你服务器的杀毒软件是摆设吗
NqIceCoffee 2013-01-07
  • 打赏
  • 举报
回复
引用 12 楼 foren_whb 的回复:
但是菜鸟们下载图片后,双击打开。。。。就悲剧了, 所以这个办法只能保护图片服务器的安全, 还不够完美啊。。。。
这个只能通过你的业务去实现了吧 上传后,通过后台的服务去验证图片的真实性,不是真实的图片,不让下载
丰云 2013-01-07
  • 打赏
  • 举报
回复
引用 10 楼 KarasCanvas 的回复:
关键是做到让他们上传了也没办法运行。
但是菜鸟们下载图片后,双击打开。。。。就悲剧了, 所以这个办法只能保护图片服务器的安全, 还不够完美啊。。。。
joyhen 2013-01-07
  • 打赏
  • 举报
回复
/// <summary>
    /// 文件编号
    /// </summary>
    public enum FileExtension
    {
        JPG = 255216,
        GIF = 7173,
        BMP = 6677,
        PNG = 13780,
        //RAR = 8297
        // 255216 jpg;    
        // 7173 gif;    
        // 6677 bmp,    
        // 13780 png;    
        // 7790 exe dll,    
        // 8297 rar    
        // 6063 xml    
        // 6033 html    
        // 239187 aspx    

        // 117115 cs    
        // 119105 js    
        // 210187 txt    
        //255254 sql    
    }
    public static class FileValidation
    {

        /// <summary>
        /// 是否允许
        /// </summary>
        /// <param name="oFile"></param>
        /// <param name="fileEx"></param>
        /// <returns></returns>
        public static bool IsAllowedExtension(HttpPostedFile oFile, FileExtension[] fileEx)
        {
            int fileLen = oFile.ContentLength;

            byte[] imgArray = new byte[fileLen];
            oFile.InputStream.Read(imgArray, 0, fileLen);
            MemoryStream ms = new MemoryStream(imgArray);
            System.IO.BinaryReader br = new System.IO.BinaryReader(ms);
            string fileclass = "";
            byte buffer;
            try
            {
                buffer = br.ReadByte();
                fileclass = buffer.ToString();
                buffer = br.ReadByte();
                fileclass += buffer.ToString();
            }
            catch { }
            br.Close();
            ms.Close();
            foreach (FileExtension fe in fileEx)
            {
                if (Int32.Parse(fileclass) == (int)fe)
                    return true;
            }
            return false;
        }
        /// <summary>
        /// 上传前的图片是否可靠
        /// </summary>
        /// <param name="oFile"></param>
        /// <returns></returns>
        public static bool IsSecureUploadPhoto(HttpPostedFile oFile)
        {
            bool isPhoto = false;
            string fileExtension = System.IO.Path.GetExtension(oFile.FileName).ToLower();
            string[] allowedExtensions = { ".gif", ".png", ".jpeg", ".jpg", ".bmp" };
            for (int i = 0; i < allowedExtensions.Length; i++)
            {
                if (fileExtension == allowedExtensions[i])
                {
                    isPhoto = true;
                    break;
                }
            }
            if (!isPhoto) return true;//不是图片,既然允许上传,那就不检测了
            FileExtension[] fe = {FileExtension.BMP,
                                     FileExtension.GIF,
                                     FileExtension.JPG,
                                     FileExtension.PNG
                                 };
            if (IsAllowedExtension(oFile, fe))
                return true;
            else
                return false;
        }
        /// <summary>
        /// 上传后的图片是否安全
        /// </summary>
        /// <param name="photoFile">物理地址</param>
        /// <returns></returns>
        public static bool IsSecureUpfilePhoto(string photoFile)
        {
            bool isPhoto = false;
            string Img = "Yes";
            string fileExtension = System.IO.Path.GetExtension(photoFile).ToLower();
            string[] allowedExtensions = { ".gif", ".png", ".jpeg", ".jpg", ".bmp" };
            for (int i = 0; i < allowedExtensions.Length; i++)
            {
                if (fileExtension == allowedExtensions[i])
                {
                    isPhoto = true;
                    break;
                }
            }
            if (!isPhoto) return true;//不是图片,既然允许上传,那就不检测了
            StreamReader sr = new StreamReader(photoFile, System.Text.Encoding.Default);
            string strContent = sr.ReadToEnd();
            sr.Close();
            string str = "request|<script|.getfolder|.createfolder|.deletefolder|.createdirectory|.deletedirectory|.saveas|wscript.shell|script.encode|server.|.createobject|execute|activexobject|language=";
            foreach (string s in str.Split('|'))
                if (strContent.ToLower().IndexOf(s) != -1)
                {
                    File.Delete(photoFile);
                    Img = "No";
                    break;
                }
            return (Img == "Yes");
        }
    }
种草德鲁伊 2013-01-07
  • 打赏
  • 举报
回复
关键是做到让他们上传了也没办法运行。
丰云 2013-01-07
  • 打赏
  • 举报
回复
引用 7 楼 NqIceCoffee 的回复:
上传过程肯定是不会执行脚本的 楼主以前不是做B/S程序的吧
谢谢,你给的这些,是判断文件类型的方法, 不是我的问题所在啊, 我要的是检测图片流中附加恶意代码的过滤与拦截
conan8126 2013-01-07
  • 打赏
  • 举报
回复
上传文件检测类型到目前为止我只看到过两种,第一种是检测文件的后缀名;第二种是检测文件的头部编码,不同类型文件的头部编码是不一样的(不知道这样说恰当不,有错误希望大家指出),比如255216是jpg;7173是gif;6677是BMP,13780是PNG;7790是exe,8297是rar...这篇文章代码多有参考网络. 前台文件:两种方法的前台文件是一样的.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>无标题页</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="btn_upload" runat="server" OnClick="btn_upload_Click" Text="上传" />
</div>
</form>
</body>
</html>
后台文件: 第一种方法:安全性相对第二种低,把文本文件1.txt改成1.jpg照样可以上传,但其实现方法容易理解,实现也简单,所以网上很多还是采取这种方法.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page 
{
   protected void Page_Load(object sender, EventArgs e)
  {

  }
  protected void btn_upload_Click(object sender, EventArgs e)
  {
     Boolean fileOk = false;
     string path = Server.MapPath("~/images/");
     //判断是否已经选取文件
     if (FileUpload1.HasFile)
     {
        //取得文件的扩展名,并转换成小写
        string fileExtension = System.IO.Path.GetExtension     (FileUpload1.FileName).ToLower();
        //限定只能上传jpg和gif图片
        string[] allowExtension = { ".jpg", ".gif" };
        //对上传的文件的类型进行一个个匹对
        for (int i = 0; i < allowExtension.Length; i++)
        {
            if (fileExtension == allowExtension[i])
            {
                fileOk = true;
                break;
            }
        }
    }
    else
   {
      Response.Write("<script>alert(’你还没有选择文件’);</script>");
   }
   //如果扩展名符合条件,则上传
  if (fileOk)
  {
     FileUpload1.PostedFile.SaveAs(path + FileUpload1.FileName);
     Response.Write("<script>alert(’上传成功’);</script>");
   }
   else
   {
   }
  }
}
第二种方法,可以实现真正意义上的文件类型判断,推荐使用这种方法.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page 
{
  protected void Page_Load(object sender, EventArgs e)
  {

  }
  protected void btn_upload_Click(object sender, EventArgs e)
  {
    try
    {
       //判断是否已经选取文件
       if (FileUpload1.HasFile)
       {
          if (IsAllowedExtension(FileUpload1))
          {
              string path = Server.MapPath("~/images/");
              FileUpload1.PostedFile.SaveAs(path + FileUpload1.FileName);
              Response.Write("<script>alert(’上传成功’);</script>");
           }
           else
          {
              Response.Write("<script>alert(’您只能上传jpg或者gif图片’);</script>");
           }

       }
       else
       {
           Response.Write("<script>alert(’你还没有选择文件’);</script>");
        }
   }
   catch (Exception error)
   {
      Response.Write(error.ToString());
   }
}
//真正判断文件类型的关键函数
public static bool IsAllowedExtension(FileUpload hifile)
{
   System.IO.FileStream fs = new System.IO.FileStream(hifile.PostedFile.FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
   System.IO.BinaryReader r = new System.IO.BinaryReader(fs);
   string fileclass = "";
   byte buffer;
  try
  {
     buffer = r.ReadByte();
     fileclass = buffer.ToString();
     buffer = r.ReadByte();
     fileclass += buffer.ToString();

  }
  catch
  {

  }
  r.Close();
  fs.Close();
  if (fileclass == "255216" || fileclass == "7173")//说明255216是jpg;7173是gif;6677是BMP,13780是PNG;7790是exe,8297是rar
  {
     return true;
   }
   else
  {
     return false;
  }
}
}
NqIceCoffee 2013-01-07
  • 打赏
  • 举报
回复
上传过程肯定是不会执行脚本的 楼主以前不是做B/S程序的吧
丰云 2013-01-07
  • 打赏
  • 举报
回复
引用 5 楼 NqIceCoffee 的回复:
引用 3 楼 foren_whb 的回复:是的, 网上关于这块的资料很少, 一般都是从图片流中过滤关键字, 问题是我不知道这些关键字是否真的能把木马神马的都过滤掉。。。。 那就把上传的目录的执行权限拿掉,一般情况下是没问题的
上传过程中, 附加的代码也可以直接执行的吧。。。。
NqIceCoffee 2013-01-07
  • 打赏
  • 举报
回复
引用 3 楼 foren_whb 的回复:
是的, 网上关于这块的资料很少, 一般都是从图片流中过滤关键字, 问题是我不知道这些关键字是否真的能把木马神马的都过滤掉。。。。
那就把上传的目录的执行权限拿掉,一般情况下是没问题的
丰云 2013-01-07
  • 打赏
  • 举报
回复
引用 2 楼 NqIceCoffee 的回复:
后缀可以随意改 如果真的要去验证是否是真正的图片,感觉上最终得去验证图片的格式是否合法 这样肯定费劲 以前为了防止这样的事情,我一般不去计较他上传的是什么 不给它上传的目录执行的权限一般情况下就比较安全了 不知道楼主是更关注安全,还是更关注图片的真实性
当然是更关注安全。。。。 图片的合法有效性, 有专门的人去鉴别, 我只管上传。。。。。
丰云 2013-01-07
  • 打赏
  • 举报
回复
引用 1 楼 heycoder 的回复:
是为了防止php asp恶意程序伪装成图片么?
是的, 网上关于这块的资料很少, 一般都是从图片流中过滤关键字, 问题是我不知道这些关键字是否真的能把木马神马的都过滤掉。。。。
NqIceCoffee 2013-01-07
  • 打赏
  • 举报
回复
后缀可以随意改 如果真的要去验证是否是真正的图片,感觉上最终得去验证图片的格式是否合法 这样肯定费劲 以前为了防止这样的事情,我一般不去计较他上传的是什么 不给它上传的目录执行的权限一般情况下就比较安全了 不知道楼主是更关注安全,还是更关注图片的真实性
heycoder 2013-01-07
  • 打赏
  • 举报
回复
是为了防止php asp恶意程序伪装成图片么?
环境要: Discuz! 兼容 PHP 4.0.6, MySQL 3.23, PostgreSQL 7.1 以上各版本和各种操作系统环境,在安全模式下也能完好运行. 算法及数据结构: 我们始终致力于开发最优化的算法和数据结构,从事 PHP 与 MySQL 的开发的过程中,我们力每行代码都充发挥开发工具的效率优势,Discuz! 是一个挑战 PHP 应用极限的应用程序. Discuz! 开发组具有丰富的 cache 处理经验,到 Discuz! 3.0,内建了包含系统设定到模板系统在内的 PHP 语法生成内核,此内核可直接生成程序格式的缓存,cache 技术的广泛应用使得 Discuz! 的代码效率再上新的台阶. Discuz! 中包含了众多独创或独有的处理方法,使得 Discuz! 可以轻松承受比其他类似产品更多的贴子数量和在线人数,成为目前最高效快速的论坛产品之一.在实现同样功能的前提下,Discuz! 力争占用数据库资源最小,页面处理时间最短.在一台配置良好的 P4 级 UNIX 主机上, 100 万贴论坛平均页面处理时间不超过 0.03 秒(搜索除外),页面平均数据库查询数不超过5 个,最大承载在线人数超过 5000 人,如果构建 Apache 和数据库离的双机系统,负载能力和速度都将获得更大的提升. 数据库操作: Discuz! 依靠专门设计的数据库操作类实现数据库存取,目前提供 MySQL 和 PostgreSQL支持模块,具有专有错误处理模块,通过 Email 实时报告数据库错误. 数据结构更经过精心的设计,从字段到表的配,索引的构建,都经过缜密的考虑,相同数据量的论坛,Discuz! 占用的数据库容量和其他类似产品相比要小. 程序内核中查询遵循 ANSI SQL 规范,短期内即可通过新增数据库类的方式移植到 SQLServer 等其他数据库系统. 模板体系: Discuz! 全部版本都使用模板与程序离的方式构建,Disucz! 2.0 是目前惟一一个采用编译模板系统构建的商业化产品,该核心由 Crossday Studio 独立开发,与传统的模板技术相比更快捷,内容修改也更容易,随着 Discuz! 2.0 应用的普及,必将引起一股编译模板技术应用的高潮. 依赖于 Discuz! 3.0 的编译模板体系,全部提示信息,均在完全不影响程序效率的前提下,用语言包实现,自 2.0 以来,彻底支持多模板,多语言和多风格.每个模板可使用不同的语言界面,不同的内码设定和不同的风格设置,模板可在线编辑,也可通过 FTP 直接上传,给界面定制带来了前所未有的方便.不懂 html 的新手通过风格设置的修改,或设计高手手工修改模板,都可实现论坛外观的完全定制. 论坛功能: 除具有满足讨论需要的全部功能外,Discuz! 还对标准的论坛体系做了丰富的扩展. 全论坛编译模板和国际化内核,更换前/后台提示语言不需要修改程序和模板 可自定义最大在线人数,UNIX 负载情况限制用户访问论坛 附件采用文件存储,读取速度更快,占用数据库更少,同时对可能发生的安全问题做了一一处理,又有完善的从记录到文件的全面管理功能. CookieFree 技术,得益于自建的会话跟踪体系,Discuz! 不需任何设置即可在不使用Cookie 或被禁止的情况下正常登录或使用论坛. 全新设计的搜索功能,使得新的搜索比以往快数倍,具有可共享的搜索缓存,有效减少数据库负载. 自定义 Discuz! 代码功能,可对代码进行扩充并支持最多三个动态代码参数. 自定义会员信息项目功能:支持选单及在帖子中显示该自定义项目. 独有的内建论坛访问与流量统计系统,紧密结合论坛自身的功能,在实现一般外挂统计系统全部功能的同时,最大限度的降低了系统资源的消耗. 预留完善的插件接口,插件只需通过修改设置文件即可被加入到论坛系统中;程序中也处处考虑插件的应用,即使插件对数据结构有修改,也不会影响论坛的正常使用和升级. 权限控制: Discuz! 具有全面而严密的权限与访问控制系统.内置不同的会员用户组,系统用户组,自动根据积或系统头衔确定用户所在组.用户组可任意编辑和添加,各组拥有可调的十几项关键权限设定,涵盖论坛使用的各个方面. 支持交叉用户组,普通用户组和管理用户组可以交叉并得到交叉权限. 版主和超级版主的权限可以具体设定,并具有自己的管理面板,可进行允许范围内的管理操作. 论坛支持密码加密,同时可在每个论坛内给用户组配不同的权限,实现最大限度的权限与访问控制. Discuz! 支持积和具备防止作弊功能的用户评,可设定积的加方式,也可设定用户评权限及最大评数;可设定主题和附件的查看/下载积,并可设定具有此设定权限的用户组;贴子中独有 [hide] 代码,可根据回复或积隐藏相应内容,满足不同要. 后台管理: Discuz! 具有快速智能的论坛后台管理程序,不仅提供详细周密的论坛和用户组权限设定,而且,可根据 10 余种以上的条件实现用户编辑,批量删贴,附件编辑等,且可自动对有关的数据,如用户发帖数,积,论坛数据等等做智能处理,确保了批量操作后统计数据的精确性.内核级访问控制,可设定及屏蔽恶意刷新及 DoS 攻击 管理程序中可方便的修改界面方案中的各种参数,熟悉以后新建一个界面方案只需一钟就可办到,同时也可在线编辑模板,或进行模板的导入,导出操作.每一个管理操作都被记录在案,方便管理员的互相监督.同时提供版主管理记录功能,可按时间顺序查看版主进行的每一个管理操作,对版主负责程度的评定更具有科学性. 数据维护: Discuz! 提供了迄今最强大的 web 界面数据备份和恢复功能,具有足以应付超大数据库的卷备份能力,使得管理员不需任何服务器权限即可轻松维护 Discuz! 数据库.更有远程数据读取功能,两台主机之间传递论坛数据不经过本地不消耗任何本地资源即可完成,创建备份论坛或更新镜像论坛易如反掌. 后台管理程序中可方便的查看数据库的使用情况,同时提供数据库优化功能以消除存储碎片,保证存取效率. 安全保证: Discuz! 3.0 坚固的数据结构和最少化数据库查询,使得 Discuz! 可以在极为繁忙的服务器环境下快速稳定运行 在用户资料存储中和传递中,密码全部使用 RSA-MD5 不可逆加密,有效保证论坛及用户资料的安全. 专门为脆弱页面设计了防刷新系统,自动阻止恶意访问和攻击. Discuz! 独有的全程操作记录,完整详细的记录了论坛运行情况.管理记录采用 PHP 文件格式存储,既能防止被非法查看或下载,又不占用数据库资源.同时具有自我尺寸控制技术,各种记录自动保存最新的 500 条,即使管理员也无法删除各种记录,犹如黑匣子般提供最可靠的安全保证. Discuz! 能有效处理页面格式,保证页面及表格的完整性.安全检查应用于每一个Discuz! 代码中,可自动屏蔽贴子及签名等中的恶意代码.

62,244

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧