From ccae64047875a10a035aa6e4bcc7674e03f9385c Mon Sep 17 00:00:00 2001 From: CoderShady Date: Thu, 9 Apr 2026 17:00:06 +0530 Subject: [PATCH 1/5] fixing command injection and path traversal security fix command injection and path traversal in name_normalize --- video_creation/final_video.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/video_creation/final_video.py b/video_creation/final_video.py index c4f3a0b..efbcaaa 100644 --- a/video_creation/final_video.py +++ b/video_creation/final_video.py @@ -68,12 +68,17 @@ class ProgressFfmpeg(threading.Thread): def name_normalize(name: str) -> str: - name = re.sub(r'[?\\"%*:|<>]', "", name) name = re.sub(r"( [w,W]\s?\/\s?[o,O,0])", r" without", name) name = re.sub(r"( [w,W]\s?\/)", r" with", name) name = re.sub(r"(\d+)\s?\/\s?(\d+)", r"\1 of \2", name) name = re.sub(r"(\w+)\s?\/\s?(\w+)", r"\1 or \2", name) - name = re.sub(r"\/", r"", name) + + # Change: Remove all characters except letters, numbers, spaces, hyphens, and underscores. + # This prevents shell injection ($(command)) and path traversal (../../) + name = re.sub(r'[^\w\s\-_]', '', name) + + # Remove leading/trailing spaces to prevent invalid names + name = name.strip() lang = settings.config["reddit"]["thread"]["post_lang"] if lang: @@ -84,6 +89,7 @@ def name_normalize(name: str) -> str: return name + def prepare_background(reddit_id: str, W: int, H: int) -> str: output_path = f"assets/temp/{reddit_id}/background_noaudio.mp4" output = ( From 5121d685744d960b04249409820732d895e52cc1 Mon Sep 17 00:00:00 2001 From: CoderShady Date: Thu, 9 Apr 2026 17:18:02 +0530 Subject: [PATCH 2/5] Improve boolean input handling in console.py Refactor boolean input handling to avoid eval and improve type checking. --- utils/console.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utils/console.py b/utils/console.py index a9abf4b..ec7777d 100644 --- a/utils/console.py +++ b/utils/console.py @@ -102,7 +102,10 @@ def handle_input( user_input = input("").strip() if check_type is not False: try: - isinstance(eval(user_input), check_type) # fixme: remove eval + if check_type is bool and isinstance(user_input, str): + if user_input.lower() in ['true', '1', 't', 'y', 'yes', 'yup']: return True + if user_input.lower() in ['false', '0', 'f', 'n', 'no', 'nope']: return False + raise ValueError return check_type(user_input) except: console.print( From 683c8b9740b9e717fc6dcc1ee5c0187fcac79098 Mon Sep 17 00:00:00 2001 From: CoderShady Date: Thu, 9 Apr 2026 17:18:27 +0530 Subject: [PATCH 3/5] Replace eval with TYPE_MAP for type conversion --- utils/settings.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/utils/settings.py b/utils/settings.py index 6b8242b..51e529d 100755 --- a/utils/settings.py +++ b/utils/settings.py @@ -25,12 +25,15 @@ def check(value, checks, name): def get_check_value(key, default_result): return checks[key] if key in checks else default_result + TYPE_MAP = {"bool": bool, "int": int, "float": float, "str": str} + incorrect = False if value == {}: incorrect = True if not incorrect and "type" in checks: try: - value = eval(checks["type"])(value) # fixme remove eval + value = TYPE_MAP.get(checks["type"], str)(value) + except: incorrect = True @@ -78,7 +81,7 @@ def check(value, checks, name): + str(name) + "[#F7768E bold]=", extra_info=get_check_value("explanation", ""), - check_type=eval(get_check_value("type", "False")), # fixme remove eval + check_type=TYPE_MAP.get(get_check_value("type", ""), False), default=get_check_value("default", NotImplemented), match=get_check_value("regex", ""), err_message=get_check_value("input_error", "Incorrect input"), From d1449f1ed609fdc52a21abeb1571ebae82e88bd2 Mon Sep 17 00:00:00 2001 From: CoderShady Date: Thu, 9 Apr 2026 17:30:38 +0530 Subject: [PATCH 4/5] Implement CSRF protection and update secret key Added CSRF protection to prevent remote reconfiguration. --- GUI.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/GUI.py b/GUI.py index 4588083..e11f9c9 100644 --- a/GUI.py +++ b/GUI.py @@ -2,6 +2,7 @@ import webbrowser from pathlib import Path # Used "tomlkit" instead of "toml" because it doesn't change formatting on "dump" +import os import tomlkit from flask import ( Flask, @@ -10,6 +11,7 @@ from flask import ( request, send_from_directory, url_for, + abort, ) import utils.gui_utils as gui @@ -23,7 +25,22 @@ PORT = 4000 app = Flask(__name__, template_folder="GUI") # Configure secret key only to use 'flash' -app.secret_key = b'_5#y2L"F4Q8z\n\xec]/' +app.secret_key = os.urandom(24) + +# CSRF Protection to prevent remote reconfiguration +@app.before_request +def csrf_protect(): + if request.method == "POST": + origin = request.headers.get("Origin") + referer = request.headers.get("Referer") + allowed_origins = [f"http://{HOST}:{PORT}", f"http://127.0.0.1:{PORT}"] + + if origin and origin not in allowed_origins: + abort(403) + if referer and not any(referer.startswith(o) for o in allowed_origins): + abort(403) + if not origin and not referer: + abort(403) # Ensure responses aren't cached From b55f20b0c49000782a506b1cdfc395955081415f Mon Sep 17 00:00:00 2001 From: CoderShady Date: Thu, 9 Apr 2026 17:31:15 +0530 Subject: [PATCH 5/5] Update gui_utils.py --- utils/gui_utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/gui_utils.py b/utils/gui_utils.py index 31c135f..f02141b 100644 --- a/utils/gui_utils.py +++ b/utils/gui_utils.py @@ -44,9 +44,11 @@ def check(value, checks): if value == "False": value = "" + TYPE_MAP = {"bool": bool, "int": int, "float": float, "str": str} + if not incorrect and "type" in checks: try: - value = eval(checks["type"])(value) # fixme remove eval + value = TYPE_MAP.get(checks["type"], str)(value) except Exception: incorrect = True