ウェブファイルアップロードフォームがセキュリティへの主要な脅威である - [1]脆弱性科学をアップロード

クリエイティブコモンズライセンス 著作権:帰属、紙ベースを作成するために他人を許可し、(同じライセンスで元のライセンス契約に基づいて用紙配布する必要がありますクリエイティブコモンズ

ここに画像を挿入説明
悪意のあるユーザーが別の扉を開くために、サーバーを危険にさらすしたいエンドユーザーは、Webサイトにファイルをアップロードできるようにするために。それはあなたのビジネス効率を向上させることができますので、そうであっても、今日の近代的なインターネットのWebアプリケーションでは、それは、一般的な要件です。FacebookやTwitterのソーシャルネットワークのようなWebアプリケーションでは、ファイルのアップロードを許可します。ブログ、フォーラム、電子バンキングサイト、YouTubeやエンタープライズサポートポータル、エンドユーザーにそれらを聞かせて、効果的にファイルを共有する従業員への機会を与えます。これにより、ユーザーは画像、動画、アバターやファイルの多くの他のタイプをアップロードすることができます。

より多くのエンドユーザーが利用可能な機能、Webアプリケーション攻撃やリスクも大きく、この機能は、特定のウェブサイトへの権利を得るために、悪意のあるユーザーによって悪用される、またはサーバーを脅かす可能性が非常に高いという可能性。

複数のWebアプリケーションをテストするとき、私たちは、よく知られているWebアプリケーションのかなりの数は、安全なファイルアップロードフォームを持っていないことに注意してください。これらの脆弱性を簡単に活用することができる、我々はファイルシステムにWebアプリケーションをホストしているこれらのサーバーにアクセスすることができます。この記事では、我々はあなたの方法の8種類が表示されます、我々はセキュリティファイルのアップロードフォームに遭遇しました。同時に、我々はまた、悪意のあるユーザーがこれらのセキュリティ対策を簡単にバイパスすることができます表示されます。

ケース1:シンプルなファイルアップロードフォームのない検証がありません

単純なファイルアップロードフォームは、通常、HTMLフォームとPHPスクリプトが含まれています。ユーザに提示するHTMLフォームの形式、およびコードに必要なPHPスクリプトファイルのアップロード機能に含まれています。ここでは、このフォームとPHPスクリプトは一例です:

HTMLフォーム:

<form enctype="multipart/form-data" action="uploader.php" method="POST"> 
<input type="hidden" name="MAX_FILE_SIZE" value="100000" /> 
Choose a file to upload: <input name="uploadedfile" type="file" /><br /> 
<input type="submit" value="Upload File" /> 
</form>

PHPコード:

<?php
    $target_path  =  "uploads/";
    $target_path  =  $target_path  .  basename($_FILES['uploadedfile']['name']);
    if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
    echo "The file " . basename($_FILES['uploadedfile']['name']) . " has been uploaded";
    echo "There was an error uploading the file, please try again!";
    } else {
    }
?>

POST要求がPHPと符号化タイプマルチパート/フォームデータを受信した場合、それは一時的なファイル名のランダムな一時ディレクトリを作成する(例えば、/ VAR / TMP / php6yXOVs)。PHPはファイルをアップロードグローバル配列$ _FILESの情報が入ります。

$ _FILES ['UploadedFile的'] ['名称']:在客户机上的文件的原始名称
$ _FILES ['UploadedFile的'] ['类型']:文件的MIME类型
$ _FILES ['UploadedFile的'] ['大小']:文件的大小(以字节为单位)
$_FILES ['UploadedFile的']['不对tmp_name']:上传的文件存储在服务器上的临时文件名。

PHPの関数は、ユーザーが提供する場所に一時ファイルを移動しmove_uploaded_file。この場合、送信先は、サーバのルートディレクトリです。:したがって、URLのファイルは、次のような、使用することができますHTTP://www.domain.tld/uploads/uploadedfile.extアクセス。この単純な例では、アップロードすることが許可されているので、攻撃者が悪意のあるコードやNETとのPHPファイルをアップロードすることができ、ファイルの種類が限定されるものではなく、サーバは妥協することがあります。

これは非常に単純な例のように見えるかもしれませんが、我々はいくつかのWebアプリケーションでは、このようなコードが発生していません。

ケース2:MIMEタイプの検証

Web開発者は、ファイルのアップロードフォームは、ちょうどPHPからの戻りMIMEタイプを確認することを確保するためのもう一つの一般的な間違い。ファイルがサーバーにアップロードされている場合、PHPは、クライアントが使用するWebブラウザが提供する変数$ _FILES MIMEタイプ[「にUploadedFile」] [「タイプ」]を設定します。ただし、ファイルアップロードフォームの検証は、この値に依存することはできません。悪意のあるユーザーが簡単にスクリプトや、彼がアップロードするファイルの偽のMIMEタイプを送信されるHTTP POSTリクエストを送信することを可能にする他の自動化されたアプリケーションを使用することができます。

ケース3:拡張のリスクを制限

別の例では、セキュリティ対策として、ファイルアップロードのブラックリストのアプローチに遭遇しました。あなたがリストに含まれたファイルをアップロードしている場合は、コレクションを開発するために危険な開発者のリストから、アクセスが拒否されます。

危険なファイルの拡張子、その主な欠点の一つの使用は、攻撃者が使用できるすべての可能な拡張子の名前を含む完全なリストは、コンパイルすることはほとんど不可能であるということです。コードが管理された環境で実行されている場合たとえば、通常、このような環境なのPerl、PythonやRubyなどのスクリプト言語の多くは、リストは無限大になるように。

悪意のあるユーザーが簡単にチェックが次のコード行に類似含む「.htaccessファイル」という名前のファイルを、アップロードバイパスすることができます:

AddTypeのがapplication / x-httpd-phpのの.JPG

ApacheWebサーバを示すコードの上の行は、それらがPHPスクリプトであるかのようにJPGイメージを行います。攻撃者は現在、PHPのコードが含まれているJPGファイルの拡張子を、アップロードすることができます。Webブラウザから以下のスクリーンショットは、PHPのコマンドのphpinfo()関数が含まれているJPGファイルを、要求したとして、それはまだWebサーバーから実行されます:
ここに画像を挿入説明
ケース4:二重拡張子(パート1)

この場合、3のセキュリティポリシーと例の使用は非常に似て使用していました。ファイル名の拡張子を確認するための簡単な方法に置き換えますが、開発者が「」ファイル名を調べて文字を持っているし、抽出点番号の後ファイルの拡張子を取得するための文字列。

道をバイパスすると述べた:.さんは、Apacheのマニュアル、次の段落の複数の拡張子を持つApacheのファイルに対処する方法を見てみましょう、現実的なファーストまだ少し複雑な、しかしアプローチする
「ファイルが複数の拡張子を持つことができますこれらの拡張のためには、例えば無関係である通常の状況下:ファイルならばwelcome.html.frコンテンツタイプにマッピングされているが、text / htmlであり、言語はフランス語で、そのファイルはまったく同じwelcome.fr.htmlにマッピングされますコンテンツは、複数の拡張が等言語やコンテンツのエンコーディングに加えて、右端に使用されるメタ情報の同じタイプにマッピングされている場合:MIMEタイプ.GIF ..画像/ GIF、.htmlのMIMEタイプがありますその後、welcome.gif.html MIMEタイプがtext / htmlのだろう、text / htmlのです。」

因此一个名为 ‘filename.php.123’ 的文件将会被解释为一个PHP文件并被执行.这仅限于最后的那个扩展名(本例中是 .123)没有在web服务器的 mime-types列表中被指定.web开发者通常不会意识到Apache还存在这么一个 ‘特性’, 出于某些原因来说这可能非常危险.知道了这个以后,一个攻击者可以上传一个名为 shell.php.123 的文件并绕过文件上传保护机制.后台脚本将会计算出最后的扩展名(.123)并作出该扩展名并不在危险的扩展名列表内的结论.话虽如此,想要预防某恶意用 户可能会使用的所有随机扩展名来上传一个文件到你的web服务器上是不可能的.

案例5: 双扩展名 (第2部分)

一个更好的增强文件上传表单的安全性的途径就是白名单机制. 在本例中, 开发者定义了一个 已知/可接受 的扩展名列表并且不允许使用未在名单中指定的扩展名.

然 而, 在某些情况下该途径不会像期待的方式那样工作. 当 Apache 被配置为执行 PHP 代码的时候, 存在两种方式来实现该机制: 使用 AddHandler 指令, 或者使用 AddType 指令. 如果 AddHandler 指令被使用, 所有包含 ‘.php’ 扩展名的文件名(例如: ‘.php’ , ‘.php.jpg’)均被作为 PHP 脚本来执行. 因此, 如果你的 Apache 配置文件包含如下一行的话, 你可能很容易受到攻击:

AddHandler php5-script .php

一个攻击者可以上传名为 ‘filename.php.jpg’ 的文件并绕过保护机制, 然后执行其中的代码.

案例 6: 检查图片头部

当 仅允许上传图片的时候, 开发者通常使用 PHP 的 getimagesize 函数来检测图片的头部信息. 该函数在被调用时将会返回图片的尺寸, 如果图片经验证为无效的, 也就是说图片头部信息不正确, 则会返回 false 值. 因此一个开发者一般会检查该函数是否返回 true 或 false, 并且通过该信息来验证上传的文件. 所以, 如果一个恶意用户试着上传一个内嵌有简单 PHP shell 的 jpg 文件的话, 该函数会返回 false 然后他将不允许上传此文件. 然而, 即使这种方式也能被很容易的绕过. 如果一个图片在一个图片编辑器内打开, 就如 Gimp, 用户就可以编辑图片的注释区, 那儿就能插入 PHP 代码, 就如下图所示.
ここに画像を挿入説明
该图片仍然有一个有效的头部; 因此就绕过了 getimagesize 函数的检查. 从下面截图中可以看到, 当一个普通的 web 浏览器请求该图的时候, 插入到图片注释区的 PHP 代码仍然被执行了:
ここに画像を挿入説明
案例七:通过.htaccess保护上传文件夹

另一种流行的穿件安全的文件上传表单的方法是适用.htaccess保护好上传文件存放的文件夹。办法是限制这个文件夹里的脚本文件的执行。这种情形一下,一个.htaccess文件一般包含下面的代码:

AddHandler cgi-script .php .php3 .php4 .phtml .pl .py .jsp .asp .htm .shtml .sh .cgi

Options –ExecCGI

上面的是另一种形式的黑名单,本身并不是很安全。在PHP手册中,move_uploaded_file一章中,有一个warning:若目标文件已经存在,则会覆盖原文件。

因为上传的文件能够而且会覆盖已经存在的同名文件,一个恶意用户很轻易就能用他自己修改过的.htaccess替换掉原来的。这使得他可以执行特定的将会帮助他危害服务器的脚本。

案例八:客户端验证

另一种在文件上传表单中常用的安全技术是在客户端验证上传的文件。一般而言,该技术在ASP.NET应用中更通用一些,因为ASP.NET提供了易用的验证控件。

这些验证控件允许开发者对要上传的文件做正则检查,以查出待上传的文件扩展名是否在允许列表中。下面是一段来自微软网站的示例代码:

<asp:FileUpload ID="FileUpload1" runat="server" />

  <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Upload File" /> 

  <asp:Label ID="Label1" runat="server"></asp:Label>

  <asp:RegularExpressionValidator id="RegularExpressionValidator1" runat="server"

  ErrorMessage="Only mp3, m3u or mpeg files are allowed!"

  ValidationExpression="^(([a-zA-Z]:)|({2}w+)$?)((w[w].*))

  +(.mp3|.MP3|.mpeg|.MPEG|.m3u|.M3U)$" ControlToValidate="FileUpload1"></asp:RegularExpressionValidator>

  <asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server"

  ErrorMessage="This is a required field!"

  ControlToValidate="FileUpload1"></asp:RequiredFieldValidator>

   

这段ASP.NET代码使用了验证控件,所以最终用户只被允许上传.mp3,.mpeg,或者.m3u文件到服务器。若文件类型和这三个指定的文件类型不一致,验证控件将跑出异常,文件也就不会被上传。

由于这种文件验证是在客户端完成的,恶意用户很容易就能绕过这一检查。写一段客户端脚本来替换web应用的验证脚本做验证并非不可能。不用web浏览器,入侵者可以使用可以发送HTTP POST请求的程序来实现上传文件。

推荐的解决方案

在允许上传文件的网站和web应用中,应当应用下面的一系列最佳实践方法。这些实践方法将有助于你保证web应用的上传文件的安全性。
定义一个.htaccess文件,只允许访问指定扩展名的文件。

不要把.htaccess文件和上传文件放在同一个目录里,应该放在父目录里。

一个典型的只允许 gif, jpg, jpeg 和 png文件的.htaccess文件应当包含下面的代码(根据你的需求做调整)。这样也能阻止双扩展名攻击.

deny from all
<Files ~ "^w+.(gif|jpe?g|png)$">
order deny,allow
allow from all
</Files>

如果可能,把文件上传到root目录以外的目录里。

禁止覆盖已存在的文件(以阻止.htaccess覆盖攻击)

创建一个mime-type白名单列表。(只允许这个列表里的Mime-type)

生成一个随机的文件名,并且加上此前生成的文件扩展名、

不要只依赖客户端验证,这不够。理想的是既有客户端验证也有服务器端验证。

总结

如上所述,恶意用户有很多手段绕过文件上传表单安全验证。因此,在web应用中实现文件上传表单时,应当尊徐正确的安全指导,并且做恰当的测试。不幸的是要做足够的测试将会需要很多时间和更多的安全专家。

幸い会社のAcunetix WVS、無セキュリティの専門家で自動的にフォームの脆弱性チェックをアップロードすることができ、開発者のための最小限の時間を提供する会社のAcunetix WVSは、問題を追跡し、修正するための十分な情報よりもすることができます。

おすすめ

転載: blog.csdn.net/kclax/article/details/92119613