Back to skill

Security audit

macOS Notification Reader

Security checks for vulnerabilities and agentic risk

Overview

This skill appears purpose-aligned, but it needs Review because it requests broad Mac privacy access and can continuously archive sensitive notifications in plaintext.

Install only if you are comfortable giving Python broad Full Disk Access and storing notification contents locally. Prefer one-time/manual runs, avoid the sudo setup method, review the output directory, restrict access to generated files, and disable or remove any cron job when no longer needed.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
SKILL.md:16
Finding
Full Disk Access Is Granted to a General-Purpose Python Interpreter## Vulnerability Details **File Location**: `SKILL.md:16-30`; duplicated in `references/permission-setup.md:18-31` **Vulnerability Type**: Excessive permissions and violation of least privilege **Risk Level**: High ```markdown ### 1. Grant Full Disk Access (Required) This skill requires Full Disk Access to read the macOS notification database. ```bash # Verify permission python3 -c "import os; print('OK' if os.access(os.path.expanduser('~/Library/Group Containers/group.com.apple.usernoted/db2/db'), os.R_OK) else 'FAIL')" ``` If it returns `FAIL`, follow these steps: 1. Open **System Settings** → **Privacy & Security** → **Full Disk Access** 2. Click the 🔒 lock and enter your password 3. Click **+**, press `Cmd+Shift+G`, enter `/usr/bin/python3`, click **Open** 4. Ensure the toggle is **ON** ``` ### Technical Analysis The Skill legitimately needs access to the protected macOS notification database. However, the instructions grant Full Disk Access to `/usr/bin/python3`, a general-purpose interpreter, rather than to a dedicated application or narrowly scoped helper. macOS privacy authorization attached to the interpreter can apply to other Python programs executed through that binary. Consequently, the authorization boundary is broader than this Skill and persists independently of an individual notification-reading invocation. The Skill does not automatically grant this access, but it explicitly directs the user to do so. The requested permission therefore exceeds the narrow requirement of reading one notification database. It can expose other privacy-protected files available to processes with Full Disk Access. ### Attack Path 1. The user follows the documented setup procedure and adds `/usr/bin/python3` to Full Disk Access. 2. The authorization remains enabled after the Skill finishes. 3. The user later runs another Python script through the authorized interpreter. 4. A malicious or compromised scr ...[truncated 550 chars]
Remediation
## Remediation Suggestions - Use a dedicated, signed application or narrowly scoped helper instead of granting Full Disk Access to the system Python interpreter. - Clearly warn users that authorizing `/usr/bin/python3` may affect every script executed through that interpreter. - Make the authorization procedure opt-in and explain how to revoke it after use. - If a dedicated executable cannot be provided, recommend an isolated interpreter used exclusively for this Skill and document the remaining risk. - Access only the notification database path and avoid reading or enumerating unrelated protected locations.

T06 · System Persistence

Warning
Location
SKILL.md:53
Finding
Persistent Scheduled Collection of Sensitive Notification Content## Vulnerability Details **File Location**: `SKILL.md:53-76` **Vulnerability Type**: Persistent scheduled execution and recurring sensitive-data collection **Risk Level**: Medium ```markdown ### 3. Set Up Cron Jobs (Recommended) #### Option A: Basic Notification Export (every 30 min) ```bash # Edit crontab crontab -e # Add this line: */30 * * * * /path/to/macos-notification-reader/scripts/export-notification.sh ``` #### Option B: Work Notification Summary (every 30 min) This filters work-related notifications (Teams, Outlook) and generates a summary: ```bash crontab -e # Add this line: */30 * * * * /path/to/macos-notification-reader/scripts/work-summary.sh ``` Or use OpenClaw's built-in cron: ```bash openclaw cron add --name "Work Notification Summary" --every "30m" --message "Run work-summary.sh" ``` ### Technical Analysis The documentation recommends registering cron jobs that survive the original Skill invocation and execute every 30 minutes. The scheduled scripts repeatedly read protected notification data and write message content into date-organized files under `~/.openclaw/workspace/memory/`. Scheduling is disclosed and supports the declared automation feature, so this is not a covert persistence mechanism. Nevertheless, it is unnecessary for on-demand notification reading and increases the collection duration, data volume, and exposure window. No retention limit, automatic deletion procedure, file-permission hardening, or cron removal instructions are provided. The scheduled export also processes notifications from the preceding 24 hours on every run, potentially creating many duplicated plaintext archives. ### Attack Path 1. The user follows the recommendation and adds one of the commands to `crontab` or OpenClaw cron. 2. The task persists across terminal sessions and repeatedly invokes the scripts. 3. Notifications from messaging, email, and work applications are read in the ...[truncated 691 chars]
Remediation
## Remediation Suggestions - Present scheduled execution as an optional advanced feature rather than the recommended default. - Require explicit user confirmation before enabling recurring collection. - Document exact removal commands for both user crontab and OpenClaw cron registrations. - Apply a configurable retention period and automatically delete obsolete archives. - Restrict collection to explicitly selected applications and use the shortest practical lookback period. - Create output directories with mode `0700` and files with mode `0600`. - Avoid repeatedly archiving the same 24-hour period; track the last successfully processed timestamp. - Explain that notification bodies are stored as plaintext and may be included in backups or workspace synchronization.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/read_notifications.py:143
Finding
Predictable Shared Temporary Files Expose Notification Data to Race and Symlink Attacks## Vulnerability Details **File Location**: `scripts/read_notifications.py:143-160`; related predictable paths in `scripts/export-notification.sh:18-31` and `scripts/work-summary.sh:26-43` **Vulnerability Type**: Unsafe temporary-file handling **Risk Level**: Medium ```python # Copy database to temp directory temp_db = Path("/tmp/notif_pipeline.db") try: shutil.copy2(original_db, temp_db) except PermissionError: with open(output_file, 'w') as f: f.write("ERROR: Permission denied\n") f.write("Please grant Full Disk Access to python3:\n") f.write(" System Settings → Privacy & Security → Full Disk Access → Add /usr/bin/python3\n") print(f"ERROR: Permission denied: {output_file}") return except Exception as e: with open(output_file, 'w') as f: f.write(f"ERROR: {e}\n") print(f"ERROR: {e}") return # Read database conn = sqlite3.connect(str(temp_db)) ``` Related wrapper behavior: ```bash python3 "$NOTIF_SCRIPT" --hours 24 --output "/tmp/notif_$TIMESTAMP.txt" 2>/dev/null ``` ```python temp_file = f"/tmp/notif_{timestamp}.txt" ``` ```bash python3 "$NOTIF_SCRIPT" --minutes 35 --output "/tmp/notif_work_$TIMESTAMP.txt" 2>/dev/null ``` ### Technical Analysis The core reader always copies the protected notification database to the fixed path `/tmp/notif_pipeline.db`. The wrapper scripts also construct temporary notification filenames from timestamps. These names are predictable and are placed in a shared temporary directory without secure exclusive creation. `shutil.copy2()` follows normal filesystem path resolution and does not establish a securely created private temporary file. An attacker who can anticipate or pre-create the destination may attempt a symlink attack, file substitution, denial of service, or data redirection. Concurrent scheduled runs also share the same database-copy path, allowing one invocation to overwrite, re ...[truncated 1458 chars]
Remediation
## Remediation Suggestions - Replace all fixed and timestamp-derived `/tmp` paths with `tempfile.TemporaryDirectory()` or securely created `NamedTemporaryFile` instances. - Create temporary files exclusively with restrictive mode `0600`. - Keep each invocation's database copy and intermediate output in a unique private directory. - Pass the generated path explicitly to wrapper processes rather than reconstructing it from a timestamp. - Place database connection closure and temporary-file deletion in `finally` blocks. - Reject symbolic links where practical and avoid opening attacker-controlled paths after checking them separately. - Add locking if overlapping scheduled invocations must be prevented. - Do not suppress all standard error output; log failures without including notification content.

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
references/permission-setup.md:34
Finding
Documentation Recommends an Unverified Privileged System-Configuration Command## Vulnerability Details **File Location**: `references/permission-setup.md:34-41` **Vulnerability Type**: Unsafe privileged configuration guidance **Risk Level**: Medium ```markdown #### Method 2: Via Terminal (Advanced) ```bash # Add python3 to Full Disk Access (requires sudo and may vary by system) # Research the correct command for your macOS version sudo dscl . append ~/Library/Preferences/com.apple.security.common file /usr/bin/python3 ``` Note: Method 2 may not work on newer macOS versions. Use Method 1 for reliability. ``` ### Technical Analysis The guide asks the user to execute `dscl` through `sudo` while simultaneously stating that the command may vary by system and may not work. This is an unverified use of a root-authorized directory-service utility for privacy configuration. The command is not necessary to run the Skill because the same documentation provides the supported System Settings procedure. Recommending a speculative command under `sudo` violates least-privilege principles and encourages users to approve a system-level modification without a reliable description of its exact effects. ### Attack Path 1. The user cannot access the notification database and selects the documented advanced method. 2. The user executes the supplied `sudo dscl` command and authenticates as an administrator. 3. The command attempts to modify local directory-service configuration using arguments presented as privacy settings. 4. The modification may be ineffective, malformed, or affect configuration other than the intended Full Disk Access control. 5. The user may incorrectly assume the required permission was securely configured and continue troubleshooting with further elevated commands. ### Impact Assessment The immediate impact is an unintended or ineffective privileged system-configuration change. The command does not contain an external payload and there is no evidence that it directly grants an attacke ...[truncated 159 chars]
Remediation
## Remediation Suggestions - Remove the `sudo dscl` method entirely. - Retain only the documented macOS System Settings workflow for granting Full Disk Access. - Do not publish privileged commands unless they are supported by Apple documentation and tested on every declared platform version. - If command-line configuration is unavailable, explicitly state that the permission must be granted interactively. - Add instructions for verifying and revoking the permission through System Settings.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (22)

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly reads and exports Notification Center contents, which commonly include message previews, email subjects, calendar details, names, and other sensitive personal or corporate data. The documentation mentions local storage and scheduling but does not clearly warn users that enabling automated exports can create a persistent plaintext archive of sensitive notifications in markdown files.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
# Edit crontab
crontab -e

# Add this line:
*/30 * * * * /path/to/macos-notification-reader/scripts/export-notification.sh
Confidence
90% confidence
Finding
The documentation encourages persistent scheduled execution via cron for periodic notification export. In this skill's context, persistence materially increases privacy risk because it continuously collects and archives sensitive notification content over time, potentially creating a long-lived local surveillance log if the workstation is shared, compromised, or backed up insecurely.

Session Persistence

Medium
Category
Rogue Agent
Content
This filters work-related notifications (Teams, Outlook) and generates a summary:

```bash
crontab -e

# Add this line:
*/30 * * * * /path/to/macos-notification-reader/scripts/work-summary.sh
Confidence
92% confidence
Finding
This scheduled work-summary mode adds recurring collection plus categorization of work-related notifications, which may aggregate sensitive corporate communications and action items into searchable markdown summaries. The persistence is more dangerous in context than a generic cron example because it systematically condenses potentially confidential business information into durable local reports.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The documented summary output uses Chinese headings and labels such as '工作通知摘要' and '待处理事项', which indicates the skill may generate reports in a fixed language. The file does not state that language is configurable or that users can opt into this locale, creating a natural-language policy concern.

File System Enumeration

Medium
Category
Data Exfiltration
Content
### "Cannot find notification database"

- Ensure macOS 15.0 or later
- Check: `ls -la ~/Library/Group\ Containers/group.com.apple.usernoted/db2/`

### Notifications are empty
Confidence
60% confidence
Finding
Code scans file system directories looking for sensitive files. This could be reconnaissance for credential theft.

Vague Triggers

Medium
Confidence
87% confidence
Finding
The description advertises broad access to the macOS notification center database and summary generation, but it does not define clear user-trigger conditions, data minimization, or limits on what notifications are read. In combination with the declared full-disk-access permission, this creates meaningful privacy and over-collection risk because the skill could process sensitive personal or work messages beyond what a user reasonably expects.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The guide instructs users to grant Full Disk Access so the skill can read the macOS notifications database, which may contain sensitive personal and security-relevant data such as messages, verification codes, and app activity. Requesting such broad permission without a prominent privacy warning, scope limitation, or data-handling disclosure increases the risk of over-collection and user harm if the skill is misused or compromised.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The advanced method tells users to use sudo and modify security-related settings without a strong warning about the risks of elevated privileges, incorrect commands, or system misconfiguration. In the context of a skill that already seeks access to protected notification data, this guidance lowers user defenses and may normalize unsafe privilege escalation for sensitive data access.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
#### Method 2: Via Terminal (Advanced)

```bash
# Add python3 to Full Disk Access (requires sudo and may vary by system)
# Research the correct command for your macOS version
sudo dscl . append ~/Library/Preferences/com.apple.security.common file /usr/bin/python3
```
Confidence
91% confidence
Finding
The document includes a sudo command that encourages privileged execution to alter system-related preferences for Python access. Even though it is presented as advanced and possibly unreliable, publishing root-level instructions without strong safeguards can lead to unsafe execution, misconfiguration, or abuse by users who do not understand the implications.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
```bash
# Add python3 to Full Disk Access (requires sudo and may vary by system)
# Research the correct command for your macOS version
sudo dscl . append ~/Library/Preferences/com.apple.security.common file /usr/bin/python3
```

Note: Method 2 may not work on newer macOS versions. Use Method 1 for reliability.
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Data Retention

- macOS automatically deletes notifications after ~3-7 days
- Cannot be configured by users
- This skill can only access notifications that still exist in the database
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## Data Retention

- macOS automatically deletes notifications after ~3-7 days
- Cannot be configured by users
- This skill can only access notifications that still exist in the database
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
This script exports macOS notification contents, which can include sensitive personal or security-relevant data such as message previews, MFA codes, emails, and calendar details, into a persistent file under the user's workspace. Because the export happens automatically and without any user-facing warning, consent prompt, minimization, or retention control, it increases the risk of unintended disclosure to other tools, backups, sync services, or local users/processes with access to that directory.

Session Persistence

Medium
Category
Rogue Agent
Content
import sqlite3
import shutil
import subprocess
import plistlib
from pathlib import Path
from datetime import datetime, timezone, timedelta
import argparse
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
import sqlite3
import shutil
import subprocess
import plistlib
from pathlib import Path
from datetime import datetime, timezone, timedelta
import argparse
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
import sqlite3
import shutil
import subprocess
import plistlib
from pathlib import Path
from datetime import datetime, timezone, timedelta
import argparse
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Session Persistence

Medium
Category
Rogue Agent
Content
import sqlite3
import shutil
import subprocess
import plistlib
from pathlib import Path
from datetime import datetime, timezone, timedelta
import argparse
Confidence
75% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
# Legacy path (macOS 14 and earlier)
    try:
        conf_dir = subprocess.check_output(["getconf", "DARWIN_USER_DIR"]).decode().strip()
        db_path = Path(conf_dir) / 'com.apple.notificationcenter' / 'db2' / 'db'
        if db_path.exists():
            return db_path
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Missing User Warnings

Medium
Confidence
99% confidence
Finding
The script reads macOS Notification Center data and exports notification titles and bodies to a file, which can include highly sensitive content such as MFA codes, private messages, email previews, and calendar details. In skill context, this is especially dangerous because it quietly collects recent user data and writes it to disk with no explicit consent flow, minimization, masking, or warning, increasing the risk of privacy compromise and credential theft.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script persists notification content from work apps into a markdown file under the user's home directory, including message snippets and inferred action items. Notifications often contain sensitive business data, personal information, or confidential requests, so storing them without minimization, consent, retention controls, or clear warning increases the risk of unintended disclosure from local compromise, backups, sync tools, or later agent access.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The description implies generalized reading of notifications from multiple apps without mentioning user choice, privacy boundaries, or constraints on personal versus work content. Because notifications often contain message previews, meeting details, email subjects, and other sensitive content, unrestricted reading and summarization can expose confidential information or aggregate more data than needed.

Natural-Language Policy Violations

Low
Confidence
97% confidence
Finding
The script hardcodes Chinese headings and status text in the generated report, which imposes a specific language regardless of user preference. The file does not indicate that the skill is region-specific or provide any language-selection mechanism.

Static analysis

No suspicious patterns detected.