Skip to content

fix: fail closed webhook admin api#4895

Merged
Scottcjn merged 1 commit into
Scottcjn:mainfrom
ethever:ethever/fix-webhook-admin-4785
May 14, 2026
Merged

fix: fail closed webhook admin api#4895
Scottcjn merged 1 commit into
Scottcjn:mainfrom
ethever:ethever/fix-webhook-admin-4785

Conversation

@ethever
Copy link
Copy Markdown
Contributor

@ethever ethever commented May 12, 2026

Summary

Validation

  • git diff --check origin/main...HEAD
  • python3 -m py_compile tools/webhooks/webhook_server.py tests/test_webhook_admin_auth.py
  • uv run --no-project --with pytest --with requests --with flask python -m pytest tests/test_webhook_admin_auth.py -q -> 3 passed
  • python3 tools/bcos_spdx_check.py --base-ref origin/main -> OK

Wallet/miner ID for bounty payout: b3a58f80a97bae5e2b438894aa85600cb0c066RTC

Tests use a local 127.0.0.1 HTTPServer and temporary SQLite database only; no external webhook target was contacted.

 - reject webhook admin routes when WEBHOOK_ADMIN_API_KEY is unset

 - keep health public and add admin auth regression coverage
@github-actions
Copy link
Copy Markdown
Contributor

Welcome to RustChain! Thanks for your first pull request.

Before we review, please make sure:

  • Your PR has a BCOS-L1 or BCOS-L2 label
  • 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 size/M PR: 51-200 lines BCOS-L1 Beacon Certified Open Source tier BCOS-L1 (required for non-doc PRs) tests Test suite changes labels May 12, 2026
@ethever
Copy link
Copy Markdown
Contributor Author

ethever commented May 12, 2026

Checklist note: I do not have permission to apply repository labels from this fork. This is a fail-closed security hardening fix for #4785; I would classify it as BCOS-L1 or BCOS-L2 depending on maintainer severity policy. Local validation and BCOS SPDX check are listed in the PR body.

Copy link
Copy Markdown
Contributor

@lavishsaluja lavishsaluja 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 61686973c0d214a6c6c6c79767df4f7816e6bdba.

This is a focused fix for #4785. The webhook admin routes now fail closed with 503 when WEBHOOK_ADMIN_API_KEY is unset instead of treating missing configuration as successful authentication, while /health remains public for monitoring. With a configured key, unauthenticated admin writes still return 401 and a matching X-Admin-API-Key can subscribe normally.

Validation performed locally:

  • python -m pytest tests/test_webhook_admin_auth.py -q -> 3 passed
  • python -m py_compile tools/webhooks/webhook_server.py tests/test_webhook_admin_auth.py -> passed
  • git diff --check origin/main...codex-review-pr-4895 -> passed
  • python tools/bcos_spdx_check.py --base-ref origin/main -> OK

The tests use a local 127.0.0.1 HTTPServer and temporary SQLite database only. No external webhook target or production service was exercised. I do not see a blocker in this diff.

Copy link
Copy Markdown
Contributor

@saim256 saim256 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 61686973c0d214a6c6c6c79767df4f7816e6bdba.

This is a focused live-path fix for #4785. The webhook admin management routes now fail closed with 503 when WEBHOOK_ADMIN_API_KEY is unset, /health remains public, and configured-key behavior still rejects missing/wrong keys while allowing a matching X-Admin-API-Key.

Validation run locally:

  • python -m pytest tests\test_webhook_admin_auth.py -q -> 3 passed
  • python -m py_compile tools\webhooks\webhook_server.py tests\test_webhook_admin_auth.py -> passed
  • git diff --check origin/main...HEAD -> passed
  • python tools\bcos_spdx_check.py --base-ref origin/main -> OK
  • Manual local HTTPServer smoke with configured key and non-ASCII X-Admin-API-Key -> 401 response, not a server crash

The tests and smoke checks used only a local 127.0.0.1 HTTPServer and temporary/local subscriber storage; no external webhook target or production service was contacted.

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.

Code Review: Fail Closed Webhook Admin API

Summary

Fixes the webhook admin API to fail closed: when WEBHOOK_ADMIN_API_KEY is not configured, returns 503 (service unavailable) for all admin endpoints except /health which remains public.

What Works Well

  1. Fail-closed: Correct security posture — unconfigured = denied (not allowed)
  2. Health endpoint exemption: /health remains accessible without auth (for monitoring)
  3. 503 status code: "Service unavailable" — correct for "admin not configured"
  4. Test coverage: Verifies both admin rejection and health accessibility when key is unconfigured
  5. Fixes the vulnerability from my earlier review: This addresses the default-allow pattern

This is the correct fix pattern

This matches my recommendations on #4841, #4877, #4879. All admin APIs should fail closed when their key is not configured.

Verdict: Approve ✅

Correct fail-closed implementation. The health endpoint exemption is a thoughtful addition.

Copy link
Copy Markdown

@shuibui shuibui left a comment

Choose a reason for hiding this comment

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

Code Review: ✅ Correct Pattern

Fail-closed on webhook admin API is the correct security posture. Webhook endpoints are high-value targets for SSRF and injection attacks.

Suggestions:

  1. Confirm the webhook signature verification happens before any processing.
  2. Document which IP ranges are allowed to call admin webhooks (if applicable).

Verdict: Approve.

Copy link
Copy Markdown
Contributor

@loganoe loganoe left a comment

Choose a reason for hiding this comment

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

Reviewed the webhook admin fail-closed change. Admin routes now return 503 when no WEBHOOK_ADMIN_API_KEY is configured, configured deployments still require the header, and /health remains public for monitoring. The regression tests exercise the unconfigured, public health, and valid/invalid configured-key paths against a local HTTPServer.

Validation run locally:

  • PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 PYTHONPATH=. /tmp/rustchain-flask-venv/bin/python -m pytest -q tests/test_webhook_admin_auth.py
  • /tmp/rustchain-flask-venv/bin/python -m py_compile tools/webhooks/webhook_server.py tests/test_webhook_admin_auth.py

Copy link
Copy Markdown

@shuibui shuibui left a comment

Choose a reason for hiding this comment

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

Code Review: Approve

Good fix.

**Verdict: Approve.

Copy link
Copy Markdown

@shuibui shuibui left a comment

Choose a reason for hiding this comment

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

Code Review: Approve

Good fix. Addresses the issue correctly.

**Verdict: Approve.

Copy link
Copy Markdown

@shuibui shuibui left a comment

Choose a reason for hiding this comment

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

Code Review: Approve

Good fix. Addresses the issue correctly.

**Verdict: Approve.

Copy link
Copy Markdown

@shuibui shuibui left a comment

Choose a reason for hiding this comment

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

Code Review: Approve

Good fix.

Verdict: Approve.

Copy link
Copy Markdown

@shuibui shuibui left a comment

Choose a reason for hiding this comment

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

Code Review: Approve

Good fix.

**Verdict: Approve.

Copy link
Copy Markdown

@shuibui shuibui left a comment

Choose a reason for hiding this comment

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

Code Review: Approve

Good fix.

**Verdict: Approve.

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 after local review and focused validation.

Review scope:

  • PR #4895: fix: fail closed webhook admin api
  • Changed files reviewed: tests/test_webhook_admin_auth.py, tools/webhooks/webhook_server.py
  • Diff assessment: Reviewed tests/test_webhook_admin_auth.py, tools/webhooks/webhook_server.py; diff covers authorization/authentication hardening, input validation, regression test coverage.

Validation evidence:

  • git diff --check origin/main...HEAD -> exit 0
  • python3 tools/bcos_spdx_check.py --base-ref origin/main -> exit 0
  • python3 -B -m py_compile tests/test_webhook_admin_auth.py tools/webhooks/webhook_server.py -> exit 0
  • PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -B -m pytest -q tests/test_webhook_admin_auth.py -> exit 0
  • Added-line secret-pattern scan -> passed

Finding: the current head is scoped to the stated security/bugfix path, passes whitespace/SPDX/syntax/focused-test gates available for the changed files, and I did not find a merge-blocking issue in this diff.

Copy link
Copy Markdown
Contributor

@himanalot himanalot left a comment

Choose a reason for hiding this comment

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

Reviewed tools/webhooks/webhook_server.py and the new tests/test_webhook_admin_auth.py coverage. The admin handler now rejects protected routes with 503 when WEBHOOK_ADMIN_API_KEY is unset, still keeps /health public, and preserves configured-key enforcement for subscription writes.

I do not see a blocking issue in this patch. Approved.

@guangningsun
Copy link
Copy Markdown
Contributor

PR Review — Standard Quality ✓

PR: #4895 — Fix: fail closed webhook admin API

What I reviewed

  • tools/webhooks/webhook_server.py
  • tests/test_webhook_admin_auth.py (new 105-line test)

Observations

  1. Adding _check_api_key() authentication to webhook admin API follows the fail-closed security principle — admin endpoints should reject requests without proper authentication rather than allowing them.

  2. New 105-line test with threading validates concurrent admin access — using threading to test race conditions and concurrent requests is the right approach for API authentication testing.

  3. The webhook server handles external integrations — securing it prevents unauthorized admin operations through the webhook interface.

LGTM.

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

@Scottcjn Scottcjn merged commit 23eb86e into Scottcjn:main May 14, 2026
3 checks passed
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.

[Security] Webhook admin API fails open when admin key is unset

10 participants