T09 · Insecure Skill Coding Practices
- 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: MediumVulnerable 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
firmaanddeal_phasecommand-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
- An attacker supplies crafted CRM data containing carriage-return or line-feed characters in the company name or deal phase.
- The Agent passes the value to the script through
--firmaor--deal-phase. - The script inserts the value directly into
DESCRIPTIONorCATEGORIES. - The injected newline terminates the intended ICS property.
- Attacker-controlled text following the ...[truncated 1066 chars]
- Remediation
View remediation
Remediation Suggestions
- Reject
\rand\nin 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.
- Reject
