Back to skill

Security audit

Elderly AI Assistant

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate Chinese-language senior assistant, but it needs review because it overstates reminder/contact capabilities, requests broad tools, and generates unsafe HTML from user input.

Review before installing. Do not rely on this skill for medication, appointment, emergency, or caregiver-contact reminders unless those functions are implemented and tested separately. Avoid opening generated HTML based on untrusted input until escaping/CSP protections are added, and limit shell/file permissions if your environment supports narrower tool grants.

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 (1)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/elderly_assistant.py:508
Finding

Unescaped User Input Enables Script Injection in Generated HTML

Content
View full analysis

Vulnerability Details

File Location: scripts/elderly_assistant.py, lines 508, 845, and 870–872; related command-line input sources at lines 924 and 942
Vulnerability Type: HTML injection and cross-site scripting in generated reports
Risk Level: High

Vulnerable Code

The dashboard inserts the user-supplied name directly into an HTML document:

python
<div style="text-align:center;font-size:24px;margin:16px 0;">
  👋 {user_name},今天有什么我能帮您的?
</div>

The health report inserts the supplied health concern without HTML escaping:

python
<div class="card">
  <p><strong>您提到:</strong>{concern}</p>
</div>

Medication fields are likewise inserted directly into table cells:

python
for i, med in enumerate(medications, 1):
    rows += f'''
    <tr>
      <td style="padding:12px;border-bottom:1px solid #ddd;">{i}</td>
      <td style="padding:12px;border-bottom:1px solid #ddd;font-weight:bold;">{med.get('name', '')}</td>
      <td style="padding:12px;border-bottom:1px solid #ddd;">{med.get('dosage', '')}</td>
      <td style="padding:12px;border-bottom:1px solid #ddd;color:#ff6b35;font-weight:bold;">{med.get('time', '')}</td>
    </tr>'''

Two affected values can be supplied directly through command-line arguments:

python
name = sys.argv[2] if len(sys.argv) > 2 else "叔叔/阿姨"
python
concern = sys.argv[2] if len(sys.argv) > 2 else ""

Technical Analysis

The HTML generation functions use Python formatted strings to concatenate untrusted values into HTML text contexts. No encoding, sanitization, validation, or restrictive Content Security Policy is applied.

An input containing active markup, such as:

html
<img src=x onerror="alert(document.domain)">

is retained as an HTML element rather than displayed as plain text. When the generated report is saved and presented in an HTML-capable browser or viewer, the event handler can execute JavaScript.

The affected entry points and sinks are:

  1. user_name passed t ...[truncated 2479 chars]
Remediation
View remediation

Remediation Suggestions

  1. Escape every untrusted value before inserting it into HTML:

    python
    from html import escape
    
    safe_user_name = escape(str(user_name), quote=True)
    safe_concern = escape(str(concern), quote=True)
    safe_name = escape(str(med.get("name", "")), quote=True)
    safe_dosage = escape(str(med.get("dosage", "")), quote=True)
    safe_time = escape(str(med.get("time", "")), quote=True)
    
  2. Use only the escaped variables in generated markup.

  3. Prefer an established template engine with automatic HTML escaping enabled rather than constructing documents through formatted strings.

  4. Validate input types, lengths, and allowed characters. Medication schedule entries should be required to be dictionaries containing bounded text values.

  5. Add a restrictive Content Security Policy to generated pages, for example:

    html
    <meta http-equiv="Content-Security-Policy"
          content="default-src 'none'; style-src 'unsafe-inline'; img-src data:; script-src 'none';">
    

    The dashboard currently requires inline JavaScript, so it should instead move scripts into a trusted external resource with a hash or nonce-based policy. Report pages that need no JavaScript should use script-src 'none'.

  6. Add regression tests covering payloads with script tags, event-handler attributes, malformed elements, encoded markup, quotation marks, and closing tags. Tests should verify that these values appear as text and never become DOM elements.

  7. Treat all values returned by an AI model, read from user files, or supplied by command-line arguments as untrusted, even when the expected content is a name, symptom, dosage, or time.

Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (14)

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The README states that the assistant is designed specifically for Chinese elderly users ("中国老年用户"), which signals a fixed locale/audience constraint. Under the policy, locale-specific targeting should either offer user choice or clearly justify the restriction as region-specific; this README does not present it as an opt-in language/locale option.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The listed trigger phrases include broad terms like “关爱模式”, “长辈模式”, and “senior mode”, which can plausibly appear in unrelated conversations or accessibility requests. In an always-on or automatic skill-routing environment, this can cause accidental invocation of the elderly-focused skill, leading to misrouting of user intent and potentially inappropriate health, reminder, or family-contact guidance.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Several trigger phrases are broad consumer-facing expressions like '关爱模式', '老年模式', and '给爸妈用', which could match ordinary conversation and cause accidental invocation. Because the skill has file-writing and web-enabled capabilities, unintended activation increases the chance of unnecessary tool use, file creation, or privacy-relevant interactions with a potentially vulnerable elderly audience.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill requests Bash even though its documented purpose is an elderly lifestyle assistant that mainly provides reminders, conversation, and formatted HTML views. Unnecessary shell access expands the blast radius: if the skill is invoked unexpectedly or later extended unsafely, it could write files, run commands, or manipulate the local environment beyond what elderly-assistant features require.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The description states the skill is designed for Chinese elderly users, and later the interaction rules specify “普通话为主” as the language. This imposes a language/locale preference without indicating that users can choose another language or opt in to the constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The line explicitly requires “语言:普通话为主,支持方言关键词识别,” which sets a mandatory language preference. Because the skill does not offer a language choice or present this as an opt-in regional limitation, it conflicts with the language/locale policy criteria.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The memory template states '到时间会提醒您', but the code has no mechanism to save reminders or notify later. In a senior-care skill, false assurance about future reminders can cause missed medical appointments, medications, or other important events, increasing real-world harm.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The medication UI claims it can set reminders, but there is no reminder creation, scheduling, persistence, or delivery logic. For elderly users, misleading them into believing medication reminders are active can directly contribute to missed doses or dosing errors, making the context more safety-critical than a normal productivity app.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The UI promises family-contact actions such as helping the user call a son, but the code only pre-fills text and shows a toast; it does not actually place a call or clearly disclose that limitation. In an elderly-assistant context, this can create dangerous overreliance during urgent situations, causing delays in contacting real caregivers or emergency help.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code sets recognition.lang = 'zh-CN', forcing speech recognition to operate only in Simplified Chinese. This is a natural-language/locale policy issue because the skill does not offer a user language choice or explain that it is intentionally region-specific.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
71% confidence
Finding

Some network access may be understandable for weather, news, or drug information, but the manifest does not explicitly define external browsing as a capability boundary and instead presents a focused senior-care assistant. The inclusion of both WebFetch and WebSearch gives the skill broad internet access beyond the narrowly described interaction model.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The main dashboard HTML declares lang="zh-CN", and the skill content is authored entirely in Chinese, but there is no user-selectable language option or explicit scope statement in this file. This can violate language/locale policy when the skill is not clearly documented as Chinese-only.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

Both generate_health_report and generate_medication_schedule emit HTML with lang="zh-CN", continuing the same forced-locale behavior across outputs. Because no opt-in or documented regional limitation appears in this file, these outputs reinforce the locale policy concern.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.