Skip to content

Fix detection edge cases, shell hooks, and audit reliability#38

Merged
sheeki03 merged 14 commits intomainfrom
fix/bug-fixes-batch
Feb 24, 2026
Merged

Fix detection edge cases, shell hooks, and audit reliability#38
sheeki03 merged 14 commits intomainfrom
fix/bug-fixes-batch

Conversation

@sheeki03
Copy link
Owner

@sheeki03 sheeki03 commented Feb 24, 2026

Summary

  • Fix schemeless URL false positives on output filenames and false negatives on TLD-overlap domains with paths
  • Fix tokenizer to skip leading env assignments for command resolution
  • Add inline bypass detection and self-invocation guard to engine
  • Add --interactive flag to shell hooks for correct bypass policy
  • Fix doctor to check fish conf.d and all profile candidates
  • Fix audit log silent failures and CLI output error handling

Changes

  • extract.rs: Schemeless URL extraction hardening (FP reduction + FN fix for TLD-overlap paths)
  • engine.rs: Inline bypass detection, self-invocation guard
  • tokenize.rs: Skip leading VAR=val assignments when resolving command name
  • audit.rs: Fix silent failures in audit log writing
  • doctor.rs: Check fish conf.d directory and all profile candidates
  • shell hooks: Add --interactive flag across zsh, bash, fish, PowerShell
  • check.rs, run.rs, score.rs: CLI output error handling improvements

Test plan

  • cargo fmt --all passes
  • cargo clippy --workspace -- -D warnings passes
  • cargo test --workspace passes (all 175+ tests)
  • Manual: verify tirith check on schemeless URLs with paths
  • Manual: verify tirith doctor detects fish conf.d hooks

🤖 Generated with Claude Code

Note

Detect inline TIRITH=0 bypasses and self-invocations in tirith-core::engine::analyze, and add stderr diagnostics for audit and CLI output failures to improve audit reliability

Adds inline bypass parsing for env wrappers and PowerShell, introduces self-invocation fast-allow in Exec scans, tokenizes segments to skip leading env assignments for accurate command resolution, adjusts URL extraction to avoid env and output-file false positives, and prints stderr errors on audit and CLI write failures.

📍Where to Start

Start with analyze in crates/tirith-core/src/engine.rs, then review find_inline_bypass, is_self_invocation, and tokenization changes in crates/tirith-core/src/tokenize.rs.

Macroscope summarized 92ba3f5.

sheeki03 and others added 8 commits February 18, 2026 11:43
Report errors via eprintln instead of silently swallowing them in
audit log open/write/sync/lock/unlock and CLI output write paths.
push_segment() incorrectly treated VAR=VALUE as the command token. Now
skips leading environment variable assignments to find the real command.
Adds pub is_env_assignment() helper for use by engine bypass detection.

Fixes: TIRITH=0 curl evil.com now correctly identifies curl as command.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add command-aware output-flag skipping for curl (-o/--output) and wget
(-O/-OFILE/--output-document). Extract URLs from command+args instead
of raw segment text to avoid matching URLs in env-prefix values.

Add conservative non-TLD file extensions (.png, .jpg, .mp4, etc.) to
schemeless host exclusion list. Fixes issue #33.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…paths

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…detection

- Treat single & as segment boundary in split_raw_words (was only handling &&)
- Add Windows backslash path check in is_tirith_command
- Use exact equality for TIRITH=0 bypass check (was starts_with, matching TIRITH=00 etc)
- Collapse else-if block in check.rs (clippy collapsible_else_if)
- cargo fmt: fix indentation in extract.rs file_exts array
// Case 1: Leading VAR=VALUE assignments before the command
let mut idx = 0;
while idx < words.len() && tokenize::is_env_assignment(&words[idx]) {
if words[idx] == "TIRITH=0" {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Low src/engine.rs:46

The comparison words[idx] == "TIRITH=0" won't match quoted variants like 'TIRITH=0' since split_raw_words preserves quotes. Consider stripping quotes before the comparison, similar to how is_env_assignment does.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file crates/tirith-core/src/engine.rs around line 46:

The comparison `words[idx] == "TIRITH=0"` won't match quoted variants like `'TIRITH=0'` since `split_raw_words` preserves quotes. Consider stripping quotes before the comparison, similar to how `is_env_assignment` does.

Evidence trail:
crates/tirith-core/src/engine.rs lines 46, 65, 85: direct comparison `words[idx] == "TIRITH=0"`
crates/tirith-core/src/engine.rs lines 122-133 (single quotes), 134-151 (double quotes): split_raw_words preserves quotes by pushing them into current
crates/tirith-core/src/tokenize.rs lines 320-328: is_env_assignment strips quotes before checking (lines 322-328)

Without this, tirith.exe on Windows would not be recognized as a
self-invocation, causing false positives on every tirith command.
@sheeki03 sheeki03 force-pushed the fix/bug-fixes-batch branch from 612325a to 819fdeb Compare February 24, 2026 16:07
- Merge origin/main (already up to date)
- Skip flags in resolve_command_wrapper
- Remove dead code in is_tirith_command
- Remove quote-stripping in is_env_assignment (callers handle this)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The _shell parameter was unused — PowerShell users couldn't use inline
bypass ($env:TIRITH="0"; cmd) because only POSIX VAR=value syntax was
detected. Now handles $env:TIRITH=0, $env:TIRITH="0", $Env:TIRITH='0',
and spaced form ($env:TIRITH = "0") when shell is PowerShell.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Comment on lines +144 to +147
if after_dollar.len() < 4 || !after_dollar[..4].eq_ignore_ascii_case("env:") {
return false;
}
&after_dollar[4..] == var_name
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟠 High src/engine.rs:144

PowerShell $env: parsing: avoid byte slicing and case‑sensitive matches. Suggest checking the $env: prefix and TIRITH name using ASCII‑insensitive prefix checks (e.g., starts_with/strip_prefix) or by iterating chars, and parse the = value without indexing. This prevents UTF‑8 boundary panics and aligns with PowerShell’s case‑insensitivity.

-    if after_dollar.len() < 4 || !after_dollar[..4].eq_ignore_ascii_case("env:") {
+    let prefix = "env:";
+    if !after_dollar.get(..prefix.len()).map_or(false, |s| s.eq_ignore_ascii_case(prefix)) {
         return false;
     }
-    &after_dollar[4..] == var_name
+    after_dollar.get(prefix.len()..).map_or(false, |s| s == var_name)
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file crates/tirith-core/src/engine.rs around lines 144-147:

PowerShell `$env:` parsing: avoid byte slicing and case‑sensitive matches. Suggest checking the `$env:` prefix and `TIRITH` name using ASCII‑insensitive prefix checks (e.g., `starts_with`/`strip_prefix`) or by iterating chars, and parse the `=` value without indexing. This prevents UTF‑8 boundary panics and aligns with PowerShell’s case‑insensitivity.

Evidence trail:
crates/tirith-core/src/engine.rs lines 139-147 (is_powershell_env_ref function with byte slicing at lines 143-144, 147), lines 122-135 (is_powershell_tirith_bypass with similar byte slicing at lines 126-127, 130, 134 and case-sensitive TIRITH= check at line 131). Rust documentation confirms that &str slicing panics on non-UTF-8-boundary indices.

…nics

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
command -v and command -V are lookup operations (print path/version),
not execution. Return None from resolve_command_wrapper for these flags
to avoid false positive self-invocation detection.

Also fix clippy::unnecessary_map_or lints in is_powershell_env_ref.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sheeki03 sheeki03 merged commit 92ba3f5 into main Feb 24, 2026
10 checks passed
@sheeki03 sheeki03 deleted the fix/bug-fixes-batch branch February 24, 2026 21:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant