From 0cd36ea4be5997d8fe7614b9500a6420c1278592 Mon Sep 17 00:00:00 2001 From: ArabCoders Date: Sun, 3 Nov 2024 17:23:56 +0300 Subject: [PATCH] validating user supplied filename. --- app/main.py | 19 +++++++++---------- frontend/src/main.js | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/app/main.py b/app/main.py index 105367d0..dd0c6966 100644 --- a/app/main.py +++ b/app/main.py @@ -519,9 +519,11 @@ class Main: sd: int = request.query.get('sd') vc: int = int(request.query.get('vc', 0)) ac: int = int(request.query.get('ac', 0)) + file_path: str = os.path.normpath(os.path.join(self.config.download_path, file)) + if not file_path.startswith(self.config.download_path): + raise web.HTTPBadRequest(reason='Invalid file path.') if request.if_modified_since: - file_path = os.path.join(self.config.download_path, file) if os.path.exists(file_path) and request.if_modified_since.timestamp() == os.path.getmtime(file_path): return web.Response(status=304) @@ -546,9 +548,7 @@ class Main: 'Access-Control-Allow-Origin': '*', 'Pragma': 'public', 'Cache-Control': f'public, max-age={time.time() + 31536000}', - 'Last-Modified': time.strftime('%a, %d %b %Y %H:%M:%S GMT', datetime.fromtimestamp( - os.path.getmtime(os.path.join(self.config.download_path, file))).timetuple() - ), + 'Last-Modified': time.strftime('%a, %d %b %Y %H:%M:%S GMT', datetime.fromtimestamp(os.path.getmtime(file_path)).timetuple()), 'Expires': time.strftime('%a, %d %b %Y %H:%M:%S GMT', datetime.fromtimestamp(time.time() + 31536000).timetuple()), } ) @@ -556,12 +556,13 @@ class Main: @self.routes.get(self.config.url_prefix + 'player/subtitle/{file:.*}.vtt') async def subtitles(request: Request) -> Response: file: str = request.match_info.get('file') + file_path: str = os.path.normpath(os.path.join(self.config.download_path, file)) + if not file_path.startswith(self.config.download_path): + raise web.HTTPBadRequest(reason='Invalid file path.') if request.if_modified_since: - file_path = os.path.join(self.config.download_path, file) lastMod = time.strftime('%a, %d %b %Y %H:%M:%S GMT', datetime.fromtimestamp( - os.path.getmtime(os.path.join(self.config.download_path, file))).timetuple() - ) + os.path.getmtime(file_path)).timetuple()) if os.path.exists(file_path) and request.if_modified_since.timestamp() == os.path.getmtime(file_path): return web.Response(status=304, headers={'Last-Modified': lastMod}) @@ -576,9 +577,7 @@ class Main: 'Access-Control-Allow-Origin': '*', 'Pragma': 'public', 'Cache-Control': f'public, max-age={time.time() + 31536000}', - 'Last-Modified': time.strftime('%a, %d %b %Y %H:%M:%S GMT', datetime.fromtimestamp( - os.path.getmtime(os.path.join(self.config.download_path, file))).timetuple() - ), + 'Last-Modified': time.strftime('%a, %d %b %Y %H:%M:%S GMT', datetime.fromtimestamp(os.path.getmtime(file_path)).timetuple()), 'Expires': time.strftime('%a, %d %b %Y %H:%M:%S GMT', datetime.fromtimestamp(time.time() + 31536000).timetuple()), } ) diff --git a/frontend/src/main.js b/frontend/src/main.js index 7eb92e12..8b77b952 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -41,7 +41,7 @@ app.config.globalProperties.makeDownload = (config, item, base = 'download') => let baseDir = 'download' === base ? `${base}/` : 'player/playlist/'; if (item.folder) { - item.folder = item.folder.replace('#', '%23'); + item.folder = item.folder.replace(/#/g, '%23'); baseDir += item.folder + '/'; }