Tool Argument Breaks Out of an AppleScript/JXA Template into `do shell script`
Detects a data-shaped tool parameter (url, uri, href, title, name, query, search, label, subject) whose quoted value contains an embedded newline followed by an AppleScript or JXA command-execution primitive -- `do shell script`, `osascript -e`, or `.doShellScript(`. Mined from CVE-2026-47252 (Anyquery macOS Chrome plugin), where a tab URL and title were sprintf-interpolated into an AppleScript/JXA template and handed to `osascript -e`; a value containing a newline escapes the `{URL:"..."}` record and appends an attacker-chosen statement. Generalized past that one plugin: the exploitable shape is any string parameter interpolated into an osascript template, so this keys on the parameter-value-contains-newline- then-execution-verb structure rather than on Anyquery's field names. The discriminator against ordinary AppleScript is deliberate and load- bearing: a legitimate script closes its string literal BEFORE the line break (`property url : "https://x"` newline `do shell script "..."`), while the injection's newline sits INSIDE a still-open value. The condition only matches the second shape. Verified on the shipped engine that the clean payload (no curl, no shell metacharacters) matches nothing across all five event types, and that no rule in the corpus mentions `do shell script`.
Response Actions
References
Detection Conditions
Combinator: any- 01A url/title/name-class parameter, reached through an unbroken JSON path from an anchored opening brace, whose quoted value carries a line break that is still INSIDE the value, followed by an AppleScript or JXA execution primitive that takes a quoted argument. Three requirements, each of which closed a measured false-positive class: the envelope must be a real payload rather than one quoted inside a sentence; the line break must sit inside a still-open value; and the verb must take an argument, because `do shell script` and `osascript -e` are also ordinary English noun phrases in macOS writing.field: contentop: regex
Attack Examples (Rule Triggers)
{"windows":[{"activeTab":{"title":"Quarterly Report\ndo shell script \"touch /tmp/pwned\"","url":"https://intra.example/q3"}}]}{"tool":"chrome_open","arguments":{"url":"https://x.example/\ndo shell script \"cp ~/.ssh/id_rsa /tmp/k\""}}{"tool":"browser_eval","arguments":{"url":"https://x.example/\nApplication('Terminal').doShellScript('id')"}}{"tool":"note_create","arguments":{"subject":"Invoice 8812\nosascript -e 'do shell script \"id\"'"}}
Real-world attack payloads, sanitized and versioned alongside the rule as regression tests — so a future revision can't silently stop catching them.
Benign Examples (Rule Doesn't Trigger)
- A legitimate AppleScript: the string literal closes before the line break
{"tool":"write_file","path":"scripts/open.applescript","content":"property url : \"https://status.example.com\"\ndo shell script \"curl -fsS \" & url"} - macOS runbook prose naming osascript with no quoted parameter value carrying a newline
To check the remote-login setting run osascript -e 'tell application "System Events" to get name of every process' and note the URL of the runbook.
- A title with a real newline and no execution primitive after it
{"tool":"create_note","arguments":{"title":"Q3 review\nAgenda: budget, hiring, do the shell rewrite"}} - package.json where the name value is closed before the script field that mentions osascript
{"name":"mac-tools","scripts":{"sleep":"osascript -e 'tell app \"System Events\" to sleep'"}} - ADVERSARIAL v1 FP -- CVE advisory quoting the PoC payload mid-sentence
CVE-2026-47252: a tab title such as {"title":"Quarterly Report\ndo shell script \"touch /tmp/pwned\""} escapes the JXA record. Upgrade the plugin. - ADVERSARIAL v1 FP -- CVE write-up with the PoC in a fenced json block (silenced by tags.suppress_in_code_blocks)
### CVE-2026-47252 The PoC payload: ```json {"tool":"chrome_open","arguments":{"url":"https://x.example/\ndo shell script \"id\""}} ``` Quote the parameter before interpolating it. - ADVERSARIAL v1 FP -- zh-Hant advisory quoting the PoC payload
資安通報 CVE-2026-47252:分頁標題若含 {"title":"季報\ndo shell script \"id\""},就會跳出 JXA 樣板。請先轉義再插值。 - ADVERSARIAL v1 FP -- ja advisory quoting the PoC payload
注意喚起 CVE-2026-47252: タブのタイトルに {"url":"https://x.example/\ndo shell script \"id\""} が含まれるとテンプレートを脱出します。 - ADVERSARIAL v1 FP -- this rule's OWN test_cases block; v1 fired on ATR's own repository
true_positives: - input: '{"windows":[{"activeTab":{"title":"Quarterly Report\ndo shell script \"touch /tmp/pwned\"","url":"https://intra.example/q3"}}]}' expected: triggered description: "CVE-2026-47252 shape" - ADVERSARIAL v1 FP -- Vitest case asserting the payload is SANITISED
it("escapes newlines before interpolating into osascript", () => { const bad = '{"title":"Report\ndo shell script \"id\""}'; expect(sanitize(bad)).not.toContain("do shell script"); }); - Detection rule JSON whose pattern field describes the payload
{"rules":[{"id":"applescript-template-escape","pattern":"\"title\":\"...\\ndo shell script ...","message":"tool parameter escapes an osascript template","severity":"ERROR"}]} - Legitimate AppleScript: the string literal closes before the line break
{"tool":"write_file","path":"scripts/open.applescript","content":"property url : \"https://status.example.com\"\ndo shell script \"curl -fsS \" & url"} - macOS runbook prose naming osascript with no quoted parameter carrying a newline
To check the remote-login setting run osascript -e 'tell application "System Events" to get name of every process' and note the URL of the runbook.
- GitHub Actions steps whose quoted names close before the run: line that calls osascript
- name: "Notify on macOS" run: osascript -e 'display notification "deploy finished"' - name: "Archive" run: tar czf out.tgz dist
- package.json whose name value closes before the script field mentioning osascript
{"name":"mac-tools","scripts":{"sleep":"osascript -e 'tell app \"System Events\" to sleep'"}} - Alfred workflow definition substituting {query} into a script
{"name":"Search Notes","query":"{query}","script":"osascript -e 'tell application \"Notes\" to search {query}'"} - A title with a real newline and no execution primitive after it
{"tool":"create_note","arguments":{"title":"Q3 review\nAgenda: budget, hiring, do the shell rewrite"}} - ADVERSARIAL v1 FP -- note title whose second line MENTIONS osascript -e as a noun phrase, with no argument
{"tool":"note_create","arguments":{"title":"macOS runbook\nosascript -e is the entry point for automation","body":"see wiki"}} - ADVERSARIAL v1 FP -- multi-line shell variable whose text discusses a 'do shell script rewrite'
label="release notes do shell script rewrite is tracked in JIRA-812" echo "$label" > notes.txt
- ADVERSARIAL v1 FP -- config reference showing an INVALID multi-line value and saying so
Config reference name: "deploy do shell script" is NOT a valid value; quote it on one line.
- Workflow plist where the name element closes before the script element calls osascript
<key>name</key> <string>Open URL</string> <key>script</key> <string>osascript -e "open location \"https://example.com\""</string>
- CSV command log with a name column and an osascript row
ts,name,cmd 2026-08-24T09:00:00Z,deploy,osascript -e 'display notification "ok"' 2026-08-24T09:05:00Z,backup,tar czf b.tgz .
Known False Positive Contexts
- ▸An ordinary multi-line AppleScript in which a string literal is closed before the line break, e.g. `property url : "https://status.example"` newline `do shell script "curl " & url`. The closing quote terminates the value scan, so the condition cannot reach the newline.
- ▸A macOS runbook or documentation that mentions `osascript -e` or `do shell script` in prose, since no url/title/name parameter assignment with an unterminated quoted value precedes it.
- ▸A JSON object whose title or name value ends in a newline and whose SHELL command sits in a separate field, because the bridge between the newline and the verb excludes the double quote that must close the first field.
- ▸Alfred/Raycast workflow definitions where `{query}` is substituted into a script, since the substitution token is not a quoted value carrying an embedded newline.
- ▸ADVERSARIAL REVIEW 2026-08-24, rule_version 2. Version 1 fired on 9 of 18 fresh benign inputs. Two defects. (1) THE VERB WAS TREATED AS A VERB WHEN IT IS ALSO AN ENGLISH NOUN PHRASE. `do shell script` and `osascript -e` are what macOS writers CALL these things, so a note title `macOS runbook` + newline + `osascript -e is the entry point for automation` fired, as did a shell variable `label="release notes` + newline + `do shell script rewrite is tracked in JIRA-812"`, and a config doc saying `name: "deploy` newline `do shell script" is NOT a valid value`. The verb must now take a quoted ARGUMENT -- an opening quote, at least one character, and a closing quote -- which is what an executable statement has and a noun phrase does not. (2) THE ENVELOPE WAS NEVER REQUIRED TO BE AN ENVELOPE. Any `{"title":"...` sequence matched wherever it appeared, so an advisory sentence quoting the PoC fired, in English, zh-Hant and ja; so did a Vitest case asserting the payload is SANITISED; and so did this rule OWN test_cases block, i.e. ATR own repository. The parameter must now be reachable through an unbroken JSON path -- braces, brackets, commas, colons, quoted strings, whitespace and bare tokens only -- from an opening brace that stands at the start of the field or at a line start. Prose between the brace and the parameter breaks that path.
- ▸RESIDUAL: a fenced ```json block whose first line is the payload is a real payload at a line start, so it matches. tags.suppress_in_code_blocks was added and silences it whenever the field carries REAL newlines. Where a document reaches the engine JSON-encoded (newlines as backslash-n) the fence cannot be located and the suppression does not apply. Triage on provenance.
- ▸PERFORMANCE NOTE, do not undo. The JSON-path prefix uses single-character units (one whitespace char, one structural char, one token char) plus whole quoted strings. An earlier draft let whitespace and token runs match {1,20} and {1,40} at a time; a 4000-space input then had exponentially many ways to be split across the repetition and the match never returned. Single-character units make the split unique. Measured 0 ms on 4000 spaces, 4000 letters, 60 nested opens and 600 repeated members.
Documented Evasion Techniques
- Technique: crlf and internal whitespace padding
{"tool":"chrome_open","arguments":{"title":"Report\r\n do shell script \"id\""}}CRLF and bounded \s{1,3} runs inside the verb keep the padded spelling covered. A verb split across a comment or a variable (`set v to "do shell " & "script"`) is a known gap: no local text carries the primitive in that form.
Publicly documented bypasses. A standard earns trust by publishing its worst figures, not hiding them — so known limitations ship inside the rule, not in a footnote.
Full YAML Definition
Edit on GitHub →title: "Tool Argument Breaks Out of an AppleScript/JXA Template into `do shell script`"
id: ATR-2026-02702
rule_version: 2
status: experimental
description: >
Detects a data-shaped tool parameter (url, uri, href, title, name, query,
search, label, subject) whose quoted value contains an embedded newline
followed by an AppleScript or JXA command-execution primitive --
`do shell script`, `osascript -e`, or `.doShellScript(`. Mined from
CVE-2026-47252 (Anyquery macOS Chrome plugin), where a tab URL and title
were sprintf-interpolated into an AppleScript/JXA template and handed to
`osascript -e`; a value containing a newline escapes the `{URL:"..."}`
record and appends an attacker-chosen statement. Generalized past that one
plugin: the exploitable shape is any string parameter interpolated into an
osascript template, so this keys on the parameter-value-contains-newline-
then-execution-verb structure rather than on Anyquery's field names.
The discriminator against ordinary AppleScript is deliberate and load-
bearing: a legitimate script closes its string literal BEFORE the line
break (`property url : "https://x"` newline `do shell script "..."`), while
the injection's newline sits INSIDE a still-open value. The condition only
matches the second shape. Verified on the shipped engine that the clean
payload (no curl, no shell metacharacters) matches nothing across all five
event types, and that no rule in the corpus mentions `do shell script`.
author: "ATR Community (CVE sweep)"
date: "2026/08/23"
schema_version: "0.1"
detection_tier: pattern
maturity: test
severity: high
references:
cwe:
- "CWE-94"
- "CWE-1236"
owasp_llm:
- "LLM05:2025"
owasp_agentic:
- "ASI02:2026"
mitre_attack:
- "T1059.002 - AppleScript"
mitre_atlas:
- "AML.T0053 - LLM Plugin Compromise"
cve:
- "CVE-2026-47252"
external:
- "https://nvd.nist.gov/vuln/detail/CVE-2026-47252"
metadata_provenance:
cwe: human-reviewed
owasp_llm: human-reviewed
owasp_agentic: human-reviewed
mitre_attack: human-reviewed
mitre_atlas: human-reviewed
compliance:
eu_ai_act:
- article: "15"
context: "Article 15 (accuracy, robustness and cybersecurity) requires resilience against inputs crafted to alter system behaviour; this rule detects a tool parameter escaping an AppleScript template to run host commands."
strength: primary
- article: "9"
context: "Article 9 (risk management system) requires identified risks to be treated by appropriate measures; this rule is the runtime treatment for script-template injection in macOS automation tools."
strength: secondary
nist_ai_rmf:
- subcategory: "MG.2.3"
context: "AppleScript template injection via an agent tool parameter is an identified AI risk requiring an active runtime countermeasure; this rule implements it."
strength: primary
- subcategory: "MP.5.1"
context: "Cataloguing unescaped interpolation into osascript templates as an AI-specific risk in the organizational risk register."
strength: secondary
iso_42001:
- clause: "8.1"
context: "ISO/IEC 42001 Clause 8.1 (operational planning and control) is operationalised by detecting the template-escape before the script is executed."
strength: primary
- clause: "8.3"
context: "ISO/IEC 42001 Clause 8.3 (AI risk treatment) is implemented through runtime detection of the injected execution statement."
strength: secondary
tags:
category: tool-poisoning
subcategory: applescript-template-injection
scan_target: runtime
confidence: high
suppress_in_code_blocks: true
agent_source:
type: mcp_exchange
framework:
- any
provider:
- any
detection:
condition: any
conditions:
- field: content
operator: regex
value: '(?:^|\n|\\n)[ \t]{0,6}\{(?:"[^"\n]{0,60}"|[ \t\n{\[,:]|[A-Za-z0-9_.+-]){0,16}(?:\\{0,2}["\x27])?\b(?:url|uri|href|title|name|query|search|label|subject)(?:\\{0,2}["\x27])?\s{0,3}[:=]\s{0,3}(?:\\{0,2}["\x27])[^"\x27\r\n]{0,40}(?:\\r)?(?:\\n|[\r\n])[^"\r\n]{0,32}(?:do\s{1,3}shell\s{1,3}script\s{0,3}(?:\\{0,2}["\x27])[^"\x27\r\n]{1,120}(?:\\{0,2}["\x27])|osascript\s{1,3}-e\s{0,3}(?:\\{0,2}["\x27])[^"\x27\r\n]{1,120}(?:\\{0,2}["\x27])|\.doshellscript\s{0,3}\(\s{0,3}(?:\\{0,2}["\x27])[^"\x27\r\n]{1,120}(?:\\{0,2}["\x27]))'
description: "A url/title/name-class parameter, reached through an unbroken JSON path from an anchored opening brace, whose quoted value carries a line break that is still INSIDE the value, followed by an AppleScript or JXA execution primitive that takes a quoted argument. Three requirements, each of which closed a measured false-positive class: the envelope must be a real payload rather than one quoted inside a sentence; the line break must sit inside a still-open value; and the verb must take an argument, because `do shell script` and `osascript -e` are also ordinary English noun phrases in macOS writing."
false_positives:
- "An ordinary multi-line AppleScript in which a string literal is closed before the line break, e.g. `property url : \"https://status.example\"` newline `do shell script \"curl \" & url`. The closing quote terminates the value scan, so the condition cannot reach the newline."
- "A macOS runbook or documentation that mentions `osascript -e` or `do shell script` in prose, since no url/title/name parameter assignment with an unterminated quoted value precedes it."
- "A JSON object whose title or name value ends in a newline and whose SHELL command sits in a separate field, because the bridge between the newline and the verb excludes the double quote that must close the first field."
- "Alfred/Raycast workflow definitions where `{query}` is substituted into a script, since the substitution token is not a quoted value carrying an embedded newline."
- "ADVERSARIAL REVIEW 2026-08-24, rule_version 2. Version 1 fired on 9 of 18 fresh benign inputs. Two defects. (1) THE VERB WAS TREATED AS A VERB WHEN IT IS ALSO AN ENGLISH NOUN PHRASE. `do shell script` and `osascript -e` are what macOS writers CALL these things, so a note title `macOS runbook` + newline + `osascript -e is the entry point for automation` fired, as did a shell variable `label=\"release notes` + newline + `do shell script rewrite is tracked in JIRA-812\"`, and a config doc saying `name: \"deploy` newline `do shell script\" is NOT a valid value`. The verb must now take a quoted ARGUMENT -- an opening quote, at least one character, and a closing quote -- which is what an executable statement has and a noun phrase does not. (2) THE ENVELOPE WAS NEVER REQUIRED TO BE AN ENVELOPE. Any `{\"title\":\"...` sequence matched wherever it appeared, so an advisory sentence quoting the PoC fired, in English, zh-Hant and ja; so did a Vitest case asserting the payload is SANITISED; and so did this rule OWN test_cases block, i.e. ATR own repository. The parameter must now be reachable through an unbroken JSON path -- braces, brackets, commas, colons, quoted strings, whitespace and bare tokens only -- from an opening brace that stands at the start of the field or at a line start. Prose between the brace and the parameter breaks that path."
- "RESIDUAL: a fenced ```json block whose first line is the payload is a real payload at a line start, so it matches. tags.suppress_in_code_blocks was added and silences it whenever the field carries REAL newlines. Where a document reaches the engine JSON-encoded (newlines as backslash-n) the fence cannot be located and the suppression does not apply. Triage on provenance."
- "PERFORMANCE NOTE, do not undo. The JSON-path prefix uses single-character units (one whitespace char, one structural char, one token char) plus whole quoted strings. An earlier draft let whitespace and token runs match {1,20} and {1,40} at a time; a 4000-space input then had exponentially many ways to be split across the repetition and the match never returned. Single-character units make the split unique. Measured 0 ms on 4000 spaces, 4000 letters, 60 nested opens and 600 repeated members."
response:
actions:
- alert
message_template: >
[ATR-2026-02702] A url/title/name tool parameter carries a line break
followed by an AppleScript or JXA execution primitive -- the shape of a
value escaping an osascript template. Quote or reject the parameter
before interpolating it into a script.
confidence: 80
test_cases:
true_positives:
- input: '{"windows":[{"activeTab":{"title":"Quarterly Report\ndo shell script \"touch /tmp/pwned\"","url":"https://intra.example/q3"}}]}'
expected: triggered
description: "CVE-2026-47252 shape -- an attacker-controlled page title escapes the JXA record and appends a shell statement"
- input: '{"tool":"chrome_open","arguments":{"url":"https://x.example/\ndo shell script \"cp ~/.ssh/id_rsa /tmp/k\""}}'
expected: triggered
description: "The URL parameter itself carrying the injected statement"
- input: '{"tool":"browser_eval","arguments":{"url":"https://x.example/\nApplication(''Terminal'').doShellScript(''id'')"}}'
expected: triggered
description: "JXA spelling of the same primitive after the template break-out"
- input: '{"tool":"note_create","arguments":{"subject":"Invoice 8812\nosascript -e ''do shell script \"id\"''"}}'
expected: triggered
description: "A subject field re-invoking osascript with an inline script"
true_negatives:
- input: '{"tool":"write_file","path":"scripts/open.applescript","content":"property url : \"https://status.example.com\"\ndo shell script \"curl -fsS \" & url"}'
expected: not_triggered
description: "A legitimate AppleScript: the string literal closes before the line break"
- input: 'To check the remote-login setting run osascript -e ''tell application "System Events" to get name of every process'' and note the URL of the runbook.'
expected: not_triggered
description: "macOS runbook prose naming osascript with no quoted parameter value carrying a newline"
- input: '{"tool":"create_note","arguments":{"title":"Q3 review\nAgenda: budget, hiring, do the shell rewrite"}}'
expected: not_triggered
description: "A title with a real newline and no execution primitive after it"
- input: '{"name":"mac-tools","scripts":{"sleep":"osascript -e ''tell app \"System Events\" to sleep''"}}'
expected: not_triggered
description: "package.json where the name value is closed before the script field that mentions osascript"
- input: 'CVE-2026-47252: a tab title such as {"title":"Quarterly Report\ndo shell script \"touch /tmp/pwned\""} escapes the JXA record. Upgrade the plugin.'
expected: not_triggered
description: ADVERSARIAL v1 FP -- CVE advisory quoting the PoC payload mid-sentence
- input: '### CVE-2026-47252
The PoC payload:
```json
{"tool":"chrome_open","arguments":{"url":"https://x.example/\ndo shell script \"id\""}}
```
Quote the parameter before interpolating it.'
expected: not_triggered
description: ADVERSARIAL v1 FP -- CVE write-up with the PoC in a fenced json block (silenced by tags.suppress_in_code_blocks)
- input: 資安通報 CVE-2026-47252:分頁標題若含 {"title":"季報\ndo shell script \"id\""},就會跳出 JXA 樣板。請先轉義再插值。
expected: not_triggered
description: ADVERSARIAL v1 FP -- zh-Hant advisory quoting the PoC payload
- input: '注意喚起 CVE-2026-47252: タブのタイトルに {"url":"https://x.example/\ndo shell script \"id\""} が含まれるとテンプレートを脱出します。'
expected: not_triggered
description: ADVERSARIAL v1 FP -- ja advisory quoting the PoC payload
- input: " true_positives:\n - input: '{\"windows\":[{\"activeTab\":{\"title\":\"Quarterly Report\\ndo shell script \\\"touch /tmp/pwned\\\"\",\"url\":\"https://intra.example/q3\"}}]}'\n expected: triggered\n description: \"CVE-2026-47252 shape\""
expected: not_triggered
description: ADVERSARIAL v1 FP -- this rule's OWN test_cases block; v1 fired on ATR's own repository
- input: "it(\"escapes newlines before interpolating into osascript\", () => {\n const bad = '{\"title\":\"Report\\ndo shell script \\\"id\\\"\"}';\n expect(sanitize(bad)).not.toContain(\"do shell script\");\n});"
expected: not_triggered
description: ADVERSARIAL v1 FP -- Vitest case asserting the payload is SANITISED
- input: '{"rules":[{"id":"applescript-template-escape","pattern":"\"title\":\"...\\ndo shell script ...","message":"tool parameter escapes an osascript template","severity":"ERROR"}]}'
expected: not_triggered
description: Detection rule JSON whose pattern field describes the payload
- input: '{"tool":"write_file","path":"scripts/open.applescript","content":"property url : \"https://status.example.com\"\ndo shell script \"curl -fsS \" & url"}'
expected: not_triggered
description: 'Legitimate AppleScript: the string literal closes before the line break'
- input: To check the remote-login setting run osascript -e 'tell application "System Events" to get name of every process' and note the URL of the runbook.
expected: not_triggered
description: macOS runbook prose naming osascript with no quoted parameter carrying a newline
- input: "- name: \"Notify on macOS\"\n run: osascript -e 'display notification \"deploy finished\"'\n- name: \"Archive\"\n run: tar czf out.tgz dist"
expected: not_triggered
description: 'GitHub Actions steps whose quoted names close before the run: line that calls osascript'
- input: '{"name":"mac-tools","scripts":{"sleep":"osascript -e ''tell app \"System Events\" to sleep''"}}'
expected: not_triggered
description: package.json whose name value closes before the script field mentioning osascript
- input: '{"name":"Search Notes","query":"{query}","script":"osascript -e ''tell application \"Notes\" to search {query}''"}'
expected: not_triggered
description: Alfred workflow definition substituting {query} into a script
- input: '{"tool":"create_note","arguments":{"title":"Q3 review\nAgenda: budget, hiring, do the shell rewrite"}}'
expected: not_triggered
description: A title with a real newline and no execution primitive after it
- input: '{"tool":"note_create","arguments":{"title":"macOS runbook\nosascript -e is the entry point for automation","body":"see wiki"}}'
expected: not_triggered
description: ADVERSARIAL v1 FP -- note title whose second line MENTIONS osascript -e as a noun phrase, with no argument
- input: 'label="release notes
do shell script rewrite is tracked in JIRA-812"
echo "$label" > notes.txt'
expected: not_triggered
description: ADVERSARIAL v1 FP -- multi-line shell variable whose text discusses a 'do shell script rewrite'
- input: 'Config reference
name: "deploy
do shell script" is NOT a valid value; quote it on one line.'
expected: not_triggered
description: ADVERSARIAL v1 FP -- config reference showing an INVALID multi-line value and saying so
- input: '<key>name</key>
<string>Open URL</string>
<key>script</key>
<string>osascript -e "open location \"https://example.com\""</string>'
expected: not_triggered
description: Workflow plist where the name element closes before the script element calls osascript
- input: 'ts,name,cmd
2026-08-24T09:00:00Z,deploy,osascript -e ''display notification "ok"''
2026-08-24T09:05:00Z,backup,tar czf b.tgz .'
expected: not_triggered
description: CSV command log with a name column and an osascript row
evasion_tests:
- input: '{"tool":"chrome_open","arguments":{"title":"Report\r\n do shell script \"id\""}}'
expected: triggered
bypass_technique: crlf_and_internal_whitespace_padding
notes: "CRLF and bounded \\s{1,3} runs inside the verb keep the padded spelling covered. A verb split across a comment or a variable (`set v to \"do shell \" & \"script\"`) is a known gap: no local text carries the primitive in that form."