Back to skill

Security audit

ontario-immigration-expert

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly an Ontario immigration scoring and monitoring helper, but it overstates its live and multi-stream capabilities and directs a persistent daily cron monitor without enough user control.

Review before installing. Use the scoring output only as a snapshot-based aid unless you independently verify current official OINP/RCIP/FCIP pages. Do not enable the daily cron monitor unless you want persistent background checks, understand the exact command being scheduled, and know how to remove it. Prefer installing a pinned reviewed release rather than cloning a mutable default branch.

Vulnerability Patterns
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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 (3)

T06 · System Persistence

Error
Location
SKILL.md:29
Finding

Persistent Daily Policy-Monitoring Task

Content
View full analysis
才推送(标题+摘要+URL)到主会话;NO_CHANGES 静默。 ``` The operative instructions direct the agent to use cron once per day at 09:00 in the `America/Toronto` time zone, run `scripts/policy_monitor.py`, and notify the main session when changes are detected. ### Technical Analysis The Skill declares access to the `cron` tool and instructs the agent to create recurring execution. A scheduled task survives the immediate Skill invocation and continues operating across sessions, which constitutes system persistence. The scheduled action is disclosed as a policy-monitoring feature and the audited script does not contain a malicious payload. Nevertheless, the persisted task creates a durable execution path. If the local script or Skill directory is modified later, the scheduled command may execute the modified code automatically without a new explicit user action. ### Attack Path 1. A user installs and loads the Skill. 2. The agent follows the instruction in `SKILL.md` and creates a daily cron task. 3. The cron task repeatedly invokes `scripts/policy_monitor.py`. 4. An attacker who later compromises or modifies the Skill directory replaces or alters the monitored script. 5. The next scheduled invocation runs the modified code automatically under the privileges of the account owning the cron task. ### Impact Assessment The immediate task performs outbound policy-page requests, writes monitoring state, and reports changes. Its privileges are limited to those of the user or agent environment that created the schedule. The persistence mechanism can, however, repeatedly execute future modifications to the scheduled script. This exte ...[truncated 161 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
README.md:27
Finding

Unpinned Installation from Mutable Remote Sources

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/policy_monitor.py:45
Finding

Fetch Failures Erase Existing Monitoring Baselines

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code chunk only implements source discovery: it fetches HTML from predefined Ontario, Canada, and Sudbury pages, regex-extracts links, filters them against allowlisted URL patterns, and stores newly discovered URLs in a local JSON file. While this is loosely supportive of a live-policy system, it is not itself an immigration policy expert and does not perform the core declared functions: no candidate input handling, no itemized score calculation, no stream-specific rules engine, no comparison against prior policy versions, and no surfaced updates beyond adding URLs. The accessed resources are consistent with the policy domain, but the actual behavior is much narrower and materially different from the declared primary purpose.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The description materially overstates the implemented functionality. The script is a standalone offline calculator for one OINP stream, using embedded scoring logic and a minimal eligibility gate. It does not access official sources, perform live policy validation, detect updates, or support RCIP/FCIP or broader multi-stream evaluation. While the itemized EOI scoring aspect partially matches, the primary claimed differentiators—generic policy expertise, real-time official-source retrieval, and update monitoring—are absent, making this a clear description/behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code only implements a narrow monitoring utility: it loads watched URLs from a JSON file, fetches their HTML, cleans text, computes hashes, compares against prior hashes, saves state, and prints whether changes were detected. This partially aligns with the declared 'detects and surfaces updates' aspect, but it does not implement the core declared functionality of being a generic Ontario immigration policy expert, making policy judgments, or computing multi-stream EOI scores with itemized detail and eligibility gates for candidates. The actual primary purpose is generic webpage change detection, not immigration policy analysis or scoring.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script explicitly states it is offline/local and reads only stdin, while the skill metadata promises real-time fetching from official sources and update detection. In an immigration-policy skill, stale or snapshot-based rules can directly mislead users about eligibility or scores, creating a serious integrity and safety problem even without code execution.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The README makes conflicting trust claims: it describes the skill as 'fully local, offline' and 'no network' while also advertising real-time official-source fetching and daily policy monitoring. In a security-sensitive agent ecosystem, misleading users about network behavior can cause them to run the skill under incorrect assumptions, weakening informed consent, review, and sandboxing decisions.

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.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill instructions and safety guidance are presented in Chinese, which effectively forces a specific language for users and downstream operators. Under the policy, language constraints should either be optional, user-selected, or explicitly justified as region-specific in a way that still addresses user choice.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The docstring documents reliance on a local snapshot and non-networked behavior, which conflicts with claims that all judgments follow live official sources. This mismatch increases the chance that users or downstream agents will trust outputs as current legal/policy guidance when they may be outdated, especially in a regulated immigration context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module description and user-facing output are written in Chinese, and there is no indication that users may choose another language or locale. This is a natural-language locale constraint that can violate organizational language-choice policy when not explicitly optional or justified as region-specific output formatting.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The phrase "Official bilingual rule (both official languages CLB 6+ = 10 points, one language = 5)" hard-codes a language-related rule in natural language. While this likely reflects program policy, the README does not explicitly frame the language constraint as a region-specific eligibility requirement in that line, which can read as an unconditional language policy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This JSON file contains user-facing natural-language fields such as name and note that include Chinese text alongside English. Because the file does not indicate that language selection is configurable or intentionally limited to Chinese-speaking users, it may violate a language/locale policy requiring user choice or explicit justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

This code performs a file write to data/sources.json, which changes repository state, but the write path itself has no user-facing prompt or inline warning near the operation. While the module docstring mentions that links will be collected into sources.json, there is no confirmation or explicit disclosure when the save actually occurs.

Content

No source excerpt is available for this finding.