Djangoのドキュメントによると、「静的アセットをユーザーがアップロードしたファイルと一緒にMEDIA_ROOTに配置し、両方をMEDIA_URLで提供するのが一般的でした。」
それは、誰もが他の人のアップロードされたファイルにアクセスできることを意味しますか?安全じゃないですか?
Djangoのドキュメントによると、「静的アセットをユーザーがアップロードしたファイルと一緒にMEDIA_ROOTに配置し、両方をMEDIA_URLで提供するのが一般的でした。」
それは、誰もが他の人のアップロードされたファイルにアクセスできることを意味しますか?安全じゃないですか?
賢いユーザーは、他のユーザーに属するメディアファイルへのパスを推測できる可能性があります。
Djangoは、これが問題にならないニュースパブリッシングビジネスで生まれました。管理者は、同じ組織に属するライターや編集者などの信頼できるユーザーの概念に基づいています。
私の最初の選択ではありませんが、WebサーバーをDjangoのユーザーデータベースに対して認証させることができます。
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIPythonPath /path/to/mysite.com
WSGIProcessGroup %{GLOBAL}
WSGIApplicationGroup %{GLOBAL}
<Location "/media/private-user-content/">
AuthType Basic
AuthName "Top Secret"
Require valid-user
AuthBasicProvider wsgi
WSGIAuthUserScript /path/to/mysite.com/mysite/wsgi.py
</Location>
受け入れられた回答は、認証されたDjangoビューから機密ファイルを提供することを推奨しています。トラフィックの少ないアプリでは問題ありませんが、大規模なプロジェクトでは、すべてのサイトが対応できるわけではないパフォーマンスの低下をもたらします。
大規模なプロジェクトでは、パフォーマンスとコストの両方を考慮して、クラウドストレージバックエンドを使用する必要があります。プロジェクトがすでにビッグ3(AWS、GCP、Azure)のいくつかでホストされている場合は、DjangoStoragesを確認してください。たとえば、S3バックエンドを使用している場合は、生成されたURLの「クエリパラメーター認証」を有効にして、問題を解決できます。これにはいくつかの利点があります。
同じWebサーバーからメディアとアプリケーションを提供している小さなプロジェクトの場合、せんさく好きなユーザーが自分に属していないメディアファイルを見つけるのを非常に難しくすることができます。
1)MEDIA_ROOTフォルダのWebサーバー「自動インデックス」を無効にします。apacheの場合、次のようになります。
<Directory /path/to/application/media/root>
Options -Indexes
</Directory>
インデックスがない場合、他の人が所有するファイルにアクセスするには、正確なファイル名を推測する必要があります。
2)FileFieldsの「upload_to」パラメータで暗号化ハッシュを使用してファイルパスを推測しにくくします。
def hard_to_guess(instance, filename):
salt = 'six random words for hidden salt'
hash = hashlib.md5(instance.user.username + salt)
return '/'.join(['content', hash, filename])
...
class SomeModel(models.Model):
...
user = models.ForeignKey(User)
content = models.FileField(upload_to=hard_to_guess)
...
メディアファイルは引き続きWebサーバーから直接提供されるため、このソリューションはパフォーマンスに影響を与えません。
あなたの質問に答えるために:はい、これは誰もがみんなのアップロードされたファイルにアクセスすることを可能にします。はい、これはセキュリティリスクです。
原則として、機密ファイルはファイルシステムから直接提供されるべきではありません。別のルールとして、明示的にマークされていない限り、すべてのファイルは機密情報と見なされます。
MEDIA_ROOT
と設定の起源は、MEDIA_URL
おそらくパブリッシングプラットフォームとしてのDjangoの歴史にあります。結局のところ、編集者は、記事に追加した写真が簡単に見つかるかどうかはおそらく気にしないでしょう。しかし、繰り返しになりますが、記事に付随する写真は通常、機密性が低くなります。
質問を拡張するには、機密ファイルは常にWebサーバーから直接アクセスできないディレクトリに配置する必要があります。これらのファイルの要求は、ファイルを提供する前に適切なアクセスチェックを実行できるビュークラスまたは関数を介してのみ実行する必要があります。
また、機密ファイルの難読化に依存しないでください。たとえば、Pauloの例(他の回答を参照)を使用して、フォトアルバムを難読化してみましょう。今、私の写真はのように保存されていMEDIA_URL/A8FEB0993BED/P100001.JPG
ます。このリンクを他の人と共有すると、その人はのようなURLを簡単に試すことができMEDIA_URL/A8FEB0993BED/P710032.JPG
、基本的には私のフォトアルバム全体を総当たり攻撃することができます。