From ae797e8c3c2a02b46d8db120a5743460c0b99cea Mon Sep 17 00:00:00 2001 From: jenkin Date: Wed, 13 May 2026 01:23:21 +0700 Subject: [PATCH] Fix: Remove hardcoded debug=True in Flask entrypoints (#4810) Replaced hardcoded debug=True with environment-controlled FLASK_DEBUG variable and added a regression test. --- bcos_directory.py | 2 +- bridge/bridge_api.py | 2 +- contributor_registry.py | 2 +- explorer/app.py | 3 ++- keeper_explorer.py | 2 +- profile_badge_generator.py | 3 ++- security_test_payment_widget.py | 2 +- tests/test_flask_debug_security.py | 39 ++++++++++++++++++++++++++++++ xss_poc_templates.py | 2 +- 9 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 tests/test_flask_debug_security.py diff --git a/bcos_directory.py b/bcos_directory.py index c16ba0e82..d484027ca 100644 --- a/bcos_directory.py +++ b/bcos_directory.py @@ -482,4 +482,4 @@ def serve_dist(filename): if __name__ == '__main__': init_db() load_projects_from_json() - app.run(debug=True, host='0.0.0.0', port=5000) \ No newline at end of file + app.run(debug=os.environ.get('FLASK_DEBUG') == '1', host='0.0.0.0', port=5000) \ No newline at end of file diff --git a/bridge/bridge_api.py b/bridge/bridge_api.py index b3725932e..34d5bc3e1 100644 --- a/bridge/bridge_api.py +++ b/bridge/bridge_api.py @@ -621,4 +621,4 @@ def register_bridge_routes(app: Flask): app = Flask(__name__) register_bridge_routes(app) print("Bridge dev server on http://0.0.0.0:8096") - app.run(host="0.0.0.0", port=8096, debug=True) + app.run(host="0.0.0.0", port=8096, debug=os.environ.get('FLASK_DEBUG') == '1') diff --git a/contributor_registry.py b/contributor_registry.py index abba61cd4..f6f251099 100644 --- a/contributor_registry.py +++ b/contributor_registry.py @@ -188,4 +188,4 @@ def approve_contributor(username): if __name__ == '__main__': if not os.path.exists(DB_PATH): init_db() - app.run(debug=True, host='0.0.0.0', port=5000) \ No newline at end of file + app.run(debug=os.environ.get('FLASK_DEBUG') == '1', host='0.0.0.0', port=5000) \ No newline at end of file diff --git a/explorer/app.py b/explorer/app.py index 872a1019c..83f40b6b0 100644 --- a/explorer/app.py +++ b/explorer/app.py @@ -1,3 +1,4 @@ +import os from flask import Flask, render_template, jsonify import requests import json @@ -134,4 +135,4 @@ def internal_error(error): return render_template('500.html'), 500 if __name__ == '__main__': - app.run(host='0.0.0.0', port=5000, debug=True) \ No newline at end of file + app.run(host='0.0.0.0', port=5000, debug=os.environ.get('FLASK_DEBUG') == '1') \ No newline at end of file diff --git a/keeper_explorer.py b/keeper_explorer.py index 8a46870e4..385954157 100644 --- a/keeper_explorer.py +++ b/keeper_explorer.py @@ -377,4 +377,4 @@ def faucet_drip(): if __name__ == '__main__': import hashlib # needed for mock hash print(f"[*] Starting Fossil-Punk Keeper Explorer on port {PORT}...") - app.run(host='0.0.0.0', port=PORT, debug=True) + app.run(host='0.0.0.0', port=PORT, debug=os.environ.get('FLASK_DEBUG') == '1') diff --git a/profile_badge_generator.py b/profile_badge_generator.py index 529925bde..05d473675 100644 --- a/profile_badge_generator.py +++ b/profile_badge_generator.py @@ -1,3 +1,4 @@ +import os # SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT @@ -216,4 +217,4 @@ def list_badges(): if __name__ == '__main__': init_badge_db() - app.run(debug=True, port=5003) \ No newline at end of file + app.run(debug=os.environ.get('FLASK_DEBUG') == '1', port=5003) \ No newline at end of file diff --git a/security_test_payment_widget.py b/security_test_payment_widget.py index 5bbc35b31..9d1bdea37 100644 --- a/security_test_payment_widget.py +++ b/security_test_payment_widget.py @@ -272,4 +272,4 @@ def admin_login(): if __name__ == '__main__': if not os.path.exists(DB_PATH): init_db() - app.run(debug=True, host='0.0.0.0', port=5000) \ No newline at end of file + app.run(debug=os.environ.get('FLASK_DEBUG') == '1', host='0.0.0.0', port=5000) \ No newline at end of file diff --git a/tests/test_flask_debug_security.py b/tests/test_flask_debug_security.py new file mode 100644 index 000000000..6eda46cad --- /dev/null +++ b/tests/test_flask_debug_security.py @@ -0,0 +1,39 @@ +import os +import re + +def test_no_hardcoded_flask_debug(): + """ + Regression test to ensure no Flask entrypoints hardcode debug=True. + Safe practice is to use an environment variable. + """ + base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) + affected_files = [ + 'security_test_payment_widget.py', + 'profile_badge_generator.py', + 'xss_poc_templates.py', + 'keeper_explorer.py', + 'contributor_registry.py', + 'bridge/bridge_api.py', + 'explorer/app.py' + ] + + pattern = re.compile(r'app\.run\(.*debug\s*=\s*True', re.IGNORECASE) + + errors = [] + for rel_path in affected_files: + full_path = os.path.join(base_dir, rel_path) + if not os.path.exists(full_path): + continue + + with open(full_path, 'r', encoding='utf-8') as f: + content = f.read() + if pattern.search(content): + errors.append(f"Hardcoded debug=True found in {rel_path}") + + if errors: + print("\n".join(errors)) + exit(1) + +if __name__ == "__main__": + test_no_hardcoded_flask_debug() + print("Test passed: No hardcoded debug=True found.") diff --git a/xss_poc_templates.py b/xss_poc_templates.py index 6f720e971..5b654ec42 100644 --- a/xss_poc_templates.py +++ b/xss_poc_templates.py @@ -418,4 +418,4 @@ def payload_tester(): return template if __name__ == '__main__': - app.run(debug=True, port=5001) \ No newline at end of file + app.run(debug=os.environ.get('FLASK_DEBUG') == '1', port=5001) \ No newline at end of file