Trivial DoS using the TransferStore.
- Dominant language
- Python
- Stars
- 5.1k
- Forks
- 796
- PR merge metrics
- No merged PRs in 30d
Description
The TransferStore is implemented via a well known flow:
https://github.com/google/grr/blob/master/grr/server/grr_response_server/flows/general/transfer.py#L884
When a file is uploaded from the client, the client will send the bulk data in chunks to the TransferStore well known flow. The flow that initiated the upload receives only a summary of the bulk data (hash and size etc):
https://github.com/google/grr/blob/master/grr/client/grr_response_client/client_actions/file_finder_utils/uploading.py#L73
And it is this summary which is added towards the flow's network bandwidth quota.
Which means that a rogue client can always send any TransferStore requests to the well known flow - even if they have not been issued a flow which requires uploading any files (and therefore there are no network byte limits enforced).
Given that by issue (https://github.com/google/grr/issues/596) a rogue client can connect to any installation without prior authentication this opens the possibility of anyone sending TransferStore operations trivially from the internet.
This is problematic for installations with finite storage space as the TransferStore will just upload the data to the database. For example in the default implementation:
https://github.com/google/grr/blob/debc44219716f4178cd7c3c9f42aff730aa0e22a/grr/server/grr_response_server/blob_stores/memory_stream_bs.py#L19
The blob is uploaded directly into the database row.
Not only is the issue with the amount of data, but also with the number of rows. Typically a blob uploaded will store at least one row in the database (for MySqlAdvancedDB this is several rows - one for each attribute like type, hash etc). Given that a single client POST request can contain millions of TransferStore operations, it is possible to grow the number of rows in the database by millions of rows in a few seconds.
For databases with limited resources this may be problematic. For example the MySql database schema maintains quite a few indexes:
https://github.com/google/grr/blob/debc44219716f4178cd7c3c9f42aff730aa0e22a/grr/server/grr_response_server/data_stores/mysql_advanced_data_store.py#L803
and so these additional insert operations will cause a lot of database pressure. Further since the schema uses the same table for blob and for other data a slow table will affect all GRR operations, not just the transfer store feature.
The overall result is that an adversary can take down the GRR server in a few minutes with little effort on their part.
I think access to the transfer store should be only allowed if the client was given a flow which fetches files and even then, the total uploaded size must be counted towards the flow's quota. This will provide some cap on the amount of data that a rogue client may upload.
Contributor guide
Assessment
This issue has not been assessed yet.