By NHI Mgmt Group Editorial TeamBased on Sonar: “Escape from AppleScript: Even folder names can be user input” (July 22, 2026)

TL;DR: A Swift app that builds AppleScript around user-controlled paths can cross a data-code boundary and permit arbitrary command execution when escaping rules do not match the target interpreter, according to Sonar. The case reinforces that native argument passing is safer than string-built scripts, especially where untrusted content can arrive through files, archives, or repositories.


At a glance

What this is: Sonar shows that OpenInTerminal's AppleScript handling can turn a crafted folder path into arbitrary command execution when shell escaping is applied in the wrong interpreter context.

Why it matters: This matters because identity and access teams increasingly rely on scripts, launchers, and automation around user-controlled inputs, and the same trust-boundary mistakes can expose admin workflows, developer tooling, and machine identities to code execution.


Context

AppleScript injection happens when untrusted data is embedded into AppleScript as code rather than passed as a literal argument. In this case, the security gap is not just bad escaping but a mismatched trust boundary between Swift, AppleScript, and the shell. That pattern matters to identity and access programmes because automation layers often touch privileged workflows, local administration, and endpoint management.

The practical lesson is that dynamic script generation is brittle whenever one interpreter prepares input for another. If a workflow accepts paths, filenames, or other externally supplied values, the safest design is to preserve argument boundaries end to end instead of trying to sanitise a command string after the fact. This is typical of broader injection problems, not an isolated macOS quirk.


Key questions

Q: What breaks when shell escaping is used in the wrong interpreter context?

A: Escaping only protects the grammar of the interpreter it was written for, so a string that is safe for the shell can still break out of an outer AppleScript literal. When applications build code for one interpreter inside another, the result is often command injection or syntax errors, because the trust boundary has moved but the escaping rules have not.

Q: Why do user-controlled paths become dangerous in launcher utilities?

A: Paths are dangerous when the application treats them as executable text instead of data. Nested folders, repository contents, archive extractions, and symlinks can all carry characters or structures that survive into a script or command builder. Once a path crosses into code generation, the file system becomes an attack delivery channel.

Q: What are the signs that command construction is failing safely?

A: The main warning sign is any feature that concatenates a command string and then relies on manual escaping before execution. If the same value crosses multiple parsers, or if developers can only explain safety by listing characters to escape, the design is fragile. Safe execution keeps the command and its arguments structurally separate.

Q: Should teams use structured execution instead of scripting for process launch?

A: Yes, when user-controlled values can influence the command. Structured execution preserves argument boundaries and avoids the uncertainty of nested escaping across interpreters. For endpoint tools, launchers, and automation helpers, that design is usually safer than sanitising a command string and hoping every parser sees it the same way.


Technical breakdown

Why shell escaping fails inside AppleScript

Shell escaping only protects the syntax of the interpreter it was designed for. In OpenInTerminal, the code builds a do shell script statement inside an AppleScript string, so a character that is harmless after shell escaping can still terminate or reshape the outer AppleScript literal. That is a classic data to code boundary failure: the application assumes one escaping layer is enough, but the payload crosses two parsers with different rules. The result is not merely a malformed path, but potential execution of attacker supplied script fragments.

Practical implication: Use native argument passing instead of constructing nested script strings for untrusted input.

How crafted paths become executable payloads

The exploit path depends on user supplied folder names, nested directories, and sometimes symlinks that make the malicious structure look ordinary. Because spaces and quotes are constrained, an attacker can assemble payload fragments from character codes, text coercion, comments, and nested folder names until the final AppleScript evaluates as intended. This is why seemingly low risk inputs like paths are dangerous in multi-interpreter workflows. Once an application treats file system names as executable text, the file system becomes an injection surface.

Practical implication: Treat filenames, paths, and repository content as untrusted input whenever they cross into scripting or automation code.

Native process execution preserves boundaries

Structured process APIs such as Process, execve(), or subprocess.run([...], shell=False) keep the command and each argument separate. That preserves the meaning of user controlled values without asking developers to predict every escaping rule in every downstream interpreter. In this case, the fixed implementation moves from concatenated strings to per argument handling, which eliminates the data code ambiguity that enabled injection. The broader security point is simple: sanitising a command string is usually weaker than never creating one.

Practical implication: Prefer structured execution APIs and per argument quoting for any workflow that launches external tools.


Threat narrative

Attacker objective: The attacker wants arbitrary code execution on the victim's machine through a crafted folder path that survives the application's escaping logic.

  1. Entry occurs when a victim downloads or receives a malicious folder structure and later opens a nested folder through OpenInTerminal's Finder integration.
  2. Credential access is not the primary issue here, but the attacker leverages crafted path content to cross the data code boundary inside AppleScript and inject commands.
  3. Impact occurs when the injected AppleScript runs arbitrary code on the victim's macOS system, demonstrated in the article by launching Calculator.

Read and download The State of NHI & AI Agent Breach Report 2026, covering 200+ breaches impacting Non-Human Identities including AI Agents.


NHI Mgmt Group analysis

Parser boundary mistakes are a governance problem, not just a coding bug. This case shows what happens when a file path is allowed to cross from data into executable script without preserving argument boundaries. Security teams should treat multi-interpreter workflows as policy-relevant surfaces, because the risk arises from how trust is transferred between components, not from any single line of code. The practical conclusion is that secure runtime design must be part of access and endpoint governance.

AppleScript injection here is really a form of command construction debt. The application tried to make dynamic script generation safe by escaping characters, but escaping is only reliable when the target syntax is fully known and singular. Once shell syntax, AppleScript syntax, and user-controlled paths overlap, the implementation accumulates hidden trust assumptions that are easy to miss in review. Practitioners should view string-built automation as a recurring control weakness, especially on endpoints used for developer tooling.

Implicit trust in local automation expands the blast radius of benign-looking inputs. Folder paths, repository contents, and archive extractions can all become delivery vehicles when an application turns them into code. That creates a control gap that sits between endpoint hardening and application security, and it is exactly the kind of boundary problem that static analysis can surface before exploitation. The practitioner lesson is to classify path handling in launcher utilities as a high-risk execution path, not a convenience feature.

Structured execution is the control pattern that matters here. The fixed design passes the program and each argument separately, which preserves intent across layers and removes the need to reason about nested escaping rules. That principle aligns with secure coding guidance such as OWASP Cheat Sheet Series recommendations on injection avoidance and safe command execution patterns. Teams should make argument separation a default design requirement anywhere user-controlled values can influence process launch.

OpenInTerminal illustrates parser chaining as an attack surface. When Swift generates AppleScript, which then invokes shell semantics, every layer becomes part of the security boundary. The named concept here is parser chain fragility: the risk that each layer is individually reasonable but collectively unsafe. For practitioners, the implication is that code review must trace cross-language trust boundaries, not just validate the local API call.

From our research library:

  • Only 44% of developers are reported to follow security best practices for secrets management, exposing a significant developer behaviour gap, according to the State of Secrets in AppSec.

What this signals

Parser chain fragility: this case shows how a control can look correct at one layer and still fail when a second interpreter reprocesses the same input. That matters for endpoint automation, developer tooling, and any workflow that turns user-controlled paths into executable text.

Security teams should treat command construction as a boundary problem, not a string-handling problem. Once data can cross from a path or filename into AppleScript, shell syntax, or another execution context, the safer control is structural argument separation, not more escaping logic.

Only 44% of developers are reported to follow security best practices for secrets management, exposing a significant developer behaviour gap, according to the State of Secrets in AppSec. The same behaviour gap shows up here when developers assume one layer of escaping is enough across multiple interpreters.


For practitioners

  • Ban string-built command launchers Require structured process APIs for any feature that launches terminal commands, editors, or helpers from user-controlled paths. The code should pass the executable and each argument separately so folder names remain data, not script text.
  • Review multi-interpreter code paths Flag any workflow where Swift, AppleScript, shell commands, or similar layers are chained together. Verify that escaping rules are aligned for every interpreter in the chain and remove any construct that depends on denylist escaping.
  • Treat file paths as untrusted input Test archive extraction, cloned repositories, nested folders, and symlinked directory structures as potential payload carriers. Include unusual characters, comments, and long path chains in security testing for launcher utilities.
  • Use static analysis for command injection patterns Add code scanning rules that detect concatenated shell commands, AppleScript do shell script usage, and other secondary interpreter patterns. Prioritise findings where user input reaches process launch logic without argument separation.

Key takeaways

  • OpenInTerminal demonstrates that the real failure is not a bad character filter but a broken trust boundary between path data and executable script.
  • The attack path uses ordinary macOS workflows, which makes archive extraction, cloned repositories, and symlinked folders relevant delivery mechanisms.
  • Structured process execution is the control that removes the ambiguity, because it keeps arguments separate instead of asking escaping to defend a command string.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

OWASP API Security Top 10 and MITRE ATT&CK address the attack and risk surface, while OWASP ASVS and CIS Controls v8 set the governance and control requirements practitioners need to meet.

FrameworkControl / ReferenceRelevance
OWASP API Security Top 10API8 — Security MisconfigurationThe issue stems from unsafe command construction and interpreter misuse rather than API logic.
Recommendation — Remove unsafe command construction patterns and preserve argument boundaries when launching external processes.
OWASP ASVSV15 — Secure Coding and ArchitectureThe bug is a secure coding failure in how user input crosses into executable script generation.
Recommendation — Apply secure coding controls that prohibit string-built commands from user-controlled input.
CIS Controls v8CIS-16 — Application Software SecurityThe flaw is a software security issue that should be caught in code review and testing.
Recommendation — Embed application security testing and code review for command injection patterns in development workflows.
MITRE ATT&CKTA0002;TA0004 — Execution; Privilege EscalationThe exploit enables code execution through crafted input and can run with the victim's local privileges.
Recommendation — Map parser-chain injection to execution and privilege impact techniques in your threat model.

Key terms

  • AppleScript Injection: AppleScript injection happens when untrusted input is inserted into an AppleScript command so the interpreter treats data as code. The flaw usually appears when applications build script strings dynamically instead of passing structured arguments, allowing quotes, comments, and concatenation to change execution behaviour.
  • Parser Chain Fragility: Parser chain fragility is the failure mode that appears when data passes through multiple interpreters, each with different syntax rules. A value that is safe in one layer can become dangerous in the next, so security depends on preserving meaning across the entire chain rather than escaping for one parser alone.
  • Structured Argument Passing: Structured argument passing sends a command and its parameters separately to the execution API instead of combining them into a single string. This preserves data boundaries, reduces injection risk, and avoids the need to predict every escaping rule used by downstream interpreters or shells.

Deepen your knowledge

NHI Mgmt Group covers identity security, NHI governance, and agentic AI through independent research, practitioner guides, and the NHI Foundation Level course. It is designed for practitioners who need to connect access governance with real-world system and workflow risks.
NHIMG Editorial Note
Published by the NHIMG editorial team on August 18, 2026.
Updated on October 12, 2026.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org