Back to skill

Security audit

Campus Morning Brief / 校园晨报

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent student morning-brief generator with expected local rendering and no evidence of hidden execution, exfiltration, or destructive behavior.

Install only if you are comfortable with an agent researching live weather/news and saving a local brief. Use minimal student profile data, avoid sensitive schedules, health details, identifiers, or contact information, and review generated Markdown links and metadata before sharing or printing.

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/render_brief.py:156
Finding

Unescaped User-Controlled Content Allows Markdown Injection

Content
View full analysis
str: lines: list[str] = [] for item in items: label = f" · {item['category']}" if item.get("category") else "" lines.append( f"- **[{item['title']}]({item['url']})**{label} — {item['summary']} " f"({item['publisher']},{item['published_date']})" ) return "\n".join(lines) def render_markdown(payload: dict[str, Any]) -> str: profile = payload["profile"] weather = payload["weather"] reminder_block = "" if payload["reminders"]: reminder_block = "\n## 今日提醒\n\n" + "\n".join(f"- {item}" for item in payload["reminders"]) + "\n" return f"""# {profile['display_name']}的校园晨报 {payload['date']} · {profile['city']} ## 今日天气 **{weather_line(payload)}** - 穿衣:{weather['outfit']} - 校园提示:{weather['campus_tip']} ## 今日一句 > {payload['quote']['primary']}
> {payload['quote']['english']}
> — {payload['quote']['author']} ## 综合要闻 {news_markdown(payload['general_news'])} ## 兴趣拓展 {news_markdown(payload['interest_news'])} ## 学习方法 {payload['study_tip']} {reminder_block} ## 现在就做 **{payload['action_anchor']}** """ ``` ### Technical Analysis The validator only requires these fields to be non-empty strings. It does not escape or reject Markdown metacharacters, embedded HTML, line breaks, or control characters before the values are inserted into the generated Markdown document. Attacker-controlled titles can terminate the existing link syntax and introduce additional links or formatting. Summaries, profile fields, reminders, study tips, quotes, weather advice, and action prompts are inserted directly and can introduce arbitrary Markdown or raw HTML. The URL validator restricts schemes to HTTP or HTTPS but does not make the URL s ...[truncated 1461 chars]
Remediation
View remediation
# Forged Trusted Section [Urgent school notice](https://attacker.example) ``` 7. Verify generated documents in the actual Markdown viewers supported by the project, with raw HTML disabled where possible. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
scripts/render_brief.py:92
Finding

Unknown Profile Fields Are Persisted in Generated Metadata

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared description suggests a skill that creates a complete morning brief, including obtaining local weather and verified current news and producing a personalized, age-appropriate digest. The code shown only accepts an existing JSON brief, validates schema fields, and renders outputs as Markdown and HTML with metadata. It uses only the standard library and performs no network access, no content generation, no fact verification, no news/weather lookup, and no user-intent handling. While the output format aligns with a campus morning brief and includes weather/news/quote/study/reminder/action sections, the primary behavior is substantially narrower: rendering pre-supplied content rather than creating the brief described.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The promotion copy explicitly markets personalized student briefs using city, age group, interests, and reminders, which are personal data elements and may involve minors. Presenting these capabilities without any privacy, consent, retention, or parental/administrator handling guidance can encourage unsafe deployments, oversharing, or noncompliant data collection in education contexts.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The description says to use the skill when a user asks for 'school morning brief' or 'printable student daily digest,' alongside broader category language about briefs for children, teens, classes, and families. Those triggers are not tightly scoped to a specific command surface or negative examples, so they could match general everyday requests and cause unintended invocation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This manifest-style JSON schema includes a bilingual title at L03 and requires a profile.language field at L10-L15, but it does not document that language selection is optional or user-driven. Because SQP-3 applies to all file types, this can be read as enforcing a specific language/locale pattern without explicit opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file sets "language": "zh-CN" as a fixed value. Per the policy, forcing a specific language or locale without offering user choice or clearly documenting a justified region-specific requirement is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
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.

Content

Scanner excerpt · references/content-guidelines.md (reported line 16)May include surrounding context.

md
## Age calibration / 年龄适配

- `primary-school`: Use short sentences, explain uncommon terms, and avoid distressing events unless directly relevant to safety. / 使用短句并解释生词;除非与安全直接相关,否则避免令人不安的事件。
- `middle-school`: Add concise context and explain relevance without simplistic moral conclusions. / 补充简明背景及相关性,避免简单化的道德结论。
- `high-school`: Allow more policy, science, and economic context while defining specialist terms. / 可增加政策、科学和经济背景,同时解释专业术语。
- `college`: Use an adult reading level while retaining the short morning format. / 采用成人阅读水平,但保持晨报简洁。

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The guideline requires output in the configured profile language without mentioning user choice, override, or consent. In a student-facing skill that may process profile attributes for personalization, this can cause unnecessary use of a potentially sensitive preference and produce content in a language the current user did not explicitly request, which is a privacy and autonomy issue rather than a direct exploit.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script renders fixed Chinese UI text such as headings, labels, and action prompts throughout both Markdown and HTML output, even though the input schema only captures a language value and does not offer a choice of localized templates. This creates a natural-language locale policy issue because the skill effectively forces a specific language for rendered content rather than offering user opt-in or documenting a region-specific constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This markdown file includes a natural-language requirement that reader-facing documentation must remain bilingual. Under the policy rules, forcing a specific language or locale without explicit opt-in can be a language-policy violation unless it is clearly justified as region-specific; the line states the requirement but does not provide that justification.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

This is a manifest-style JSON file, so vague or underspecified configuration values can matter. The language is hard-coded to a specific locale with no accompanying constraints, alternatives, or negative examples, making the intended scope of this locale setting unclear.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The manifest describes creating a concise personalized morning brief, which is consistent with rendering content, but this script also creates an output directory and writes Markdown, HTML, and metadata files to disk. That is a broader operational behavior than simple content generation, though still related to a printable digest use case.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest focuses on generating a morning brief with weather, news, quote, study guidance, reminders, and an action prompt. The script additionally stores structured metadata including the user's profile and article source list in metadata.json, which is an extra retention behavior not described in the manifest.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This JSON sets the profile language to "zh-CN" directly, and the surrounding content is also presented in Chinese. Under the policy, forcing a specific language or locale without explicit user choice or documented justification is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
tests/test_render_brief.py:14