Back to skill

Security audit

SJTU Canvas 课程助手

Security checks for vulnerabilities and agentic risk

Overview

This Canvas course helper is purpose-aligned, but it needs Review because unsafe handling of Canvas data could expose the API token, overwrite local files, or run AppleScript locally.

Review before installing. Use a limited-scope Canvas token if possible, avoid committing config.json, run the skill in a dedicated environment, and be cautious with calendar sync and bulk downloads until URL validation, filename containment, AppleScript escaping, and confirmation/preview controls are fixed.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/calendar_sync.py:36
Finding

AppleScript Injection Through Unescaped Calendar and LMS Data

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/canvas_api.py:48
Finding

Canvas Bearer Token Disclosure Through Unvalidated Response URLs

Content
View full analysis
")[0] params = None return items ``` The same credential-forwarding behavior occurs for file URLs: ```python def download_file(file_url, save_path): r = requests.get(file_url, headers=headers(), stream=True) r.raise_for_status() os.makedirs(os.path.dirname(save_path), exist_ok=True) with open(save_path, "wb") as f: for chunk in r.iter_content(chunk_size=8192): f.write(chunk) return save_path ``` The authorization header contains the configured API token: ```python def headers(): return {"Authorization": f"Bearer {get_token()}"} ``` ### Technical Analysis The first API request is built from the configured Canvas base URL, but subsequent pagination URLs are extracted from the remote `Link` header and used without validating their origin. Every request receives the `Authorization: Bearer ...` header. Likewise, `download_file()` accepts a URL returned in Canvas file metadata and attaches the bearer token regardless of the URL's host, scheme, or port. HTTP clients do not protect a caller from explicitly sending an authorization header to a different origin. Therefore, if the LMS response supplies an attacker-controlled absolute URL, ...[truncated 1523 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/canvas_api.py:82
Finding

Arbitrary File Overwrite Through Canvas Filename Path Traversal

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:44
Finding

Unpinned Third-Party Dependency Installation

Content
View full analysis
Remediation
View remediation
\ --hash=sha256: ``` All transitive dependencies must also appear with exact versions and approved hashes. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The documented behavior materially exceeds or diverges from what is safely declared: it reads local configuration containing a Canvas token, interacts with remote Canvas endpoints, downloads files, and can submit assignments, yet these sensitive behaviors are not transparently bounded in the skill contract. This mismatch can mislead users and orchestrators about the real trust requirements, increasing the chance of unintended data access, remote actions, or credential exposure.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented behavior materially exceeds or diverges from what is safely declared: it reads local configuration containing a Canvas token, interacts with remote Canvas endpoints, downloads files, and can submit assignments, yet these sensitive behaviors are not transparently bounded in the skill contract. This mismatch can mislead users and orchestrators about the real trust requirements, increasing the chance of unintended data access, remote actions, or credential exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The README promotes Apple Calendar synchronization as a feature but does not clearly warn users that running the sync will create or modify calendar entries on their local/iCloud-backed calendar. In an agent-skill context, actions that change external state should be explicitly disclosed because users may trigger them through natural-language requests without realizing the side effect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README instructs users to place a Canvas API token directly into config.json but does not warn that this token is a sensitive credential that grants API access to coursework, grades, submissions, and other account data. Storing secrets in a plaintext file inside a cloned skill directory increases the risk of accidental disclosure through backups, file sharing, screenshots, or source control mistakes.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill documentation describes capabilities that require shell execution, network access, and local file read/write, but it does not declare any tool scope or permission boundaries. In an agent environment, this omission can cause over-privileged or ambiguous execution, making it easier for the skill to access tokens, user files, download remote content, or submit assignments without explicit policy gating.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger keywords include very broad academic terms like '课程', '作业', '成绩', 'PPT', '总结', 'course', and 'assignment', which are likely to appear in many normal conversations. Over-broad triggers can invoke a high-privilege skill unexpectedly, exposing local files, tokens, or causing remote actions such as downloads or assignment submission in contexts where the user did not intend to use this skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The code forces Asia/Shanghai time via TZ_SHANGHAI and presents user-visible messages/calendar names only in Chinese, with no opt-in or configuration for language/locale behavior. Under the policy, forcing a specific language or locale without user choice is a natural-language policy violation unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/calendar_sync.py (reported line 31)May include surrounding context.

python
end if
end tell
'''
    r = subprocess.run(["osascript", "-e", script], capture_output=True, text=True, timeout=30)
    return r.returncode == 0

def create_event(summary, due_dt, description=""):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/calendar_sync.py (reported line 75)May include surrounding context.

python
end if
end tell
'''
    r = subprocess.run(["osascript", "-e", script], capture_output=True, text=True, timeout=30)
    return r.returncode == 0

def create_event(summary, due_dt, description=""):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
89% confidence
Finding

The code constructs AppleScript by directly interpolating untrusted summary and description values into a quoted script string, then executes it via osascript. If course or assignment data from Canvas contains quotes or AppleScript syntax, an attacker-controlled course item could break out of the string literal and inject unintended AppleScript actions on the local machine.

Content

Scanner excerpt · scripts/calendar_sync.py (reported line 59)May include surrounding context.

python
end tell
end tell
'''
    r = subprocess.run(["osascript", "-e", script], capture_output=True, text=True, timeout=30)
    return r.returncode == 0

def list_existing_events():

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/calendar_sync.py (reported line 83)May include surrounding context.

python
def sync_ddls(ddls):
    """同步 DDL 列表到 Apple Calendar(跳过已存在的)"""
    # 启动日历
    subprocess.run(["open", "-a", "Calendar"], capture_output=True)
    import time; time.sleep(2)
    
    ensure_calendar()

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script modifies a user's Apple Calendar by creating events automatically, with no confirmation, dry run, or preview of what will be added. In this skill context, data originates from external course content, so malformed or malicious assignment names could lead to unwanted calendar changes at scale and reduce trust in the agent.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The docstring says the function uploads files and submits an assignment, but the code builds request URLs using expressions like get_base_url()/api/v1/..., which is invalid Python/string construction and will not perform the documented Canvas API calls. This is an active divergence between the documented intent and the implemented behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code performs a state-changing action: it uploads local files and submits an assignment using the user's bearer token, but contains no built-in confirmation, dry-run mode, or guardrails in the submission function itself. In an agent setting, that makes accidental or unauthorized submission easier if higher-level orchestration invokes it based on ambiguous prompts, potentially sending the wrong files or submitting before the user intends.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file's primary description string is in Chinese, and the script also uses Chinese-only user-facing messages elsewhere, indicating the skill is designed around a fixed language. This can violate language/locale policy because it does not offer user opt-in or document that the tool is intentionally region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Returned strings such as installation guidance, unsupported-file errors, and extraction-failure messages are presented only in Chinese. Because these are user-visible outputs in a code file, they enforce a locale choice without giving the user an alternative or explaining a justified regional restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The config uses Chinese-only default values for save_dir and calendar_name (Canvas课件, Canvas作业). This can impose a specific language/locale on users without opt-in, which matches the natural-language policy violation criteria for forced language settings.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The module docstring and multiple user-facing strings are written only in Chinese, which indicates a fixed language choice in the skill's natural-language interface. There is no visible opt-in, language selection, or documentation in this file that the skill is intentionally restricted to a Chinese-speaking audience.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The manifest describes the skill as managing Canvas course data and mentions syncing DDLs to Apple Calendar, but this module directly exposes Canvas calendar event listing as a first-class API operation. That capability is adjacent to the stated purpose, yet it is broader than the module's own documented scope of courses/files/assignments/grades/discussions and not clearly required for the claimed core Canvas data management behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.