security: fix DoS on title getter

the `timeout` parameter only applies to seconds per *byte* received (and time to first
byte), not the entire request

this means an attacker could theoretically send a very... slow...
stream... of... bytes... and... crash... the... worker... when... the...
timeout... is... reached...
master
justcool393 2022-11-25 07:10:05 -06:00
parent 6b052b05cf
commit 816389cf28
1 changed files with 3 additions and 1 deletions

View File

@ -1075,6 +1075,7 @@ extensions = IMAGE_FORMATS + VIDEO_FORMATS + AUDIO_FORMATS
@ratelimit_user("3/minute") @ratelimit_user("3/minute")
@auth_required @auth_required
def get_post_title(v): def get_post_title(v):
POST_TITLE_TIMEOUT = 5
url = request.values.get("url") url = request.values.get("url")
if not url or '\\' in url: abort(400) if not url or '\\' in url: abort(400)
url = url.strip() url = url.strip()
@ -1084,7 +1085,8 @@ def get_post_title(v):
if any((checking_url.endswith(f'.{x}') for x in extensions)): if any((checking_url.endswith(f'.{x}') for x in extensions)):
abort(400) abort(400)
try: x = requests.get(url, headers=titleheaders, timeout=5, proxies=proxies) try:
x = gevent.with_timeout(POST_TITLE_TIMEOUT, requests.get, url, headers=titleheaders, timeout=POST_TITLE_TIMEOUT, proxies=proxies)
except: abort(400) except: abort(400)
content_type = x.headers.get("Content-Type") content_type = x.headers.get("Content-Type")