题
我工作的公司最近在我们托管的网站上遇到了许多标头注入和文件上传攻击,虽然我们已经修复了标头注入攻击的问题,但我们尚未控制上传漏洞。
我正在尝试设置即插即用型系列的上传脚本,以便内部使用,设计人员可以将其复制到其网站的结构中,修改一些变量并准备好在他们的网站上传表格。我们希望尽可能地限制我们的曝光(我们已经关闭了fopen和shell命令)。
我在网站上搜索了最后一小时,发现许多不同的答案处理依赖外部来源的特定方法。您认为什么是最好的仅限脚本的解决方案,具体到足以用作可靠的保护方法?另外,如果可能的话,我想将语言限制为PHP或伪代码。
编辑:我找到了我的答案(在下面发布),虽然它确实使用了shell命令exec(),但是如果阻止脚本文件上传(这个解决方案确实如此)非常好),你不会遇到任何问题。
解决方案
最好的解决方案是恕我直言,将包含上传文件的目录放在“网络”之外。环境并使用脚本使其可下载。通过这种方式,即使某人上传了一个脚本,也无法通过从浏览器中调用它来执行它,也不必检查上传文件的类型。
其他提示
-
仅允许授权用户上传文件。您也可以添加验证码以阻止原始机器人。
-
首先,在上传表单中设置
MAX_FILE_SIZE
,并设置最大文件size
和<服务器上的代码>计数 。ini_set('post_max_size', '40M'); //or bigger by multiple files ini_set('upload_max_filesize', '40M'); ini_set('max_file_uploads', 10);
按上传的文件进行大小检查:
if ($fileInput['size'] > $sizeLimit) ; //handle size error here
-
您应该使用
$ _ FILES
和move_uploaded_file()
将上传的文件放到正确的目录中,或者如果要处理它,请检查is_uploaded_file( )代码>。 (这些函数用于防止由
register_globals
引起的文件名注入。)$uploadStoragePath = '/file_storage'; $fileInput =
。-
仅允许授权用户上传文件。您也可以添加验证码以阻止原始机器人。
-
首先,在上传表单中设置
MAX_FILE_SIZE
,并设置最大文件size
和<服务器上的代码>计数
ini_set('post_max_size', '40M'); //or bigger by multiple files ini_set('upload_max_filesize', '40M'); ini_set('max_file_uploads', 10);
按上传的文件进行大小检查:
if ($fileInput['size'] > $sizeLimit) ; //handle size error here
-
-
您应该使用
$ _ FILES
和move_uploaded_file()
将上传的文件放到正确的目录中,或者如果要处理它,请检查is_uploaded_file( )代码>。 (这些函数用于防止由
register_globals
引起的文件名注入。)SetHandler none SetHandler default-handler Options -ExecCGI php_flag engine off
始终生成随机ID,而不是使用原始文件名。
-
创建新子域 ,例如对于上传的文件,http://static.example.com 或
public_html
之外的至少一个新目录。此子域或目录不应执行任何文件。在服务器配置中设置它,或在目录中的strong> .htaccess
文件 。$noExecMode = 0644; chmod($uploadedFile, $noExecMode);
使用
将其设置为 chmod()
。$userContent = '../uploads/malicious.jpg'; include('includes/'.$userContent);
在新上传的文件上也使用
chmod()
并将其设置在目录中。 -
您应该检查黑客发送的 mime类型 。您应该创建允许的 mime类型的白名单。 仅限图片,如果不需要任何其他格式。任何其他格式都是安全威胁。图像也是,但至少我们有工具来处理它们...
损坏的内容例如:图像文件中的 HTML 可能会导致浏览器 XSS 内容嗅探漏洞。当损坏的内容是 PHP 代码时,它可以与 eval injection 漏洞结合使用。Strict-Transport-Security: max-age={your-max-age} X-Content-Type-Options: nosniff X-Frame-Options: deny X-XSS-Protection: 1; mode=block Content-Security-Policy: {your-security-policy}
尽量避免这种情况,例如使用
类自动加载器
而不是手动包含php文件...
通过首先处理 javascript注入,您必须关闭浏览器中的 xss 和内容嗅探。 内容嗅探问题是旧版 msie 的典型问题,我认为其他浏览器可以很好地过滤它们。无论如何,你可以用一堆标题来防止这些问题。 (并非每个浏览器都完全支持,但这是您在客户端可以做的最好的。)try { $uploadedImage = new Imagick($uploadedFile); $attributes = $uploadedImage->identifyImage(); $format = $image->getImageFormat(); var_dump($attributes, $format); } catch (ImagickException $exception) { //handle damaged or corrupted images }
您可以使用
Imagick识别来检查文件是否已损坏代码>
,但这并不意味着完全的保护。X-Download-Options: noopen Content-Disposition: attachment; filename=untrustedfile.html
如果您想提供其他 mime类型,则应始终强制下载 ,绝不要包含他们进入网页,除非你真的知道你在做什么......
<*> -
可以使用包含代码的有效图像文件,例如 exif 数据。因此,如果内容对您不重要,则必须从图像中清除 exif 。您可以使用
Imagick
或GD
来完成此操作,但这两者都需要重新打包文件。你可以找到一个exiftool
FILES['image']; if ($fileInput['error'] != UPLOAD_ERR_OK) ; //handle upload error here, see http://php.net/manual/en/features.file-upload.errors.php //size check here $temporaryName = $fileInput['tmp_name']; $extension = pathinfo($fileInput['name'], PATHINFO_EXTENSION); //mime check, chmod, etc. here $name = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); //true random id move_uploaded_file($temporaryName, $uploadStoragePath.'/'.$name.'.'.$extension);始终生成随机ID,而不是使用原始文件名。
-
创建新子域 ,例如对于上传的文件,http://static.example.com 或
<*>public_html
之外的至少一个新目录。此子域或目录不应执行任何文件。在服务器配置中设置它,或在目录中的strong> .htaccess
文件 。使用
<*>将其设置为 chmod()
。在新上传的文件上也使用
chmod()
并将其设置在目录中。 -
您应该检查黑客发送的 mime类型 。您应该创建允许的 mime类型的白名单。 仅限图片,如果不需要任何其他格式。任何其他格式都是安全威胁。图像也是,但至少我们有工具来处理它们...
<*>
损坏的内容例如:图像文件中的 HTML 可能会导致浏览器 XSS 内容嗅探漏洞。当损坏的内容是 PHP 代码时,它可以与 eval injection 漏洞结合使用。尽量避免这种情况,例如使用
<*>类自动加载器
而不是手动包含php文件...
通过首先处理 javascript注入,您必须关闭浏览器中的 xss 和内容嗅探。 内容嗅探问题是旧版 msie 的典型问题,我认为其他浏览器可以很好地过滤它们。无论如何,你可以用一堆标题来防止这些问题。 (并非每个浏览器都完全支持,但这是您在客户端可以做的最好的。)您可以使用
<*>Imagick识别来检查文件是否已损坏代码>
,但这并不意味着完全的保护。如果您想提供其他 mime类型,则应始终强制下载 ,绝不要包含他们进入网页,除非你真的知道你在做什么......
<*> -
可以使用包含代码的有效图像文件,例如 exif 数据。因此,如果内容对您不重要,则必须从图像中清除 exif 。您可以使用
Imagick
或GD
来完成此操作,但这两者都需要重新打包文件。你可以找到一个exiftool
使用和配置 Hardened-PHP 使用 move_uploaded_file 和 $ _ FILES superglobal 。最简单的脚本,最安全(至少,与正在运行的PHP版本本身一样安全)