Back to skill

Security audit

ICS CRM Reminder

Security checks for vulnerabilities and agentic risk

Overview

This skill coherently creates local calendar reminder files from CRM details, with implementation issues around privacy warnings, output path handling, and ICS escaping but no evidence of hidden or malicious behavior.

Reasonable to install if you want German-styled CRM calendar reminders, but generate files only from trusted CRM text, keep output paths in a dedicated workspace folder, review the .ics before importing, and remember that contact and deal details may sync to calendar services.

Vulnerability Patterns
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_ics.py:144
Finding

ICS Property and Component Injection Through Unescaped User Input

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_ics.py, lines 144-157
Vulnerability Type: ICS property/component injection
Risk Level: Medium

Vulnerable Code

python
if args.alarm > 0:
    ics_lines.extend([
        'BEGIN:VALARM',
        'TRIGGER:-PT{}M'.format(args.alarm),
        'ACTION:DISPLAY',
        f'DESCRIPTION:Reminder: {args.firma} kontaktieren',
        'END:VALARM',
    ])

# Add categories based on deal phase
categories = ['viSales CRM']
if args.deal_phase:
    categories.append(args.deal_phase)
if args.prioritaet.lower() == 'hoch':
    categories.append('Priorität Hoch')
ics_lines.append(f'CATEGORIES:{",".join(categories)}')

Technical Analysis

The firma and deal_phase command-line arguments originate from user-provided CRM data. They are inserted directly into ICS property lines without RFC 5545 escaping or rejection of carriage-return and line-feed characters.

Although the script applies escape_ics_text() to the event summary and primary description, it does not apply equivalent protection to the alarm description or category values. An attacker can therefore include newline sequences in a company name or deal phase to terminate the current property and inject additional ICS properties or components.

Category values also require individual escaping because commas and semicolons have structural meaning in ICS content. Escaping only after joining would not be sufficient unless the serializer correctly distinguishes separators from data.

Attack Path

  1. An attacker supplies crafted CRM data containing carriage-return or line-feed characters in the company name or deal phase.
  2. The Agent passes the value to the script through --firma or --deal-phase.
  3. The script inserts the value directly into DESCRIPTION or CATEGORIES.
  4. The injected newline terminates the intended ICS property.
  5. Attacker-controlled text following the ...[truncated 1066 chars]
Remediation
View remediation

Remediation Suggestions

  • Reject \r and \n in every field intended to occupy a single ICS property line.
  • Apply RFC 5545-compliant escaping to all dynamic property values, including alarm descriptions and category entries.
  • Escape each category value independently before joining the values with the structural category separator.
  • Update escape_ics_text() to handle carriage returns explicitly and normalize accepted line endings before serialization.
  • Prefer a maintained ICS serialization library that handles property escaping, value encoding, and line folding.
  • Add regression tests using CRLF and LF payloads in every user-controlled field.
  • Test structural characters such as commas, semicolons, backslashes, and Unicode input.
  • Parse generated files with a standards-compliant ICS parser during testing to verify that user input cannot create additional properties or components.

T09 · Insecure Skill Coding Practices

Note
Location
scripts/generate_ics.py:207
Finding

Unrestricted Output Path Allows Overwriting Arbitrary Writable Files

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_ics.py, lines 207-218
Vulnerability Type: Unrestricted file write and overwrite
Risk Level: Low

Vulnerable Code

python
# Determine output filename if only directory given
output_path = Path(args.output)
if output_path.is_dir():
    filename = f'{args.datum}_{sanitize_filename(args.firma)}_Reminder.ics'
    output_path = output_path / filename
elif not output_path.suffix:
    filename = f'{args.datum}_{sanitize_filename(args.firma)}_Reminder.ics'
    output_path = output_path / filename

# Write file
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(ics_content, encoding='utf-8')

Technical Analysis

The required --output argument is converted directly into a filesystem path. The script does not restrict that path to the user's workspace, require an .ics extension, reject traversal or absolute paths, or check whether an existing file will be replaced.

mkdir(parents=True, exist_ok=True) creates missing parent directories, while write_text() truncates and overwrites an existing destination by default. If a supplied path has a suffix, the script uses it directly regardless of whether that suffix is .ics.

The issue is constrained by the operating-system permissions of the process. It does not bypass filesystem access controls, but it can modify any destination already writable by the Agent process.

Attack Path

  1. An attacker causes or persuades the Agent to use a crafted --output value, such as an absolute path or a traversal path outside the intended workspace.
  2. The script accepts the path without canonicalizing it against an approved output directory.
  3. Missing parent directories are created where permissions allow.
  4. If the destination exists and is writable, write_text() truncates it and replaces its contents with generated ICS data.
  5. The target file is corrupted or des ...[truncated 616 chars]
Remediation
View remediation

Remediation Suggestions

  • Define a trusted workspace or output directory and resolve all requested paths against that directory.
  • Use Path.resolve() and verify that the resolved destination remains beneath the approved directory.
  • Reject absolute paths and traversal paths when callers are only expected to provide a filename.
  • Require the final destination to use an .ics extension.
  • Refuse to overwrite existing files by default, for example by using exclusive creation mode.
  • If overwriting is required, expose it through an explicit authorization flag and clearly report the affected path.
  • Consider accepting only an output directory and generating the final filename internally from sanitized data.
  • Where supported, protect against symbolic-link redirection by validating the destination and using safe file-opening semantics.
  • Run the Skill with least-privilege filesystem access so that only its designated workspace is writable.
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (4)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill instructs the agent to generate and save files in the user's workspace, but it does not declare any explicit tool scope or permissions boundary for that file-writing capability. This weakens least-privilege controls and can enable unintended file creation or overwrite behavior if the skill is invoked in broader agent contexts.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill explicitly stores CRM/contact data such as names, phone numbers, email addresses, budget, and deal status into an ICS file in the user's workspace, but it gives no warning that this creates a local file containing potentially sensitive business and personal data. Users may then import or share the file without understanding the privacy, retention, and exposure risks across calendar clients and synced accounts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The file presents the skill as generally compatible with Apple Calendar, Google Calendar, and Outlook, but the embedded CRM template and command examples are largely German-specific. Because no user opt-in or locale justification is provided, this appears to impose a language/locale choice in the generated content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The file’s natural-language interface and generated content are explicitly German-specific, including labels, help text, and output strings, but there is no indication that users can opt into another language or that the skill is intentionally limited to a German-region workflow. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.