Skip to content

Hide explorer upstream exception details#5482

Closed
rogierx wants to merge 2 commits into
Scottcjn:mainfrom
rogierx:bounty-5449-explorer-upstream-errors
Closed

Hide explorer upstream exception details#5482
rogierx wants to merge 2 commits into
Scottcjn:mainfrom
rogierx:bounty-5449-explorer-upstream-errors

Conversation

@rogierx
Copy link
Copy Markdown
Contributor

@rogierx rogierx commented May 16, 2026

Fixes #5449.

Summary

  • stops the explorer API from returning raw upstream requests exception strings to clients
  • logs full upstream failures server-side with route-specific context
  • preserves the existing /api/miners fallback shape with miners: []
  • adds regression coverage for /api/miners, /api/network/stats, and /api/miner/<id> using a host/token/path-bearing upstream exception

Validation

  • /tmp/rustchain-5449-venv/bin/python -m pytest tests/test_explorer_app_upstream_errors.py -q -> 3 passed
  • /tmp/rustchain-5449-venv/bin/python -m py_compile explorer/app.py tests/test_explorer_app_upstream_errors.py
  • git diff --check

@github-actions
Copy link
Copy Markdown
Contributor

Welcome to RustChain! Thanks for your first pull request.

Before we review, please make sure:

  • Non-doc PRs have a BCOS-L1 or BCOS-L2 label
  • Doc-only PRs are exempt from BCOS tier labels when they only touch docs/**, *.md, or common image/PDF files
  • New code files include an SPDX license header
  • You've tested your changes against the live node

Bounty tiers: Micro (1-10 RTC) | Standard (20-50) | Major (75-100) | Critical (100-150)

A maintainer will review your PR soon. Thanks for contributing!

@github-actions github-actions Bot added BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) tests Test suite changes size/M PR: 51-200 lines labels May 16, 2026
@rogierx
Copy link
Copy Markdown
Contributor Author

rogierx commented May 16, 2026

I tried to add the required BCOS tier label, but fork contributors do not have label permissions (AddLabelsToLabelable is denied for this account). Suggested tier: BCOS-L1 for this small information-disclosure hardening patch.

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

@HoangTechCS-AIE HoangTechCS-AIE left a comment

Choose a reason for hiding this comment

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

I validated the functional hardening path on head 92c003371519ef87432a7252af4486711a6fb035:

  • python3 -m py_compile explorer/app.py tests/test_explorer_app_upstream_errors.py passed
  • python3 -m pytest tests/test_explorer_app_upstream_errors.py -q passed with 3 passed in 0.07s
  • git diff --check origin/main...HEAD -- explorer/app.py tests/test_explorer_app_upstream_errors.py passed

The exception redaction itself looks correct: all three affected API routes now catch requests.exceptions.RequestException, log the full upstream failure server-side via app.logger.exception(...), and return a stable generic client-visible error. The /api/miners fallback shape also keeps miners: [], which matches the existing API contract.

Blocking issue before merge: the newly added code file tests/test_explorer_app_upstream_errors.py is missing an SPDX header. The repo enforces this for added code-like files via tools/bcos_spdx_check.py; running python3 tools/bcos_spdx_check.py --base-ref origin/main currently fails with:

BCOS SPDX check failed. Add an SPDX header to the following new files:
- tests/test_explorer_app_upstream_errors.py

Please add the project-appropriate header near the top of the new test file, e.g. # SPDX-License-Identifier: MIT, then this should be ready from the explorer behavior/security side.

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 and verified.

This PR addresses the information-disclosure issue in #5449 for the three affected explorer API routes. The client-visible responses now use the shared generic error string, and /api/miners preserves its existing fallback shape with miners: [].

Validation run:

git fetch origin pull/5482/head:review-pr-5482 --force
git diff --check origin/main...review-pr-5482 -- explorer/app.py tests/test_explorer_app_upstream_errors.py
python -m py_compile explorer/app.py tests/test_explorer_app_upstream_errors.py
python -m pytest tests/test_explorer_app_upstream_errors.py -q

I ran the compile and targeted pytest checks from a temporary archive of the PR head. Result:

3 passed in 0.23s

The regression test covers:

/api/miners         -> {"error": "Upstream RustChain API unavailable", "miners": []}
/api/network/stats  -> {"error": "Upstream RustChain API unavailable"}
/api/miner/alice    -> {"error": "Upstream RustChain API unavailable"}

It also asserts the simulated leaked substrings are absent from the response body: 127.0.0.1, 8000, super-secret, /srv/rustchain/private, and node.py.

No blocking issue found.

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!

@rogierx
Copy link
Copy Markdown
Contributor Author

rogierx commented May 16, 2026

Addressed the SPDX blocker in c04035f: added the missing SPDX header to tests/test_explorer_app_upstream_errors.py. No behavior changes.

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.

Approving after validating the current head c04035f. The earlier review concern about the new regression file missing an SPDX header is resolved on this head, and the focused upstream-error redaction path still passes.

Focused validation:

python -m py_compile explorer/app.py tests/test_explorer_app_upstream_errors.py
passed

python -m pytest tests/test_explorer_app_upstream_errors.py -q
...                                                                      [100%]
3 passed in 0.44s

The three covered API routes now return stable generic client-visible errors while preserving the /api/miners response shape with miners: []; full upstream exception detail remains server-side only via logging.

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! Thanks for contributing. Approved.

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 #5482 at head c04035f.

Validation performed:

  • Checked issue #5449. The scoped bug is the explorer API returning raw upstream requests exception text on /api/miners, /api/network/stats, and /api/miner/<miner_id>.
  • git fetch origin pull/5482/head:review-pr-5482 --force
  • git diff --check origin/main...review-pr-5482 -- explorer/app.py tests/test_explorer_app_upstream_errors.py -> passed.
  • python -m py_compile explorer/app.py tests/test_explorer_app_upstream_errors.py on an extracted PR-head tree -> passed.
  • python -m pytest tests/test_explorer_app_upstream_errors.py -q --confcutdir= -> 3 passed.
  • Ran Flask test-client probes with an upstream exception containing host, port, token, path, and filename details. /api/miners returned 500 with {"error":"Upstream RustChain API unavailable","miners":[]}; /api/network/stats and /api/miner/alice returned 500 with the generic upstream-unavailable error. None of the sensitive substrings appeared in the client-visible response bodies.

The explorer routes now preserve the /api/miners fallback shape while keeping upstream connection details out of client JSON. Approving.

@BossChaos
Copy link
Copy Markdown
Contributor

Code Review — Bounty #73

PR: Hide explorer upstream exception details by @rogierx
Files changed: 2 (+64/-8)

  • ✅ Code change
  • ✅ Input validation present
  • ✅ Error handling present

Summary

This is a code change PR. Changes appear consistent with project patterns.

Wallet: 0xdaE5d307339074A24F579dB48e7c639359D94904

Reviewing under Bounty #73 — Code Review Bounty Program

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

@kekehanshujun kekehanshujun left a comment

Choose a reason for hiding this comment

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

Approved. I reviewed the explorer upstream error redaction patch for issue #5449.

Validation performed:

  • Applied the PR patch locally against the PR base.
  • git diff --check -- explorer/app.py tests/test_explorer_app_upstream_errors.py passed; the only local note was the existing CRLF/LF normalization warning for explorer/app.py.
  • python -B -m py_compile explorer/app.py tests/test_explorer_app_upstream_errors.py passed.
  • python -B -m pytest -q tests/test_explorer_app_upstream_errors.py --noconftest -> 3 passed.

The implementation replaces client-visible raw requests exception text with a shared generic upstream-unavailable response, keeps the existing /api/miners fallback shape with miners: [], and logs the detailed upstream exception server-side with route-specific context. The regression test covers all three affected API routes and checks that host, token, and private path substrings are not leaked.

@BossChaos
Copy link
Copy Markdown
Contributor

Code Review — Bounty #73

PR: Hide explorer upstream exception details by @rogierx

  • ✅ Code review

Wallet: 0xdaE5d307339074A24F579dB48e7c639359D94904

Reviewing under Bounty #73

Copy link
Copy Markdown
Contributor

@508704820 508704820 left a comment

Choose a reason for hiding this comment

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

Hide explorer upstream exception details. Good - prevents leaking internal service URLs and error details. Verify all upstream error handlers follow this pattern. - Xeophon (security 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

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

Approved. I focused on the explorer upstream-error redaction path.

Validation performed on head c04035f27dbe944a6f8b1317169345ea7284370b:

  • git diff --check origin/main...HEAD -- explorer/app.py tests/test_explorer_app_upstream_errors.py passed.
  • python3 -B -m py_compile explorer/app.py tests/test_explorer_app_upstream_errors.py passed.
  • uv run --no-project --with pytest --with flask --with requests python -B -m pytest -q -o addopts= tests/test_explorer_app_upstream_errors.py --noconftest -p no:cacheprovider passed with 3 passed in 0.23s.
  • A Flask runtime probe monkeypatched requests.get() to raise HTTPConnectionPool(host='127.0.0.1', port=8000): token=super-secret trace=/srv/rustchain/private/node.py; /api/miners, /api/network/stats, and /api/miner/alice all returned HTTP 500 with the generic Upstream RustChain API unavailable JSON shape and leaks=false for the host/token/private-path strings.

The public response boundary is clean now: upstream exception details stay out of API JSON, /api/miners keeps the existing miners: [] client shape, and the full exception is only logged internally for operators.

@508704820
Copy link
Copy Markdown
Contributor

Security Review ✅

Same class as #5545: stops explorer from returning raw upstream exception strings. Logs failures server-side, returns generic error.

Reviewed by Xeophon - Solana: Lt9nERv6VHsojw15LpFeiaabuphAggzfLF9sM9UXRrZ

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 duplicate of #5450 by @hungle123-dev (first-posted 5h earlier on the same issue).

Per first-poster rule, only the original submitter gets bounty credit on a given issue. The fix in #5450 addresses the same root cause and is already under review.

Appreciate the effort — for next time, please check open PRs against the same issue before filing. Thanks for the contribution.

@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) size/M PR: 51-200 lines tests Test suite changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Explorer API leaks upstream connection exception details