410b1dd4d1
* fix: prevent AppleScript injection RCE in macOS notifications buildAppleScript escaped only the double-quote in notification title/body and interpolated the result into an `osascript -e` string literal. A raw trailing backslash defeated that escaping: `\"` became `\\"`, which AppleScript reads as an escaped backslash plus a real closing delimiter, so the `display notification "..."` literal terminated early and any following text (e.g. `do shell script`) executed on the host. Notification title/body come verbatim from untrusted external-integration issue titles (Sentry/Linear/Jira) with no sanitization, so an attacker who can raise an issue in a connected workspace could achieve RCE on the macOS host when the office session reached WAITING_FOR_INPUT. Replace string interpolation with argv passing: title/body are delivered as `run` handler arguments (item 1/2 of argv) and never touch the AppleScript source, so no escaping is required. Add a proof-of-concept test documenting the legacy breakout and a regression guard asserting the fixed builder never leaks attacker text into script fragments. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix: terminate osascript option parsing before notification argv Passing untrusted title/body as trailing arguments still let a title that looks like an osascript flag be consumed as an option: a title of "-e" would turn the body into another script fragment, reopening the AppleScript injection. Add a `--` option terminator before title/body so untrusted text always lands in argv. Extend the regression tests to cover the flag-like title vector. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test: prove single-line AppleScript payload is host RCE, not just DoS Add a single-line (Jira/Linear, no newline) PoC alongside the multi-line Sentry payload. A newline statement separator is only needed for a SECOND statement; the single-line payload instead injects an expression `& (do shell script (...))` into the display-notification body argument, so the command executes as a side effect while the line stays one valid statement. Both shapes are host code execution. Extend the regression guard to prove the argv fix neutralizes both. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Kandev Agent <agent@kandev.dev> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>