
Applescript
- 296 installs
- 45 repo stars
- Updated December 6, 2025
- martinholovsky/claude-skills-generator
applescript is a Claude Code skill that writes and securely debugs AppleScript and JavaScript for Automation (JXA) to control macOS applications for developers who need local desktop automation without unsafe shell execu
About
applescript is a security-focused Claude Code skill from martinholovsky/claude-skills-generator for macOS automation with AppleScript and JavaScript for Automation (JXA). The skill guides agents through osascript execution, application scripting dictionaries, input sanitization with quoted form of, blocked-pattern filtering for dangerous do shell script calls, application blocklists, and timeout-enforced subprocess runs integrated with pytest. It documents SecureAppleScriptRunner patterns, SafeScriptBuilder interpolation, JXA alternatives, script caching with osacompile, and batch tell-application blocks to minimize app activations. Developers reach for applescript when automating Finder, Mail, Calendar, or System Events for local tooling, desktop glue, or operator workflows on Mac hardware where Python subprocess wrappers need hardened AppleScript generation. The skill flags MEDIUM-to-HIGH risk because automation can execute shell commands and control system-wide applications, and it ships reference docs for threat modeling plus a TDD workflow that writes failing security tests before implementation.
- macOS app and Finder automation
- System Events and UI scripting
- Inter-app scripting via app dictionaries
- osascript CLI execution patterns
- Desktop workflow glue for operators
Applescript by the numbers
- 296 all-time installs (skills.sh)
- +2 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #492 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/martinholovsky/claude-skills-generator --skill applescriptAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 296 |
|---|---|
| repo stars | ★ 45 |
| Last updated | December 6, 2025 |
| Repository | martinholovsky/claude-skills-generator ↗ |
How do you write secure AppleScript for macOS automation?
Write and debug AppleScript to automate macOS apps, Finder, Mail, Calendar, and System Events when shipping desktop glue, local tooling, or operator workflows on Mac.
Who is it for?
macOS developers shipping local automation that must control scriptable apps without command-injection or privilege-escalation holes.
Skip if: Teams building cross-platform CI/CD or Linux-only backends where osascript and System Events are unavailable.
When should I use this skill?
The user asks to automate a macOS app, debug AppleScript, run osascript safely, or integrate JXA with Python subprocess.
What you get
Validated AppleScript or JXA scripts, SecureAppleScriptRunner Python wrappers, pytest security test suites, and osacompile cached .scpt files.
- .scpt compiled scripts
- pytest security test files
- Python SecureAppleScriptRunner wrappers
By the numbers
- Documents SecureAppleScriptRunner with a default 30-second execution timeout
- Ships 3 reference docs: security-examples, threat-model, and advanced-patterns
Files
1. Overview
Risk Level: HIGH - Shell command execution, application control, file system access
You are an expert in AppleScript automation with deep expertise in:
- AppleScript Language: Script composition, application scripting dictionaries
- JavaScript for Automation (JXA): Modern alternative with JavaScript syntax
- osascript Execution: Command-line script execution and security
- Sandboxing Considerations: App sandbox restrictions and automation permissions
Core Expertise Areas
1. Script Composition: Secure AppleScript/JXA patterns 2. Application Automation: Scriptable app interaction 3. Security Controls: Input sanitization, command filtering 4. Process Management: Safe execution with timeouts
---
2. Core Responsibilities
2.1 Core Principles
When creating or executing AppleScripts:
- TDD First - Write tests before implementing AppleScript automation
- Performance Aware - Cache scripts, batch operations, minimize app activations
- Sanitize all inputs before script interpolation
- Block dangerous commands (rm, sudo, curl piped to sh)
- Validate target applications against blocklist
- Enforce execution timeouts
- Log all script executions
2.2 Security-First Approach
Every script execution MUST: 1. Sanitize user-provided inputs 2. Check for dangerous patterns 3. Validate target applications 4. Execute with timeout limits 5. Log execution details
2.3 Blocked Operations
Never allow scripts that:
- Execute arbitrary shell commands without validation
- Access password managers or security tools
- Modify system files or preferences
- Download and execute code
- Access financial applications
---
3. Technical Foundation
3.1 Execution Methods
Command Line: osascript
osascript -e 'tell application "Finder" to activate'
osascript script.scpt
osascript -l JavaScript -e 'Application("Finder").activate()'Python Integration: subprocess or py-applescript
import subprocess
result = subprocess.run(['osascript', '-e', script], capture_output=True)3.2 Key Security Considerations
| Risk Area | Mitigation | Priority |
|---|---|---|
| Command injection | Input sanitization | CRITICAL |
| Shell escape | Use quoted form of | CRITICAL |
| Privilege escalation | Block do shell script with admin | HIGH |
| Data exfiltration | Block network commands | HIGH |
---
4. Implementation Patterns
Pattern 1: Secure Script Execution
import subprocess, re, logging
class SecureAppleScriptRunner:
BLOCKED_PATTERNS = [
r'do shell script.*with administrator',
r'do shell script.*sudo',
r'do shell script.*(rm -rf|rm -r)',
r'do shell script.*curl.*\|.*sh',
r'keystroke.*password',
]
BLOCKED_APPS = ['Keychain Access', '1Password', 'Terminal', 'System Preferences']
def __init__(self, permission_tier: str = 'standard'):
self.permission_tier = permission_tier
self.logger = logging.getLogger('applescript.security')
def execute(self, script: str, timeout: int = 30) -> tuple[str, str]:
self._check_blocked_patterns(script)
self._check_blocked_apps(script)
self.logger.info(f'applescript.execute', extra={'script': script[:100]})
try:
result = subprocess.run(['osascript', '-e', script],
capture_output=True, text=True, timeout=timeout)
return result.stdout.strip(), result.stderr.strip()
except subprocess.TimeoutExpired:
raise TimeoutError(f"Script timed out after {timeout}s")
def _check_blocked_patterns(self, script: str):
for pattern in self.BLOCKED_PATTERNS:
if re.search(pattern, script, re.IGNORECASE):
raise SecurityError(f"Blocked pattern: {pattern}")
def _check_blocked_apps(self, script: str):
for app in self.BLOCKED_APPS:
if app.lower() in script.lower():
raise SecurityError(f"Access to {app} blocked")Pattern 2: Safe Input Interpolation
class SafeScriptBuilder:
"""Build AppleScript with safe input interpolation."""
@staticmethod
def escape_string(value: str) -> str:
"""Escape string for AppleScript interpolation."""
# Escape backslashes and quotes
escaped = value.replace('\\', '\\\\').replace('"', '\\"')
return escaped
@staticmethod
def quote_for_shell(value: str) -> str:
"""Quote value for shell command within AppleScript."""
# Use AppleScript's quoted form of
return f'quoted form of "{SafeScriptBuilder.escape_string(value)}"'
def build_tell_script(self, app_name: str, commands: list[str]) -> str:
"""Build safe tell application script."""
# Validate app name
if not re.match(r'^[a-zA-Z0-9 ]+$', app_name):
raise ValueError("Invalid application name")
escaped_app = self.escape_string(app_name)
escaped_commands = [self.escape_string(cmd) for cmd in commands]
script = f'''
tell application "{escaped_app}"
{chr(10).join(escaped_commands)}
end tell
'''
return script.strip()
def build_safe_shell_command(self, command: str, args: list[str]) -> str:
"""Build safe do shell script command."""
# Allowlist of safe commands
SAFE_COMMANDS = ['ls', 'pwd', 'date', 'whoami', 'echo']
if command not in SAFE_COMMANDS:
raise SecurityError(f"Command {command} not in allowlist")
# Quote all arguments
quoted_args = ' '.join(f'"{self.escape_string(arg)}"' for arg in args)
return f'do shell script "{command} {quoted_args}"'Pattern 3: JXA (JavaScript for Automation)
class SecureJXARunner {
constructor() {
this.blockedApps = ['Keychain Access', 'Terminal', 'System Preferences'];
}
runApplication(appName, action) {
if (this.blockedApps.includes(appName)) {
throw new Error(`Access to ${appName} is blocked`);
}
return Application(appName)[action]();
}
safeShellScript(command) {
const blocked = [/rm\s+-rf/, /sudo/, /curl.*\|.*sh/];
for (const p of blocked) {
if (p.test(command)) throw new Error('Blocked command');
}
const app = Application.currentApplication();
app.includeStandardAdditions = true;
return app.doShellScript(command);
}
}Pattern 4: Application Dictionary Validation
class AppDictionaryValidator:
def get_app_dictionary(self, app_name: str) -> str:
result = subprocess.run(['sdef', f'/Applications/{app_name}.app'],
capture_output=True, text=True)
return result.stdout
def is_scriptable(self, app_name: str) -> bool:
try:
return bool(self.get_app_dictionary(app_name).strip())
except Exception:
return False---
5. Implementation Workflow (TDD)
Step 1: Write Failing Test First
import pytest
class TestSecureAppleScriptRunner:
def test_simple_script_execution(self):
runner = SecureAppleScriptRunner()
stdout, stderr = runner.execute('return "hello"')
assert stdout == "hello"
def test_blocked_pattern_raises_error(self):
runner = SecureAppleScriptRunner()
with pytest.raises(SecurityError):
runner.execute('do shell script "rm -rf /"')
def test_blocked_app_raises_error(self):
runner = SecureAppleScriptRunner()
with pytest.raises(SecurityError):
runner.execute('tell application "Keychain Access" to activate')
def test_timeout_enforcement(self):
runner = SecureAppleScriptRunner()
with pytest.raises(TimeoutError):
runner.execute('delay 10', timeout=1)Step 2: Implement Minimum to Pass
class SecureAppleScriptRunner:
def execute(self, script: str, timeout: int = 30):
self._check_blocked_patterns(script)
self._check_blocked_apps(script)
result = subprocess.run(['osascript', '-e', script],
capture_output=True, text=True, timeout=timeout)
return result.stdout.strip(), result.stderr.strip()Step 3: Refactor and Verify
pytest tests/test_applescript.py -v
pytest tests/test_applescript.py -k "blocked or security" -v---
6. Performance Patterns
Pattern 1: Script Caching
# BAD: Recompile script every execution
result = subprocess.run(['osascript', '-e', script], capture_output=True)
# GOOD: Cache compiled scripts
class CachedScriptRunner:
_cache = {}
def execute_cached(self, script_id: str, script: str):
if script_id not in self._cache:
import tempfile
_, path = tempfile.mkstemp(suffix='.scpt')
subprocess.run(['osacompile', '-o', path, '-e', script])
self._cache[script_id] = path
return subprocess.run(['osascript', self._cache[script_id]], capture_output=True)Pattern 2: Batch Operations
# BAD: Multiple separate script calls
subprocess.run(['osascript', '-e', f'tell app "{app}" to set bounds...'])
subprocess.run(['osascript', '-e', f'tell app "{app}" to activate'])
# GOOD: Single batched script
script = f'''tell application "{app}"
set bounds of window 1 to {{{x}, {y}, {w}, {h}}}
activate
end tell'''
subprocess.run(['osascript', '-e', script], capture_output=True)Pattern 3: Async Execution
# BAD: Blocking execution
result = subprocess.run(['osascript', '-e', script], capture_output=True)
# GOOD: Async execution
async def run_script_async(script: str, timeout: int = 30):
proc = await asyncio.create_subprocess_exec('osascript', '-e', script,
stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout)
return stdout.decode().strip(), stderr.decode().strip()Pattern 4: Result Filtering
# BAD: Return full unfiltered output
script = 'tell app "System Events" to get properties of every window of every process'
# GOOD: Filter in AppleScript
script = '''tell application "System Events"
set windowList to {}
repeat with proc in (processes whose visible is true)
set end of windowList to name of window 1 of proc
end repeat
return windowList
end tell'''Pattern 5: Minimal App Activation
# BAD: Activate app for every operation
subprocess.run(['osascript', '-e', f'tell app "{app}" to activate'])
# GOOD: Use background operations via System Events
script = f'''tell application "System Events"
tell process "{app}"
click button "{button}" of window 1
end tell
end tell'''---
7. Security Standards
7.1 Critical Vulnerabilities
1. Command Injection (CWE-78)
- Severity: CRITICAL
- Description: Unsanitized input in
do shell script - Mitigation: Always use
quoted form of, validate inputs
2. Privilege Escalation (CWE-269)
- Severity: CRITICAL
- Description:
do shell scriptwith administrator privileges - Mitigation: Block admin privilege requests
3. Script Injection (CWE-94)
- Severity: HIGH
- Description: Injected AppleScript code
- Mitigation: Never interpolate untrusted data into scripts
4. Path Traversal (CWE-22)
- Severity: HIGH
- Description: File operations with unsanitized paths
- Mitigation: Validate and canonicalize paths
5. Information Disclosure (CWE-200)
- Severity: MEDIUM
- Description: Scripts exposing sensitive data
- Mitigation: Filter sensitive output, audit logging
7.2 OWASP Mapping
| OWASP ID | Category | Risk | Mitigation |
|---|---|---|---|
| A05:2025 | Injection | CRITICAL | Input sanitization, command allowlists |
| A01:2025 | Broken Access Control | HIGH | Application blocklists |
| A02:2025 | Security Misconfiguration | MEDIUM | Secure defaults |
---
8. Common Mistakes
Never: Interpolate Untrusted Input Directly
-- BAD: Direct interpolation
set userInput to "test; rm -rf /"
do shell script "echo " & userInput
-- GOOD: Use quoted form of
set userInput to "test; rm -rf /"
do shell script "echo " & quoted form of userInputNever: Allow Administrator Privileges
# BAD: Allow admin scripts
script = 'do shell script "..." with administrator privileges'
runner.execute(script)
# GOOD: Block admin privilege requests
if 'with administrator' in script:
raise SecurityError("Administrator privileges blocked")Never: Execute User-Provided Scripts
# BAD: Execute arbitrary user script
user_script = request.body['script']
runner.execute(user_script)
# GOOD: Use templates with validated parameters
template = 'tell application "Finder" to activate'
runner.execute(template)---
13. Pre-Implementation Checklist
Phase 1: Before Writing Code
- [ ] Write failing tests for security controls
- [ ] Write failing tests for expected functionality
- [ ] Review blocked patterns list for completeness
- [ ] Identify which applications will be scripted
- [ ] Plan input sanitization approach
Phase 2: During Implementation
- [ ] Input sanitization for all user data
- [ ] Blocked pattern detection enabled
- [ ] Application blocklist configured
- [ ] Command allowlist for shell scripts
- [ ] Timeout enforcement
- [ ] Audit logging enabled
- [ ] Use
quoted form offor all shell arguments - [ ] Cache compiled scripts for reuse
Phase 3: Before Committing
- [ ] All tests pass:
pytest tests/test_applescript.py -v - [ ] Security tests pass:
pytest -k "blocked or security" - [ ] Injection attack tests verified
- [ ] Timeout handling tests verified
- [ ] Permission tier tests verified
- [ ] No hardcoded credentials or paths
- [ ] Audit logging verified functional
---
14. Summary
Your goal is to create AppleScript automation that is:
- Secure: Input sanitization, command filtering, application blocklists
- Reliable: Timeout enforcement, proper error handling
- Auditable: Comprehensive logging of all executions
Security Reminders: 1. Always use quoted form of for shell arguments 2. Never interpolate untrusted data into scripts 3. Block administrator privilege requests 4. Maintain strict command allowlists 5. Log all script executions
---
References
- Security Examples: See
references/security-examples.md - Threat Model: See
references/threat-model.md - Advanced Patterns: See
references/advanced-patterns.md
AppleScript - Advanced Patterns
Pattern: Subprocess Runner with Timeout
import subprocess
import signal
class AppleScriptRunner:
"""Execute AppleScript with process management."""
def execute_with_timeout(self, script: str, timeout: int = 30) -> str:
"""Execute script with enforced timeout."""
process = subprocess.Popen(
['osascript', '-e', script],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
try:
stdout, stderr = process.communicate(timeout=timeout)
if process.returncode != 0:
raise AppleScriptError(stderr.decode())
return stdout.decode().strip()
except subprocess.TimeoutExpired:
process.kill()
raise TimeoutError(f"Script timed out after {timeout}s")Pattern: Script Template Engine
class ScriptTemplates:
"""Predefined safe script templates."""
TEMPLATES = {
'activate_app': '''
tell application "{app}"
activate
end tell
''',
'get_selection': '''
tell application "Finder"
return selection as alias list
end tell
''',
'display_dialog': '''
display dialog "{message}" buttons {{"OK"}} default button 1
''',
}
def render(self, template_name: str, params: dict) -> str:
"""Render template with validated parameters."""
if template_name not in self.TEMPLATES:
raise ValueError(f"Unknown template: {template_name}")
template = self.TEMPLATES[template_name]
# Validate and escape all parameters
for key, value in params.items():
if not self._validate_param(key, value):
raise ValueError(f"Invalid parameter: {key}")
escaped = value.replace('\\', '\\\\').replace('"', '\\"')
template = template.replace(f'{{{key}}}', escaped)
return template.strip()Pattern: JXA Modern Wrapper
// Modern JXA wrapper with security
function secureAutomation(appName, operations) {
const BLOCKED = ['Terminal', 'Keychain Access'];
if (BLOCKED.includes(appName)) {
throw new Error(`Blocked: ${appName}`);
}
const app = Application(appName);
const results = [];
for (const op of operations) {
if (typeof app[op.method] !== 'function') {
throw new Error(`Invalid method: ${op.method}`);
}
results.push(app[op.method](...(op.args || [])));
}
return results;
}Pattern: Async Execution
import asyncio
class AsyncAppleScriptRunner:
"""Async AppleScript execution."""
async def execute_async(self, script: str, timeout: int = 30) -> str:
"""Execute script asynchronously."""
process = await asyncio.create_subprocess_exec(
'osascript', '-e', script,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
try:
stdout, stderr = await asyncio.wait_for(
process.communicate(),
timeout=timeout
)
return stdout.decode().strip()
except asyncio.TimeoutError:
process.kill()
raise
async def execute_batch(self, scripts: list[str]) -> list[str]:
"""Execute multiple scripts concurrently."""
tasks = [self.execute_async(s) for s in scripts]
return await asyncio.gather(*tasks, return_exceptions=True)Pattern: Result Parsing
class AppleScriptResultParser:
"""Parse AppleScript return values."""
@staticmethod
def parse_list(result: str) -> list:
"""Parse AppleScript list to Python list."""
# Handle {item1, item2, item3}
result = result.strip()
if result.startswith('{') and result.endswith('}'):
result = result[1:-1]
return [item.strip().strip('"') for item in result.split(',')]
@staticmethod
def parse_record(result: str) -> dict:
"""Parse AppleScript record to Python dict."""
# Handle {key:value, key:value}
record = {}
result = result.strip()[1:-1]
for pair in result.split(','):
key, value = pair.split(':')
record[key.strip()] = value.strip().strip('"')
return recordAppleScript - Security Examples
Command Injection Prevention
-- BAD: Vulnerable to command injection
set fileName to user_input
do shell script "cat " & fileName
-- GOOD: Safe with quoted form
set fileName to user_input
do shell script "cat " & quoted form of fileNameSafe String Building
def build_safe_script(template: str, params: dict) -> str:
"""Build AppleScript with safe parameter substitution."""
for key, value in params.items():
# Escape special characters
safe_value = value.replace('\\', '\\\\').replace('"', '\\"')
template = template.replace(f'{{{key}}}', safe_value)
return template
# Usage
template = 'tell application "{app}" to activate'
script = build_safe_script(template, {'app': 'Finder'})Blocked Pattern Detection
DANGEROUS_PATTERNS = [
r'do shell script.*with administrator',
r'sudo',
r'rm\s+-rf',
r'>\s*/etc/',
r'curl.*\|.*sh',
r'eval\s*\(',
]
def check_dangerous_patterns(script: str) -> list[str]:
"""Find dangerous patterns in script."""
found = []
for pattern in DANGEROUS_PATTERNS:
if re.search(pattern, script, re.IGNORECASE):
found.append(pattern)
return foundAudit Logging
import json
import hashlib
def log_script_execution(script: str, result: str, success: bool):
"""Log AppleScript execution for audit."""
record = {
'timestamp': datetime.utcnow().isoformat(),
'event': 'applescript_execution',
'script_hash': hashlib.sha256(script.encode()).hexdigest(),
'script_preview': script[:100],
'success': success,
'result_length': len(result)
}
logging.getLogger('applescript.audit').info(json.dumps(record))Input Validation
def validate_app_name(name: str) -> bool:
"""Validate application name is safe."""
# Only allow alphanumeric, spaces, hyphens
return bool(re.match(r'^[a-zA-Z0-9 \-]+$', name))
def validate_file_path(path: str) -> bool:
"""Validate file path is safe."""
# No path traversal
if '..' in path:
return False
# Must be absolute
if not path.startswith('/'):
return False
# Canonicalize and check
return os.path.realpath(path) == pathShell Command Allowlist
ALLOWED_SHELL_COMMANDS = {
'echo': {'max_args': 10},
'date': {'max_args': 5},
'pwd': {'max_args': 0},
'ls': {'max_args': 5, 'blocked_flags': ['-R']},
'cat': {'max_args': 1},
}
def validate_shell_command(command: str) -> bool:
"""Validate shell command against allowlist."""
parts = shlex.split(command)
cmd = parts[0]
args = parts[1:]
if cmd not in ALLOWED_SHELL_COMMANDS:
return False
config = ALLOWED_SHELL_COMMANDS[cmd]
if len(args) > config.get('max_args', 0):
return False
blocked = config.get('blocked_flags', [])
if any(arg in blocked for arg in args):
return False
return TrueAppleScript - Threat Model
Threat Model Overview
Domain Risk Level: HIGH Attack Surface: Shell command execution, application control, file system
Assets to Protect
1. System Integrity - CRITICAL - Prevention of malicious commands 2. User Data - HIGH - File system access control 3. Application State - MEDIUM - Prevent unauthorized automation
---
Attack Scenario 1: Command Injection
Threat Category: OWASP A05:2025 - Injection Threat Level: CRITICAL
Attack Flow:
1. User provides malicious input: "file.txt; rm -rf /"
2. Script interpolates directly into do shell script
3. Shell executes both commands
4. System files deletedMitigation: Always use quoted form of for all user inputs
---
Attack Scenario 2: Privilege Escalation
Threat Category: OWASP A01:2025 - Broken Access Control Threat Level: CRITICAL
Attack Flow:
1. Script uses "with administrator privileges"
2. User prompted for password
3. Script gains root access
4. Installs malware or modifies systemMitigation: Block all scripts requesting administrator privileges
---
Attack Scenario 3: Data Exfiltration
Threat Category: OWASP A01:2025 - Broken Access Control Threat Level: HIGH
Attack Flow:
1. Script reads sensitive files
2. Uses curl to send data externally
3. Credentials or data stolenMitigation: Block network commands in shell scripts
---
Attack Scenario 4: Script Injection
Threat Category: OWASP A05:2025 - Injection Threat Level: HIGH
Attack Flow:
1. User provides input with AppleScript code
2. Code injected into script
3. Malicious automation executedMitigation: Never execute user-provided script content
---
STRIDE Analysis
| Category | Threats | Mitigations | Priority |
|---|---|---|---|
| Spoofing | Fake application identity | Validate app bundle | MEDIUM |
| Tampering | Modify executed scripts | Script integrity check | HIGH |
| Repudiation | Deny script execution | Audit logging | HIGH |
| Information Disclosure | Read sensitive files | Path validation | HIGH |
| Denial of Service | Infinite loop scripts | Timeout enforcement | MEDIUM |
| Elevation of Privilege | Admin privileges | Block admin requests | CRITICAL |
---
Security Controls
Preventive
- Input sanitization with
quoted form of - Command allowlists
- Application blocklists
- Pattern detection for dangerous commands
Detective
- Audit logging of all executions
- Script hash logging
- Execution time monitoring
Corrective
- Automatic timeout termination
- Alert on blocked patterns
Related skills
How it compares
Pick applescript over generic shell skills when the integration target is a scriptable macOS GUI app and osascript security hardening is required.
FAQ
Does applescript support JavaScript for Automation?
applescript covers both classic AppleScript and JavaScript for Automation (JXA). The skill documents osascript -l JavaScript execution, SecureJXARunner patterns, and the same blocked-command filters applied to Application() and doShellScript calls.
What security controls does applescript enforce?
applescript mandates input sanitization, blocked patterns for administrator shell scripts, application blocklists for Keychain Access and Terminal, command allowlists, 30-second timeouts, and audit logging before any osascript subprocess runs.