Fix #2160: sanitise agent_id and learning_id paths in markdown_store (CWE-22)#903
Open
AlexMikhalev wants to merge 10 commits into
Open
Fix #2160: sanitise agent_id and learning_id paths in markdown_store (CWE-22)#903AlexMikhalev wants to merge 10 commits into
AlexMikhalev wants to merge 10 commits into
Conversation
…1992 reqwest::Error from error_for_status() on a 400 response is an HTTP application error, not a transport/connectivity failure. Previously classify_error() returned ExitCode::ErrorNetwork (6) for all reqwest errors, causing test_server_mode_search_with_selected_role to fail when the server returned 400 due to missing role configuration. Now check re.status() before falling back to ErrorNetwork: - 401 / 403 → ErrorAuth (5) - 404 → ErrorNotFound (4) - other 4xx/5xx → ErrorGeneral (1) - no status → ErrorNetwork (6, true connectivity failure) Adds five regression tests using a real one-shot TCP server so no mocks are needed, covering 400, 401, 403, 404, 500 paths. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds an integration test that starts a real TCP listener replying with HTTP 400 Bad Request and asserts the binary exits 0 or 1 (never 6). This exercises the classify_error fix end-to-end through the real binary, complementing the unit-level classify_reqwest_tests in main.rs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…_node_ids Refs #2039 Deserialising a SerializableRoleGraph JSON written before issue #84 (trigger-based KG retrieval) was merged would fail with a missing-field error because trigger_descriptions and pinned_node_ids had no serde(default) annotation. Adds the annotation to both fields and a round-trip regression test that strips the fields from a serialised graph and confirms deserialisation succeeds with empty collections, matching the existing learning_document_ids pattern. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…2133
Replace `for stream in incoming() { if let Ok(s) = stream { ... } }` with
`for s in incoming().flatten() { ... }` to satisfy clippy::manual_flatten.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…(feature = "firecracker") firecracker.rs called get_vm_status() and execute_vm_code() from ApiClient which are #[cfg(feature = "firecracker")] but the module was compiled unconditionally. This broke cargo test -p terraphim_agent with default features. Fix: add #[cfg(feature = "firecracker")] to pub mod firecracker in modes/mod.rs and update HybridExecutor to conditionally use FirecrackerExecutor only when the feature is enabled, falling back to LocalExecutor otherwise. Refs #2164 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ths (CWE-22) source_agent was joined directly into filesystem paths in agent_dir(), save(), save_to_shared(), load(), and delete() — enabling path traversal attacks (CWE-22) via crafted agent IDs such as "../../../etc/passwd". Add sanitise_path_component() which replaces every character that is not ASCII-alphanumeric, hyphen, underscore, or dot with an underscore, and emits a tracing::warn! when sanitisation is required (audit trail for injection attempts). Apply sanitisation at every path-construction site: - agent_dir(): agent_id - save(): learning.id in filename - save_to_shared(): both learning.source_agent and learning.id in filename - load(): learning_id in filename - delete(): learning_id in filename Add 5 regression tests covering strip of slashes, null bytes, traversal sequences, and end-to-end save/load with malicious source_agent values. Fixes #2160
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
Fixes Gitea terraphim/terraphim-ai#2160 — P2 security: path traversal (CWE-22) in shared_learning markdown_store.
source_agentwas joined directly into filesystem paths in five places withoutany sanitisation, allowing a crafted agent ID such as
../../../etc/passwdtoescape the
learnings_dirboundary.Changes
sanitise_path_component(s: &str) -> String— replaces every characteroutside
[a-zA-Z0-9._-]with_and emitstracing::warn!on sanitisation(audit trail for injection attempts).
agent_dir,save,save_to_shared,load,delete.sequences, end-to-end
savewith malicioussource_agent, andsave_to_sharedwith traversal value.
Vulnerable functions fixed
agent_dir(agent_id)../in agent_idsave(learning)../in learning.idsave_to_shared(learning)../in source_agent + idload(agent_id, learning_id)delete(agent_id, learning_id)Test plan
Refs terraphim/terraphim-ai#2160 (Gitea)