[security] fix(web): protect web control plane by default#4
Closed
Hinotoi-agent wants to merge 1 commit intoShun-Calvin:mainfrom
Closed
[security] fix(web): protect web control plane by default#4Hinotoi-agent wants to merge 1 commit intoShun-Calvin:mainfrom
Hinotoi-agent wants to merge 1 commit intoShun-Calvin:mainfrom
Conversation
- bind web server to loopback by default - require bearer auth for exposed API and Socket.IO control paths - add regression coverage for unauthenticated config and submit requests
Author
|
Closing at the author's request. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR hardens the web frontend control plane added on the PR HKUDS#87 branch so it is not network-exposed without an explicit authentication boundary.
It makes three focused changes:
oh webto loopback by default instead of all interfaces/api/configand/api/submitrequestsSecurity issues covered
Before this PR
oh webdefaulted to0.0.0.0, making the web backend reachable from other hosts on the same network or any exposed interface./api/configaccepted unauthenticated state-changing requests, includingpermission_modeupdates that normalizeautotofull_auto./api/submitaccepted unauthenticated prompts and forwarded them into the active runtime viabackend_host.handle_request(...).After this PR
oh webandrun_web_server()default to127.0.0.1.0.0.0.0now requires an explicit bearer token via--auth-tokenorOPENHARNESS_WEB_AUTH_TOKEN./api/*routes requireAuthorization: Bearer <token>when a web auth token is configured, while/api/healthremains unauthenticated for health checks.Why this matters
The web backend is a control plane for a running coding agent. If it is reachable from a network interface without authentication, an unauthenticated caller can influence runtime settings and submit arbitrary prompts into the agent session.
The most important boundary is therefore not just “browser UI access”; it is whether a remote client can reach endpoints that mutate agent behavior or drive the runtime.
Attack flow
Affected code
src/openharness/cli.py,src/openharness/web_server.pytests/test_web_server_security.pyRoot cause
Unauthenticated web control plane:
CVSS assessment
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HRationale: when the web port is network-reachable, no credentials or user interaction are required to drive control-plane behavior that can affect agent confidentiality, integrity, and availability. The practical impact still depends on the deployment being reachable beyond localhost and on the runtime permissions/tools available to the agent.
Safe reproduction steps
On the vulnerable PR HKUDS#87 branch, a local
TestClientharness with a fake runtime bundle showed that unauthenticated requests reached the runtime sinks:The new regression tests encode the same boundary with fake settings/runtime objects so the test does not write real local OpenHarness configuration.
Expected vulnerable behavior
Before this PR, unauthenticated callers could receive successful responses from both:
and those requests could update runtime permission state and submit a prompt into the agent session.
Changes in this PR
0.0.0.0to127.0.0.1in both CLI and server defaults.--auth-tokenandOPENHARNESS_WEB_AUTH_TOKENsupport for explicit authenticated web deployments./api/*, excluding/api/health.Files changed
src/openharness/cli.py--auth-tokenaddedsrc/openharness/web_server.pytests/test_web_server_security.pyMaintainer impact
oh webcontinues to work on127.0.0.1without a token.Fix rationale
The safest default for a local agent control plane is loopback-only access. Non-loopback access is still available, but it must be paired with an explicit authentication token so deployments do not accidentally expose prompt submission and runtime configuration endpoints to a network.
The tests lock in both sides of that behavior: unauthenticated control-plane requests are denied when auth is configured, while correctly authenticated requests still reach the intended runtime handlers.
Type of change
Test plan
TestClientharness.git diff --check.Executed with:
PYTHONPATH=src:. uv run pytest -o addopts='' tests/test_web_server_security.py -q PYTHONPATH=src:. uv run python -m compileall -q src/openharness/web_server.py src/openharness/cli.py tests/test_web_server_security.py git diff --check uv run ruff check src/openharness/web_server.py src/openharness/cli.py tests/test_web_server_security.pyNote:
uv run ruff format --checkreports broad pre-existing formatting churn in legacy files such assrc/openharness/cli.pyandsrc/openharness/web_server.py, so I did not include unrelated whole-file formatting changes in this security PR. The new test file was formatted with Ruff.Disclosure notes