Repository navigation
Relay fixes round 2, batch 2: dashboard path traversal, MCP errors, query bound - #45
Merged
Merged
Conversation
Calling with actions like 'search:foo' on a page without input[placeholder="Search memories..."] (e.g. wrong route or unauthenticated state) makes `input` null; `input.type` throws TypeError and no screenshot is saved. Found by the GLM relay (memorygate__dashboard__screenshot-interact.mjs_p0__bugs__0), confirmed by GLM votes (round 2). Regression test to add: Run the script with actions 'search:foo' against a route lacking the search input and verify it logs an error, skips the action, and still saves the screenshot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… dist/
GET /..%2F..%2F..%2Fetc%2Fpasswd -> candidate = DIST_DIR/../../../etc/passwd resolves outside dist; candidate.is_file() is True and FileResponse returns the arbitrary system file (the {full_path:path} converter does not reject dot-segments after URL decoding).
Found by the GLM relay (memorygate__dashboard__server.py_p0__bugs__0), confirmed by GLM votes (round 2).
Regression test to add: Test that a GET to /..%2F..%2F..%2Fetc%2Fpasswd returns the SPA index.html (or a non-passwd response) rather than /etc/passwd contents, and that normal files under dist/ still serve.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
If services/api/app/ contains a normal __init__.py (required for `from app import ...` to resolve in most setups), APP.glob("*.py") matches it, and since its name is not main.py the check reports '__init__.py: modules live in a package named for their type' and exits 1 — the invariant check fails on a perfectly legal layout.
Found by the GLM relay (memorygate__scripts__check_package_boundaries.py_p0__bugs__0), confirmed by GLM votes (round 2).
Regression test to add: Add an empty services/api/app/__init__.py and verify the script exits 0 and reports no loose-module or cross-package problems.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A request with an id and an unrecognized method (e.g. "resources/list") falls into the elif "id" branch and gets an empty success result instead of a JSON-RPC Method not found error, so clients believe the capability exists.
Found by the GLM relay (memorygate__services__mcp_p0__bugs__0), confirmed by GLM votes (round 2).
Regression test to add: Send a JSON-RPC request with method "resources/list" and an id, and assert the response contains error code -32601 ("Method not found") rather than an empty result.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A batch payload like "[{\"id\":1,\"method\":\"tools/list\"}]" makes request.get raise AttributeError; the except branch then emits a single response with null id, so the batch's per-item responses are never delivered.
Found by the GLM relay (memorygate__services__mcp_p0__bugs__1), confirmed by GLM votes (round 2).
Regression test to add: A test should feed the line '[{"id":1,"method":"tools/list"}]' to the server and assert it emits an Invalid request error response with null id without crashing or attempting request.get on a list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
memorygate_context's inputSchema imposes no maxLength on 'query' (unlike EXPLORE's strict schema), so a model/client can send an arbitrarily large query string that is forwarded verbatim to the backend, enabling unbounded input / DoS or oversized storage of query text. Found by the GLM relay (memorygate__services__mcp_p0__sec__0), confirmed by GLM votes (round 2). Regression test to add: A regression test should send a memorygate_context tools/call with a query longer than 2000 characters (or missing/non-string) and assert the server returns an error without issuing a request to the backend, while a query at or under the limit still succeeds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The boundary check must still read imports in package __init__.py files (only the loose-module rule allows them). MCP clients send ping; the new Method-not-found branch would have refused it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
GLM relay round 2 (hunt, vote, fix), reviewed by Claude.
../could serve files outsidedist/; now resolved and checked withis_relative_to.interactstep: missingsearchinput no longer crashes.queryis bounded (2000 chars, no extra properties).app/__init__.pyis no longer flagged as a loose module.Review corrections (last commit): the boundary check still reads imports in
__init__.pyfiles (GLM had skipped them, which would hide real edges);pingis answered with{}so MCP clients keep working.Checks: 406 passed locally (
services/api, contract test excluded as in CI); ruff clean; package boundaries ok (12 edges); MCP stdin probe: ping →{}, unknown → error,[1]→ batch error, empty query → error.🤖 Generated with Claude Code