From 84d29488e956750b6fa5ce02f6759d82a62e02cc Mon Sep 17 00:00:00 2001 From: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com> Date: Fri, 28 Aug 2026 13:34:08 +0530 Subject: [PATCH] fix(cron): harden _is_named_profile_path against symlinked profile homes Check both resolved and unresolved path parts so a symlinked named profile (e.g. profiles/dev -> /mnt/data/dev) is still detected. Also use _ensure_cron_dir for output_dir in ensure_dirs() for consistency. Simplify-code Phase 2 finding (medium severity). --- cron/jobs.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cron/jobs.py b/cron/jobs.py index 5fe8a2a6d9..eb7a3a42e4 100644 --- a/cron/jobs.py +++ b/cron/jobs.py @@ -732,11 +732,17 @@ def _is_named_profile_path(path: Path) -> bool: Named profiles live under ``/profiles//``. The default profile lives at ```` directly (no ``profiles`` parent), as do custom ``HERMES_HOME`` paths outside ``~/.hermes``. + + Checks both the resolved path (handles symlinks in the parent chain) + and the raw path (catches symlinked profile homes whose resolve() + target no longer contains ``profiles``). """ try: - return "profiles" in path.resolve().parts + if "profiles" in path.resolve().parts: + return True except (OSError, RuntimeError): - return False + pass + return "profiles" in path.parts def _ensure_cron_dir(cron_dir: Path) -> None: @@ -759,7 +765,7 @@ def ensure_dirs(): """Ensure cron directories exist with secure permissions.""" store = _current_cron_store() _ensure_cron_dir(store.cron_dir) - store.output_dir.mkdir(exist_ok=True) + _ensure_cron_dir(store.output_dir) _secure_dir(store.cron_dir) _secure_dir(store.output_dir)