2016-09-23 5 views
4

1日のファイルアップロードの上限をどのように設定することができますか?ユーザーが1日に最大10枚の写真を公開したいと思っています。データベース側では、増分カウンタを置いています。一定のサイズに達すると、ユーザーは他のコンテンツを投稿することができません。ストレージ側ではこれは不可能です。攻撃者は、必要なすべてのファイルを制限なしで公開することができます。このような状況を防ぐための解決策はありますか?前もって感謝します。現在、私のセキュリティルールは以下の通りです:火災防止対策スパム対策

service firebase.storage { 
    match /b/projectid/o { 
    match /Photo/{user}/{photo}/image.jpg { 
     allow write: if request.auth != null && 
         request.auth.uid == user && (
         request.resource.size < 5 * 1024 * 1024 && photo.size() < 32 || 
         request.resource == null); 
     allow read: if request.auth != null && 
        request.auth.uid == user 
    } 
    } 
} 
+2

できることはいくつかあります。 1)検証されたユーザーのみが問題のノードを読み書きできるルールを実装します。これにより、攻撃者が任意のノードにアップロードするだけで済みます。 2)その日の 'upload_count'ノードを実装し、アップロード(書き込み)にタイムスタンプと同様にアップロードを含めます。その日のカウントが10未満の場合にのみアップロードを許可する検証ルールを設定します。あらかじめ定義されたルール変数 'now'と 'new data'を見て、現在のものと書き込もうとしているデータのタイムスタンプを比較したいと思うでしょう。 – Jay

+0

ルールが表示されている場合、各ユーザーはそのノードにのみ書き込むことができますが、各ユーザーはそのノードに無制限のファイルを書き込めるという問題があります。私は第二のポイントを理解していない。データベースにはすでにカウンターがありますが、ストレージにはどうすればカウンターを保管できますか?データベースとストレージのルールは別々であり、攻撃者はデータベースのカウンタを更新せずにファイルをアップロードできることを忘れないでください。 – DThink

+0

これを解決する方法はありませんか? – DThink

答えて

1

これは非常に簡単な方法です。これを行う正しい方法があります。

特定の期間に特定の数のファイルのみをアップロードできるようにするには、いくつかの数値プロパティ(例:users/{userid}/0.jpgusers/{userid}/9.jpg)のファイル名を付けてください。

あなたは次のようにすることを確認するためにルールを記述することができます

// Match all filenames like 0.jpg 
match /users/{userId}/{photoId} { 
    allow write: if photoId.matches('^\d\.jpg$') 
} 

をご桁以上の粒度が必要な場合は、あなたのような何かをすることができます半分だけ、私たちが解決

// Match all filenames like YYY.jpg where YYY is a number less than XXX 
match /users/{userId}/{photoId} { 
    allow write: if int(photoId.split('\.')[0]) < XXX 
} 

を私たちはファイルの数を制限することができますが、ユーザーが単にファイルをアップロードしたい場合はどうなりますか?幸運なことに、エンドユーザーがファイルを上書きするのを防ぐルールを書くことができます(ただし、削除は削除する必要があります)。のは、見てみましょう:

// Allow files to be overwritten once a day, written if there's nothing there, or deleted as often as desired 
match /users/{userId}/{photoId} { 
    allow write: if request.time > resource.timeCreated + duration.value(1, "d") || resource.size == 0 || request.resource.size == 0 
} 

これらの関数に組み合わせることができます

function isAllowedPhotoId(photoId) { 
    return int(photoId.split('\.')[0]) < XXX 
} 

function canOverwritePhoto() { 
    return request.time > resource.timeCreated + duration.value(1, "d") || resource.size == 0 || request.resource.size == 0 
} 

match /users/{userId}/{photoId} { 
    allow write: if isAllowedPhotoId(photoId) && canOverwritePhoto() 
} 

長期、解決策は、ストレージ内からデータベースのデータ、およびその逆を参照できることです。残念ながら、その世界はまだここにはありませんが、我々はそれに向かって取り組んでいます。

+0

が解決されました。ありがとう:) – DThink

+0

私はこのメソッドでは、ファイルを削除するときの問題を参照してください。私は特定のファイルを削除する場合、私は順序付けされていないファイルとフォルダがあります。特定のIDを持つ写真を保存したいときにこれはちょっと難しいです – DThink

+0

あなたはそうです - クライアントにファイルの名前を正しく変更するのは負担になります。シンプルなハッシュスキームを選ぶことができます:* n *でファイルの名前を変更し、その場所に配置します。失敗した場合は、1(線形プロービング)またはn^2(2次プロービング)で増分し、ファイルをそこに追加します。 –

関連する問題