为了尽可能简短:最近我们的系统管理员(应该是这种类型的事情)注意到我们最新的基于 Web 的项目的要求之一是允许客户执行文件上传。特别是这些将主要是图像和可能的视频[,但我相信你知道,你不能保证上传的确切内容是什么,直到它在服务器上]。
系统管理员有点迟疑,只差一个明目张胆的“不!”。
我熟悉许多关于用户输入、处理上传等方面的最佳实践,因此我对这个项目的幕后/代码方面非常有信心。我的问题是,是否有任何特定的资源或对话点可以让我的系统管理员放心?我应该重点向他解释这种事情,如何处理等等?
一些问题是潜在的存储空间(我知道需要根据估计的“受欢迎程度”乘以估计的文件大小来计算)和托管上传内容的安全问题。
归根结底,您和管理员都在那里支持业务需求。挑战在于找到功能(上传文件)和非功能(安全、磁盘成本、性能)方法的正确平衡。
每个建议检查文件扩展名以确保您安全的人都是疯了。将 exe 或 mp3 重命名为 gif 很容易。上传 MIME 类型同上。
确定上传类型的唯一方法是解析它;在文件中查找文件签名,将其加载到图像处理器中并查看它是否阻塞等。
您还需要做什么取决于您的操作系统和网络服务器,但通常上传不应进入单独的磁盘,因此当有人上传大量文件并占用所有空间时,您不会杀死您的操作系统。无论上传到哪里都不应包含执行权限,因此没有人可以通过浏览器从那里运行文件(以防万一它是您使用的任何网络语言的脚本),最好不要允许直接引用它完全可以通过实用程序页面提供文件,使用 GUID 之类的参数作为参数(例如 displayImage?id=0000-000000-0000-0000)
当然还有病毒扫描,限制最大上传大小(尽管要注意这一点,例如 IIS6 无法在中途检查流长度,因此会将上传存储在内存中直到完成,然后将其传递到您的 asp.net 应用程序)
阅读本站:http://www.owasp.org/index.php/OWASP_Top_Ten
您会注意到“上传魔法损坏的 Apache”并不是众所周知的安全漏洞。
Apache 上传处理可能会很糟糕——而且很糟糕——但你真的必须通过忽略 OWASP 漏洞列表来处理它。
此外,您的框架(您没有提到)具有以安全方式处理上传的特定准则。如果它没有任何上传的规定,那么运行——不要走——到一个更好的框架。
“[,但我相信你知道,在上传到服务器之前,你无法保证上传的确切内容是什么]。”
远非真实。并且无关紧要,即使它对于您的特定框架是正确的。
文件通过缓冲区。Python 框架使上传在缓存(如果它很大)或内存(如果它很小)中可用。即使它在文件支持的缓存中,它在文件系统上也不是“真正的”。它没有最终名称或权限——它只是字节。
字节不会神奇地破坏 Apache。具有愚蠢所有权(和/或权限中的 setuid 位)的可执行文件会破坏 Apache。
上传的技巧是 (a) 利用框架的缓存,(b) 在将数据保存到任何地方之前验证数据,(c) 将其保存在某个不可执行的地方——某个地方 Apache 无法查找可执行文件,以及 (d) 从不
chmod
或chown
任何东西在任何情况下。如果一个不可执行的上传被命名.htaccess
并且你把它写到 Apache 从中获取它的目录中,一个不可执行的上传可能会导致问题——通过设置这个目录的权限并且从不命名一个上传的文件,这个操作很容易被阻止.htaccess
。漏洞非常少。他们有据可查。你的框架已经处理了这个。
如果这是业务需求的重要组成部分,我看不出他怎么能拒绝,只要遵循安全协议(即过滤文件扩展名/类型、MIME 类型、文件大小等)
假设他是公司阶梯的一部分(而不是公司中唯一的系统管理员),请尝试去找他的主管并解释您的情况。
请记住,您可以验证上传文件的类型(使用 MIME 类型检测;在 PHP 中有多种方法可以做到这一点,或者使用外部实用程序,
file
例如效用。据推测,一旦您处理并验证了上传的文件,您会将其移动到其最终位置,并且您将拒绝未通过这些阶段的文件;如果是这样,您可以向管理员解释您只会保存“安全”文件。
你可以先问他在这个问题上的主要痛点是什么;他是否关心安全/安保,负责发布其他用户提供的内容(以及引发的任何最终用户安全隐患),还是他关心基础设施问题 - 存储、网络等?
注意:上述“安全”是指所执行检查中的安全性。显然,您不能保证用户提供的任何东西的绝对安全。
文件上传管理起来很复杂,安全性和一般性。
为了获得足够安全的应用程序,您需要...
然后它还取决于您对最终用户的信任。如果它是一个跟踪所有内容的 Intranet,那么您不需要像公共网站那样多的安全性!如果用户是已知的,您将不必检查所有内容。
另一个好的完整性检查——不要将文件上传到磁盘,而是将它们存储在数据库中。这杀死了经典的“上传邪恶文件,然后在服务器上下文中执行邪恶文件”,因为这些文件在服务器上不存在。
现在,如果您在使用 db 支持的文件时遇到性能问题,您总是可以巧妙地提供文件以供下载。
曾经是那个说“呃,不”的管理员。对于要求将文件上传到服务器的开发人员,我可以告诉你我在一个看起来可以做到这一点的应用程序中寻找的东西。主要的限制是,除非我们谈论的是专用的网络服务器,否则我们的网络服务器的大小并没有考虑到海量文件存储。
几年前我工作的初创公司之一是一个 Linux 上的视频和图像上传网站(所以我所有的例子都来自那个)。允许上传可能会出现许多问题。
所有上传系统都应将原始格式转码为您的标准格式。这样做的好处是双重的。首先,您现在有了一种标准格式,可以更轻松地在 html 上显示图像和视频。接下来,如果您确信您已经对文件进行了足够的更改,以至于您没有托管受感染的文件。如果您打算提供来自任何具有电子邮件地址的用户的原始上传文件,那么您可能会遇到很多麻烦。
正如其他人所提到的,您需要的不仅仅是检查扩展名。这是一个更难解决的问题。我们尝试了几次我从不满意的尝试,但出于几个原因,这是值得的。最重要的一点是,您可能会有多种路径来对视频进行转码。视频包含在许多不同的容器中,还有数百万种音频和视频轨道的组合。您对文件了解得越多,您在如何处理它或最终拒绝它时就会做出更好的选择。
假设您正在对文件进行转码,您很容易受到处理库(如 ffmpeg 或 libgd)中的攻击。我们将原始文件写入 NFS 共享上的磁盘,然后在 jail/chroot 环境中生成处理。这使我们能够在不感染服务器或任何其他文件的情况下转码为新格式或在单个目录中失败。此外,您的转码系统需要保持最新状态,因此您需要每晚检查您的发行版,以确保 libpng、libtiff、libmad、libdv 等底层库没有任何当前的安全漏洞。
回到最初的问题,确保您解决了每个人都指出的问题,并且您应该没有问题让您的系统管理员参与进来,并且最终也有一个更好的应用程序。不幸的是,您的系统管理员的工作是对那些看起来将成为支持的运营噩梦的事情说“不”。