Commit 4de39be
fix(F7): canonicalize paths in permission check_path to follow symlinks (#82)
Track F-HIGH #7 from ROADMAP.md.
## Problem
`resolve_absolute` (`permission/checker.rs:370-376`) joined
relative paths against working_dir but never followed symlinks.
A user could create:
ln -s /etc/passwd ./benign-name.txt
…and any deny rule on `/etc/**` would be bypassed because the
pattern matcher only saw `./benign-name.txt`. Same hole for
external-directory rules in `Accept` mode.
## Fix
`resolve_absolute` now calls `std::fs::canonicalize` on the
joined path. canonicalize() resolves symlinks AND normalizes
`.` / `..` lexically — the path the rule matches is now the
real target, not the link name.
Three-level fallback for nonexistent paths (writes to new files
need to resolve too):
1. Try `canonicalize(full_path)` — works for existing paths +
symlinks.
2. If that fails (NotFound on write-to-new), try
`canonicalize(parent) + basename` — catches
`/safe/parent/../../etc/passwd` style attacks where the
parent exists.
3. If even the parent can't canonicalize (test fixture dirs
that don't exist on disk), fall back to the lexical join.
Matches pre-F7 behavior so existing permission tests on
not-yet-existing paths still match.
## Tests
Two new tests in `permission::checker::tests`:
- `resolve_absolute_follows_symlinks`: creates a tempdir with
`real-secret.txt` and a `benign-name.txt` symlink to it;
asserts resolve returns the real target's canonical path,
not the link name. Handles macOS `/tmp -> /private/tmp` by
canonicalizing the expected path too.
- `resolve_absolute_handles_nonexistent_via_parent_canonicalize`:
parent dir exists but the leaf doesn't; asserts the result is
`canonical(parent) / leaf` — proves the second-level fallback
works without breaking parent resolution.
662 pass (was 660). All build profiles clean.
Co-authored-by: Yogthos <yogthos@gmail.com>1 parent 9700da8 commit 4de39be
1 file changed
Lines changed: 92 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
369 | 369 | | |
370 | 370 | | |
371 | 371 | | |
372 | | - | |
373 | | - | |
| 372 | + | |
| 373 | + | |
374 | 374 | | |
375 | | - | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
376 | 407 | | |
377 | 408 | | |
378 | 409 | | |
| |||
389 | 420 | | |
390 | 421 | | |
391 | 422 | | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
392 | 481 | | |
393 | 482 | | |
394 | 483 | | |
| |||
0 commit comments