Repository navigation
Local request origin checks, single-use approvals under clock rollback, browser cleanup and migration logging - #15
Merged
Conversation
…k, browser cleanup and migration logging The local server ran any request it received. A web page open in the browser could send a text/plain POST to the local port with its own Origin, or reach it under a foreign Host name (DNS rebinding), and create projects or cancel running work. Local mode now checks every request before reading its body or touching the runtime or storage: - Host must be 127.0.0.1, localhost or [::1] on any port; otherwise 403 LOCAL_HOST_REJECTED. - A request that can change state and carries an Origin must come from an http Origin on one of those names; otherwise 403 LOCAL_ORIGIN_REJECTED. Local programs that send no Origin still work. - /rpc, /rpc/query, /rpc/async and operation cancel require an application/json body; otherwise 415 JSON_CONTENT_TYPE_REQUIRED. - A rejected request writes nothing, the response never echoes the received headers, and no CORS headers or settings are added. Hosted review mode is unchanged. The built-in UI, the Vite development proxy and local JSON clients behave as before. docs/KNOWN_LIMITATIONS states the local single-user premise and that these checks are not authentication. Reading a page with the headless browser could also lose a page it had already captured: closing the browser ran inside the reading deadline, and its own 2 second limit raised over the result. Under machine load the research step then recorded zero sources. - The reading deadline now covers launch and capture only. Cleanup runs afterwards: 2 seconds for a graceful close, then this call's driver is stopped so the browser is forced to exit, observed for up to 2 more seconds. A slow close is logged and keeps the captured page. - If cleanup cannot be confirmed, the call fails with ANONYMOUS_BROWSER_CLEANUP_UNCONFIRMED instead of leaving a process behind silently. Read failures, read timeouts and outside cancellation behave as before. Tests pin the local HTTP behavior before and after the checks (57 observations), and 12 parallel runs of the browser tests that failed 11 of 12 before this change pass 12 of 12 with no leftover browser process. A real browser attack, DNS rebinding and the Vite proxy were not exercised end to end. A single-use approval could be consumed twice when the system clock moved backwards: the current approval revision was chosen by created_at, so the earlier-stamped CONSUMED revision did not read as current. The current revision is now chosen by storage order, only the latest revision of each approval counts, and consumption checks in its transaction that the expected revision is current and not superseded; otherwise it is refused with reason_code AUTHORIZATION_ALREADY_CONSUMED and writes nothing. The normal response is unchanged: a second start reports the step as protected and creates no new attempt. Past records are not modified and there is no schema change. Running database migrations disabled every logger that existed before the workspace was opened (fileConfig's default), so THOTH diagnostics stopped reaching the console. Existing loggers now stay enabled; log levels are unchanged. Verification: the full local check (Python 5246 tests, web tests, lint, typecheck, build, architecture and module budget, README smoke) ran on the origin-check and browser changes; its only failures were four browser cleanup log assertions caused by the migration logging issue, which is fixed here. The approval and logging changes were verified with their focused and existing regression tests.
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.
The local server ran any request it received. A web page open in the
browser could send a text/plain POST to the local port with its own
Origin, or reach it under a foreign Host name (DNS rebinding), and create
projects or cancel running work. Local mode now checks every request
before reading its body or touching the runtime or storage:
403 LOCAL_HOST_REJECTED.
an http Origin on one of those names; otherwise 403
LOCAL_ORIGIN_REJECTED. Local programs that send no Origin still work.
application/json body; otherwise 415 JSON_CONTENT_TYPE_REQUIRED.
received headers, and no CORS headers or settings are added. Hosted
review mode is unchanged.
The built-in UI, the Vite development proxy and local JSON clients
behave as before. docs/KNOWN_LIMITATIONS states the local single-user
premise and that these checks are not authentication.
Reading a page with the headless browser could also lose a page it had
already captured: closing the browser ran inside the reading deadline,
and its own 2 second limit raised over the result. Under machine load
the research step then recorded zero sources.
afterwards: 2 seconds for a graceful close, then this call's driver is
stopped so the browser is forced to exit, observed for up to 2 more
seconds. A slow close is logged and keeps the captured page.
ANONYMOUS_BROWSER_CLEANUP_UNCONFIRMED instead of leaving a process
behind silently. Read failures, read timeouts and outside cancellation
behave as before.
Tests pin the local HTTP behavior before and after the checks (57
observations), and 12 parallel runs of the browser tests that failed 11
of 12 before this change pass 12 of 12 with no leftover browser process.
A real browser attack, DNS rebinding and the Vite proxy were not
exercised end to end.
A single-use approval could be consumed twice when the system clock
moved backwards: the current approval revision was chosen by created_at,
so the earlier-stamped CONSUMED revision did not read as current. The
current revision is now chosen by storage order, only the latest
revision of each approval counts, and consumption checks in its
transaction that the expected revision is current and not superseded;
otherwise it is refused with reason_code AUTHORIZATION_ALREADY_CONSUMED
and writes nothing. The normal response is unchanged: a second start
reports the step as protected and creates no new attempt. Past records
are not modified and there is no schema change.
Running database migrations disabled every logger that existed before
the workspace was opened (fileConfig's default), so THOTH diagnostics
stopped reaching the console. Existing loggers now stay enabled; log
levels are unchanged.
Verification: the full local check (Python 5246 tests, web tests, lint,
typecheck, build, architecture and module budget, README smoke) ran on
the origin-check and browser changes; its only failures were four
browser cleanup log assertions caused by the migration logging issue,
which is fixed here. The approval and logging changes were verified with
their focused and existing regression tests.