fix: disable public Flask debug entrypoints#5561
Conversation
strongkeep-debug
left a comment
There was a problem hiding this comment.
The patch cleanly closes the public-debug default from #4810 without expanding the service surface. I checked the prior #4926 attempt was closed unmerged; this PR covers the same reported public entrypoint list and adds the faucet CLI/docs hardening that was not in the original issue list.
Validation on head 827ff6e:
git diff --check origin/main...HEAD
# passed
python -m py_compile tests/test_flask_debug_disabled.py bridge/bridge_api.py contributor_registry.py explorer/app.py faucet_service/faucet_service.py keeper_explorer.py security_test_payment_widget.py
# passed; existing keeper_explorer string warning only
python -m pytest -q tests/test_flask_debug_disabled.py
# 1 passed, 1 warning
The new AST regression is a useful fit for this class of bug because it catches both app.run(..., debug=True) and future direct config['debug'] = True regressions on the listed public entrypoints. LGTM.
ZacharyZhang-NY
left a comment
There was a problem hiding this comment.
Reviewed PR #5561 at commit 827ff6e. The patch removes hard-coded Flask debug=True from the public entrypoints listed in #4810, keeps faucet_service --debug from enabling Flask debug mode, and updates the faucet docs away from debug startup. Validation passed: git diff --check for the changed files; py_compile for the affected Python files; tests/test_flask_debug_disabled.py passed with 1 passed; static rg check found no app.run debug=True, debug=True assignment, or config['server']['debug']=True matches across the listed public entrypoints. I did not find a blocking issue in this patch.
TJCurnutte
left a comment
There was a problem hiding this comment.
Requesting changes because the debug-mode sweep is still incomplete.
Validation I ran from a detached PR worktree:
git diff --check origin/main...HEAD -- bridge/bridge_api.py contributor_registry.py explorer/app.py faucet_service/IMPLEMENTATION_SUMMARY.md faucet_service/README.md faucet_service/faucet_service.py keeper_explorer.py security_test_payment_widget.py tests/test_flask_debug_disabled.py
python3 -B -m py_compile bridge/bridge_api.py contributor_registry.py explorer/app.py faucet_service/faucet_service.py keeper_explorer.py security_test_payment_widget.py tests/test_flask_debug_disabled.py profile_badge_generator.py xss_poc_templates.py
python3 -B -m pytest -q tests/test_flask_debug_disabled.py
# 1 passed, 2 warnings in 0.06sThe added regression test passes, but it only checks the files listed in PUBLIC_FLASK_ENTRYPOINTS. A broader AST probe for direct app.run(debug=True) calls still finds:
DEBUG_TRUE profile_badge_generator.py:249
DEBUG_TRUE xss_poc_templates.py:421
The blocker is profile_badge_generator.py. It is a real Flask service-style entrypoint, not just a README snippet: it registers /badge/generator, /api/badge/create, and /api/badge/list, writes to rustchain.db, and still ends with app.run(debug=True, port=5003). That leaves a public badge-generator surface under the Flask debugger while the PR/test claim public Flask debug entrypoints are disabled.
Please either include profile_badge_generator.py in the fix and regression list, or narrow/document the scope so intentionally excluded PoC-only files are not presented as covered. I am not blocking on xss_poc_templates.py if it is deliberately a local PoC harness, but the test should make that boundary explicit.
Live duplicate gates were clear before posting: PR open/non-draft, not self-authored, no existing @TJCurnutte PR review, and no current @TJCurnutte bounty-issue claim for this PR.
jaxint
left a comment
There was a problem hiding this comment.
LGTM! Great work on this PR. 🚀
iamdinhthuan
left a comment
There was a problem hiding this comment.
Disclosure: I am reviewing this under Scottcjn/rustchain-bounties#73 as @iamdinhthuan.
Reviewed current head da6238ffa278ce45eee3a8a5b7e07bbf188d26f3. The prior profile_badge_generator.py debug=True gap is fixed here and the new test now explicitly treats xss_poc_templates.py as a local PoC exception. I still found two current-head merge blockers.
First, the new regression suite does not pass on this repository checkout. The broad python_sources() scan now parses every Python file, and it aborts on the existing build_static.py syntax error before it can prove the no-debug invariant:
python3 -B -m pytest -q tests/test_flask_debug_disabled.py --noconftest
# 1 failed, 1 passed
# SyntaxError: f-string: expecting '}'
# while parsing build_static.py:407
That means test_no_undocumented_flask_debug_true_entrypoints is currently a failing regression test, even though the public Flask entrypoint-specific test passes. Please either make the broad scan handle/document existing parse-incompatible files, or narrow the regression so it remains a reliable merge gate for the Flask debug surface.
Second, the new test file is missing the required SPDX header:
python3 tools/bcos_spdx_check.py --base-ref origin/main
# BCOS SPDX check failed. Add an SPDX header to:
# tests/test_flask_debug_disabled.py
Other validation I ran on this head:
git diff --check origin/main...HEAD -- bridge/bridge_api.py contributor_registry.py explorer/app.py faucet_service/IMPLEMENTATION_SUMMARY.md faucet_service/README.md faucet_service/faucet_service.py keeper_explorer.py profile_badge_generator.py security_test_payment_widget.py tests/test_flask_debug_disabled.py
python3 -B -m py_compile bridge/bridge_api.py contributor_registry.py explorer/app.py faucet_service/faucet_service.py keeper_explorer.py profile_badge_generator.py security_test_payment_widget.py tests/test_flask_debug_disabled.py
# both passedI would re-check after the SPDX header is added and the broad AST regression no longer fails on build_static.py.
Safety note: no private keys, tokens, wallet secrets, production writes, withdrawals, or fund movement were used.
strongkeep-debug
left a comment
There was a problem hiding this comment.
Approved current head 27f747a6760b7a24e9462256ae71a28129e9d2d7.
The debug-mode sweep is now broader than the earlier entrypoint-only pass. The current head keeps the originally listed public Flask entrypoints at debug=False, covers profile_badge_generator.py and security_test_payment_widget.py, and adds a repository-wide AST guard that skips only the documented local PoC harness plus documented parse-incompatible legacy files.
Validation run on this head:
git diff --check origin/main...HEAD
# passed
python -m py_compile tests/test_flask_debug_disabled.py
# passed
python tools/bcos_spdx_check.py --base-ref origin/main
# passed
uv run --with pytest --with flask --with requests python -m pytest tests/test_flask_debug_disabled.py -q --tb=short
# 2 passed
focused debug-enable string probe excluding the documented local PoC harness and the guard test itself
# unexpected hits: 0
The remaining xss_poc_templates.py debug server is explicitly documented in the test as a local PoC harness, so the merge gate now protects the public Flask surfaces without overreaching into that intentional example.
PR Review — PR #5561Title: fix: disable public Flask debug entrypoints Author: kekehanshujun What I reviewed
Observations
LGTM. Good security fix. Removing debug mode from production entry points is critical. Bounty: #2782 |
|
Closing as stale branch — would cause destructive deletions if merged. Your branch was filed roughly 155 commits behind current main. Since then, many overlapping fixes from other contributors have landed via parallel PRs. GitHub's Bounty credit acknowledgedIf your fix addressed a real bug, the canonical version has very likely already shipped via a parallel contributor's PR over the past two weeks. Specific cases covered by today's audit:
If you want fresh reviewRebase against current main and verify your diff shows roughly the size of the changes you originally made: If the deletion count is significantly higher than what you added, the branch is still picking up stale assumptions — recreate from a fresh main. Thanks for the contribution work this week. |
Summary
0.0.0.0service entrypoints--debugFixes #4810.
Validation
python -B -m pytest -q tests/test_flask_debug_disabled.pypython -B -m py_compile tests/test_flask_debug_disabled.py bridge/bridge_api.py contributor_registry.py explorer/app.py faucet_service/faucet_service.py keeper_explorer.py security_test_payment_widget.pygit diff --checkrg -n app\.run\([^\n]*debug=True|debug\s*=\s*True|config\['server'\]\['debug'\]\s*=\s*True bcos_directory.py explorer/app.py security_test_payment_widget.py bridge/bridge_api.py contributor_registry.py keeper_explorer.py faucet_service/faucet_service.pyBounty
RTC wallet:
RTC02811ff5e2bb4bb4b95eee44c5429cd9525496e7