Repository navigation
OpenConceptLab/ocl_online#553 | 0.2.1: encode identifiers as path segments, tighten the origin check - #15
Conversation
…ments, tighten the origin check - Every ID, version, key or queue name the client puts in a request path is quoted as one segment. An empty value, ".", ".." or a value containing "/" raises APIError (status_code 0) before anything is sent. search_repos now validates owner_type, like the other methods. - `ocl tool recreate-collection` quotes the collection paths it builds, and refuses an export whose collection ID would name another endpoint. - The origin check compares hosts in their encoded form, refuses URLs that carry credentials, and checks a base_url path prefix against the path as a server that decodes and normalizes it would route it. A host that isn't a valid domain name raises APIError instead of idna's error. - Version 0.2.1. The README says what the library refuses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QvHhCgtEqAD6xKyJAbToDH
…of the path; exports need a version - A base_url path prefix must hold for the path as sent, with dot segments resolved, and with backslashes read as slashes. Reading backslashes as slashes alone let a path outside the prefix pass. - The export methods require a version: an empty one would make the path name a version called "export". - An invalid host in a redirect's Location raises APIError too: httpx builds the next request even when it doesn't follow redirects. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QvHhCgtEqAD6xKyJAbToDH
|
Codex review, pass 1 (codex-cli 0.163.0, commit 15aa628): 3 findings, all fixed in dc10220.
Each has a new test. The full pass is on the tracking ticket. |
…that name their own endpoint fetch_cascade_children takes expressions from export data. It now returns no children, without a request, for an expression with a "." or ".." segment (encoded or not), a "?" or a "#". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QvHhCgtEqAD6xKyJAbToDH
|
Codex review, pass 2 (codex-cli 0.163.0, commit dc10220): the pass 1 fixes hold. One new P2, fixed in d03708b: |
…ge two encoding tests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QvHhCgtEqAD6xKyJAbToDH
|
Simplification review (fresh Claude subagent, commit d03708b): 3 suggestions. I applied two in 12aa8b2: merged two encoding tests, and inlined a one-caller helper. I declined folding the empty-identifier test into the sweep, because the optional versions accept an empty value on purpose. The full review is on the tracking ticket. |
… decoded until stable A base_url path prefix must now hold for the raw path as sent, and for a reading of the decoded path that is decoded until it stops changing, reads backslashes as slashes and drops ";" parameters, besides the readings already checked. Gateways that route on the raw path, decode twice or honour path parameters can no longer take a request outside the prefix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QvHhCgtEqAD6xKyJAbToDH
|
Adversarial review of the token handling (fresh Claude subagent, commit 12aa8b2): one P1 and one P2, both only for a
The default |
|
Adversarial re-verification (commit 5207d9c): no material issues. The prefix fixes hold in the real code, and legitimate identifiers and prefixed bases still work. Three new low-severity notes, all about a |
…ke, bound the decoding - Each reading of the request path is compared with the same reading of the base_url prefix, so a prefix that contains ";" or a literal "%25" works again. - Decoding stops after four passes; a path still changing then is refused, which bounds the work an untrusted URL can cause. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QvHhCgtEqAD6xKyJAbToDH
The path and the base_url prefix are now compared at each of five decoding depths, not only as sent and fully decoded, so a path that leaves the prefix at an intermediate depth is refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QvHhCgtEqAD6xKyJAbToDH
|
Codex check of b3b7cf8: clean. The review loop is finished: no P0, P1 or P2 is open. The low-severity notes are recorded on the tracking ticket. |
Linked Issue
Closes OpenConceptLab/ocl_online#553
Summary
openconceptlab0.2.1 hardens how the client builds request paths and where it sends them. Method signatures don't change, and theoclcommand works as before for every identifier OCL accepts.quote(value, safe=""). Before, values went into paths as given, so some characters changed which endpoint a request named. An empty value,.,..or a value containing/raisesAPIError(status_code0) before anything is sent. The server would decode a/back into a separator, so no encoding can carry it. A test runs each refused value through 66 calls that cover every path-building method.ocl tool recreate-collectionbuilds its own collection paths. It now quotes them, and it refuses an export file whose collection ID would name a different endpoint. Before, a crafted export could make--no-dry-runact on a resource other than the named collection. Thecollection_urlwritten into the bulk-import lines is unchanged.base_urlwith a path prefix, requires the raw path, and every way a server or gateway might read the decoded path, to stay inside the prefix. The readings cover dot segments resolved, backslashes read as slashes, and repeated decoding with;parameters dropped (capped at four passes). Encoded dot segments, slashes or backslashes can no longer leave the prefix.APIError. Before, httpx raised idna's error while building the request. Nothing was sent either way.search_reposnow validatesowner_type, like the other methods.fetch_cascade_childrensends nothing for an expression with dot segments,?or#. These expressions come from export files.get(endpoint)and the other low-level methods take a whole path as before, and nothing changes in request or response bodies.Test Plan
pytest -q: 285 passed (49 before). The new tests failed before the change: requests went out for every refused identifier, and the origin-check cases were allowed. One exception: three tests pin behaviour that already worked (a prefixbase_url, a punycode host, an encoded backslash inside the prefix).ocl concept get CIEL CIEL "A B+50%"sends/orgs/CIEL/sources/CIEL/concepts/A%20B%2B50%25/(CLI test). oclapi2 decodes the path once, then matches the raw form and several encoded forms of the identifier, so lookups behave as before.ruff check src tests: all checks passed.import openconceptlabandocl --versionboth work.Notes
v0.2.1happen after merge.🤖 Generated with Claude Code
https://claude.ai/code/session_01QvHhCgtEqAD6xKyJAbToDH