Protect Application Script Files from Tampering
Lock embedded Python, Ruby, and shell scripts in app bundles to Apple installers only, blocking IDLE-style injection backdoors.
Idea
Many macOS applications bundle interpreters and scripts within their app bundles. These embedded scripts often run with the application's privileges and code signing doesn't always validate them after installation. This creates an opportunity for attackers to modify these scripts to add malicious functionality.
A particularly concerning example is Python IDLE (the Python IDE included with macOS Python installations). As documented by Csaba Fitzl, you can modify IDLE's embedded Python scripts to inject malicious code:
sudo vi './Python 3.12/IDLE.app/Contents/Resources/idlemain.py'
# Add: os.system("osascript -e 'Tell application \"System Events\" to display dialog \"Backdoor\"'")
When IDLE launches, it executes the modified idlemain.py, running your injected code with the user's privileges. This bypasses code signing because the modified file is a resource, not part of the signed binary.
Similar vulnerabilities exist in:
- Applications with embedded Python scripts
- Apps with embedded Ruby scripts
- Applications using shell scripts in their Resources
- Electron apps with JavaScript files (covered separately in Day 1)
- Any app with interpreted code in its bundle
This is a form of "living off the land" attack - using legitimate applications as execution vehicles by modifying their supporting files.
The fix is to use file access rules to make these embedded script directories read-only, allowing only the owning application (and system update processes) to modify them.
Solutions
- Path Prefixes
- •
- •
- Options
- Allow Read Access:Audit Only:Rule Type:
- Processes
- •Signing ID:
- •Signing ID:
- •
- Custom Message
- Path Literals
- •
- •
- •
- •
- Path Prefixes
- •
- Options
- Allow Read Access:Audit Only:Rule Type:
- Processes
- •Signing ID:
- •Signing ID:
- •
- Custom Message
- Path Literals
- •
- •
- •
- •
- Options
- Allow Read Access:Audit Only:Rule Type:
- Custom Message
Mitre Attack
Tactics
Techniques
Tags
Deployment Notes
This rule protects embedded scripts in application bundles from unauthorized modification. It's particularly important for:
- Developer tools (Python IDLE, Ruby tools)
- Applications with embedded interpreters
- System utilities that use scripts
- Any app with script-based plugins
Deployment considerations:
- This rule may be too broad if many applications need to modify their own scripts
- Consider targeting specific high-value applications instead of all apps
- Allow application updaters and installers to modify their own scripts
- System updates need write access (Apple installer and softwareupdated)
Recommended approach:
- Start with audit mode to understand which apps modify their scripts
- Add specific rules for high-value targets (Python, developer tools)
- Gradually expand coverage based on risk assessment
The comprehensive rule uses wildcards which may impact performance on systems with many applications. Consider targeting specific apps if this is a concern.
False Positive Guidance
Legitimate scenarios where application scripts are modified:
- Application self-updates that modify resource files
- Plugin installation that adds scripts to app bundles
- Development tools that dynamically generate scripts
- User customization of scriptable applications
Specific applications to consider:
- Python IDLE: Usually doesn't self-modify, safe to protect
- MacVim: Users may customize configuration scripts
- Emacs: Highly customizable, users add scripts
- Other developer tools with plugin systems
Mitigation:
- Allow specific signing IDs for application updaters
- Exempt plugin managers by their signing ID
- Use Workshop tags to exempt developer machines
- Start in audit mode to identify legitimate patterns
Testing Instructions
-
Try to modify a Python IDLE script:
sudo vi '/Applications/Python 3.12/IDLE.app/Contents/Resources/idlemain.py' # Try to save changes(should be blocked)
-
Verify the application still launches:
open -a IDLE(should work normally) -
Test that system updates can still modify (if using approved signing IDs): Install a Python update from python.org (should work)
-
Check that user scripts outside app bundles work:
echo "print('test')" > ~/test.py python3 ~/test.py(should work)
Detection Methods
Monitor FAA events for attempts to modify application script files. Focus on:
Suspicious patterns:
- Modifications from unexpected processes (text editors, shells)
- Changes to Python IDLE or other developer tools
- Modifications from user-launched processes (not installers)
- Bulk modifications to multiple app bundles
Investigation steps:
- Identify which script was targeted
- Determine what application owns the script
- Check the process attempting modification
- Review if this is part of software installation or malicious tampering
- Examine the file contents if possible (may need backup/snapshot)
Legitimate modifications typically:
- Come from signed installers or updaters
- Target the application's own files
- Happen during known update windows
- Use expected update mechanisms
Resources
Related Rules
Protect Electron Apps from Heap Snapshot Backdoors
Restrict writes to Electron heap snapshot files to the app's own signed process, blocking the Trail of Bits backdoor against Slack and 1Password.
Protect Audio Plugin Directories
Block writes to audio plugin directories, stopping malicious .component bundles that run as root via coreaudiod for persistence.
Prevent Gatekeeper from Being Disabled
Block spctl from disabling macOS Gatekeeper protections, stopping attackers and social engineering attempts from weakening signature enforcement.