Skip to content

fix: disable public Flask debug entrypoints#5561

Closed
kekehanshujun wants to merge 4 commits into
Scottcjn:mainfrom
kekehanshujun:codex/flask-debug-entrypoints-4810
Closed

fix: disable public Flask debug entrypoints#5561
kekehanshujun wants to merge 4 commits into
Scottcjn:mainfrom
kekehanshujun:codex/flask-debug-entrypoints-4810

Conversation

@kekehanshujun
Copy link
Copy Markdown
Contributor

Summary

Fixes #4810.

Validation

  • python -B -m pytest -q tests/test_flask_debug_disabled.py
  • python -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.py
  • git diff --check
  • rg -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.py

Bounty

RTC wallet: RTC02811ff5e2bb4bb4b95eee44c5429cd9525496e7

@github-actions github-actions Bot added documentation Improvements or additions to documentation BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) BCOS-L2 Beacon Certified Open Source tier BCOS-L2 (required for non-doc PRs) security Security-related change tests Test suite changes size/M PR: 51-200 lines labels May 17, 2026
Copy link
Copy Markdown

@strongkeep-debug strongkeep-debug left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown

@ZacharyZhang-NY ZacharyZhang-NY left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown

@TJCurnutte TJCurnutte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.06s

The 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.

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown
Contributor

@jaxint jaxint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Great work on this PR. 🚀

Copy link
Copy Markdown
Contributor

@iamdinhthuan iamdinhthuan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 passed

I 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.

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown

@strongkeep-debug strongkeep-debug left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@guangningsun
Copy link
Copy Markdown
Contributor

PR Review — PR #5561

Title: fix: disable public Flask debug entrypoints

Author: kekehanshujun

What I reviewed

  • bridge/bridge_api.py
  • contributor_registry.py
  • explorer/app.py

Observations

  1. Removes debug=True from Flask app.run() calls in multiple files — bridge/bridge_api.py, contributor_registry.py, and explorer/app.py.
  2. Each file has a single-line change (+1/-1).
  3. This is a security fix — Flask debug mode exposes the Werkzeug debugger and interactive console, which should never be enabled on public-facing servers.
  4. Minimal, focused fix addressing a serious security issue.

LGTM. Good security fix. Removing debug mode from production entry points is critical.

Bounty: #2782
Disclosure: I received RTC compensation for this review.

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown
Contributor

@HCIE2054 HCIE2054 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@Scottcjn
Copy link
Copy Markdown
Owner

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 mergeable=clean indicator only catches text-level conflicts — it doesn't detect "this branch is so old that merging would silently delete code that landed after it was filed."

Bounty credit acknowledged

If 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 review

Rebase against current main and verify your diff shows roughly the size of the changes you originally made:

git fetch upstream main
git rebase upstream/main
git diff main..HEAD --shortstat

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.

@Scottcjn Scottcjn closed this May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) BCOS-L2 Beacon Certified Open Source tier BCOS-L2 (required for non-doc PRs) documentation Improvements or additions to documentation security Security-related change size/M PR: 51-200 lines tests Test suite changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SECURITY] Public Flask entrypoints enable debug mode by default

9 participants