()
| 651 | |
| 652 | #[tokio::test] |
| 653 | async fn test_path_traversal_dots() { |
| 654 | let sandbox_path = with_sandbox("path_traversal_dots"); |
| 655 | |
| 656 | // Create a real file inside sandbox |
| 657 | tokio::fs::write(sandbox_path.join("safe.txt"), "hello") |
| 658 | .await |
| 659 | .expect("create safe.txt"); |
| 660 | |
| 661 | let executor = ToolExecutor::new(sandbox_path.clone()); |
| 662 | |
| 663 | // Attempt traversal via relative path — should be rejected |
| 664 | let call = ToolCall { |
| 665 | tool: ToolName::ReadFile, |
| 666 | input: serde_json::json!({ "path": "../../../../etc/passwd" }), |
| 667 | }; |
| 668 | let result = executor.execute(call).await; |
| 669 | assert!( |
| 670 | result.is_error, |
| 671 | "Path traversal with .. should be rejected, got: {}", |
| 672 | result.output |
| 673 | ); |
| 674 | |
| 675 | cleanup("path_traversal_dots"); |
| 676 | } |
| 677 | |
| 678 | #[tokio::test] |
| 679 | async fn test_path_traversal_absolute_escape() { |
nothing calls this directly
no test coverage detected