Skip to content

Commit 02190cd

Browse files
committed
Remove average download speed check
The average download speed check does not achieve its purpose of protecting against slow retrieval attacks. Such protection is highly dependent on the networking stack which could be user-provided and not under tuf's control. The slow retrieval attack protection has been removed from the specification for similar reasons. Signed-off-by: Teodora Sechkova <tsechkova@vmware.com>
1 parent f057d57 commit 02190cd

1 file changed

Lines changed: 2 additions & 58 deletions

File tree

tuf/ngclient/_internal/download.py

Lines changed: 2 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,10 @@
2525

2626
import logging
2727
import tempfile
28-
import timeit
2928
from urllib import parse
3029

3130
from securesystemslib import formats as sslib_formats
3231

33-
import tuf
3432
from tuf import exceptions, formats
3533

3634
# See 'log.py' to learn how logging is handled in TUF.
@@ -42,9 +40,7 @@ def download_file(url, required_length, fetcher, strict_required_length=True):
4240
<Purpose>
4341
Given the url and length of the desired file, this function opens a
4442
connection to 'url' and downloads the file while ensuring its length
45-
matches 'required_length' if 'STRICT_REQUIRED_LENGH' is True (If False,
46-
the file's length is not checked and a slow retrieval exception is raised
47-
if the downloaded rate falls below the acceptable rate).
43+
matches 'required_length' if 'STRICT_REQUIRED_LENGTH' is True.
4844
4945
<Arguments>
5046
url:
@@ -92,43 +88,19 @@ def download_file(url, required_length, fetcher, strict_required_length=True):
9288
# the downloaded file.
9389
temp_file = tempfile.TemporaryFile() # pylint: disable=consider-using-with
9490

95-
average_download_speed = 0
9691
number_of_bytes_received = 0
9792

9893
try:
9994
chunks = fetcher.fetch(url, required_length)
100-
start_time = timeit.default_timer()
10195
for chunk in chunks:
102-
103-
stop_time = timeit.default_timer()
10496
temp_file.write(chunk)
105-
106-
# Measure the average download speed.
10797
number_of_bytes_received += len(chunk)
108-
seconds_spent_receiving = stop_time - start_time
109-
average_download_speed = (
110-
number_of_bytes_received / seconds_spent_receiving
111-
)
112-
113-
if average_download_speed < tuf.settings.MIN_AVERAGE_DOWNLOAD_SPEED:
114-
logger.debug(
115-
"The average download speed dropped below the minimum"
116-
" average download speed set in tuf.settings.py."
117-
" Stopping the download!"
118-
)
119-
break
120-
121-
logger.debug(
122-
"The average download speed has not dipped below the"
123-
" minimum average download speed set in tuf.settings.py."
124-
)
12598

12699
# Does the total number of downloaded bytes match the required length?
127100
_check_downloaded_length(
128101
number_of_bytes_received,
129102
required_length,
130103
strict_required_length=strict_required_length,
131-
average_download_speed=average_download_speed,
132104
)
133105

134106
except Exception:
@@ -154,10 +126,7 @@ def download_bytes(url, required_length, fetcher, strict_required_length=True):
154126

155127

156128
def _check_downloaded_length(
157-
total_downloaded,
158-
required_length,
159-
strict_required_length=True,
160-
average_download_speed=None,
129+
total_downloaded, required_length, strict_required_length=True
161130
):
162131
"""
163132
<Purpose>
@@ -182,9 +151,6 @@ def _check_downloaded_length(
182151
False when we know that we want to turn this off for downloading the
183152
timestamp metadata, which has no signed required_length.
184153
185-
average_download_speed:
186-
The average download speed for the downloaded file.
187-
188154
<Side Effects>
189155
None.
190156
@@ -193,10 +159,6 @@ def _check_downloaded_length(
193159
strict_required_length is True and total_downloaded is not equal
194160
required_length.
195161
196-
exceptions.SlowRetrievalError, if the total downloaded was
197-
done in less than the acceptable download speed (as set in
198-
tuf.settings.py).
199-
200162
<Returns>
201163
None.
202164
"""
@@ -214,28 +176,10 @@ def _check_downloaded_length(
214176
required_length,
215177
)
216178

217-
# If the average download speed is below a certain threshold, we
218-
# flag this as a possible slow-retrieval attack.
219-
if average_download_speed < tuf.settings.MIN_AVERAGE_DOWNLOAD_SPEED:
220-
raise exceptions.SlowRetrievalError(average_download_speed)
221-
222179
raise exceptions.DownloadLengthMismatchError(
223180
required_length, total_downloaded
224181
)
225182

226-
# We specifically disabled strict checking of required length, but
227-
# we will log a warning anyway. This is useful when we wish to
228-
# download the Timestamp or Root metadata, for which we have no
229-
# signed metadata; so, we must guess a reasonable required_length
230-
# for it.
231-
if average_download_speed < tuf.settings.MIN_AVERAGE_DOWNLOAD_SPEED:
232-
raise exceptions.SlowRetrievalError(average_download_speed)
233-
234-
logger.debug(
235-
"Good average download speed: %f bytes per second",
236-
average_download_speed,
237-
)
238-
239183
logger.info(
240184
"Downloaded %d bytes out of upper limit of %d bytes.",
241185
total_downloaded,

0 commit comments

Comments
 (0)