Back to skill

Security audit

Intent Engine

Security checks for vulnerabilities and agentic risk

Overview

This skill appears to be a real intent-classification dashboard, but it exposes powerful management and debug functionality too broadly if run as documented.

Review before installing. Only run this bound to localhost or behind authentication, disable Flask debug mode, restrict access to the management APIs, sanitize dashboard rendering, limit or validate regex patterns, and pin reviewed dependencies before using it on any shared or network-reachable machine.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
run.py:4
Finding

Flask Debug Server Exposed on All Network Interfaces

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
intent_classifier/api.py:68
Finding

Unauthenticated Intent Configuration Management

Content
View full analysis
", methods=["GET"]) def get_intent(intent_id): intent = store.get(intent_id) if not intent: return jsonify({"error": "Intent not found"}), 404 return jsonify({"intent": intent.to_dict()}) @app.route("/api/intents/", methods=["PUT"]) def update_intent(intent_id): data = request.get_json(silent=True) or {} intent = store.update(intent_id, data) if not intent: return jsonify({"error": "Intent not found"}), 404 return jsonify({"intent": intent.to_dict()}) @app.route("/api/intents/", methods=["DELETE"]) def delete_intent(intent_id): if store.delete(intent_id): return jsonify({"ok": True}) return jsonify({"error": "Intent not found"}), 404 ``` ### Technical Analysis All administrative intent-management routes are accessible without authentication or an authorization decision. The POST, PUT, and DELETE handlers directly pass attacker-controlled data to persistent storage. Because the application is configured to listen on every network interface, thi ...[truncated 1721 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
static/index.html:398
Finding

Stored DOM Cross-Site Scripting in the Management Dashboard

Content
View full analysis
` ${i.icon} ${i.name}
${i.description||''} ${i.category} ${i.sub_category}
${(i.keywords||[]).slice(0,3).map(k => { const v = typeof k==='string' ? k : k.value; return `${v}`; }).join('')} ${(i.keywords||[]).length > 3 ? `+${i.keywords.length-3}` : ''}
${i.route_skill || '-'} ${i.priority} ${i.enabled?'启用':'禁用'}
编辑 ${i.enabled?'禁用':'启用'} 删除
`).join('') || '暂无意图数据'; ``` Classification results are also rendered without output encoding: ```javascript function singleResultHTML(r) { const pct = (r.confidence*100).toFixed(1); const hue = pct > 70 ? 150 : pct > 40 ? 45 : 0; return `
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
intent_classifier/engine.py:94
Finding

User-Controlled Regular Expressions Permit Denial of Service

Content
View full analysis
Intent: now = datetime.now().isoformat() intent_id = data.get("id") or str(uuid.uuid4())[:8] intent = Intent( id=intent_id, name=data["name"], description=data.get("description", ""), category=data["category"], sub_category=data["sub_category"], icon=data.get("icon", "?"), keywords=data.get("keywords", []), patterns=data.get("patterns", []), route_skill=data.get("route_skill", ""), route_description=data.get("route_description", ""), priority=data.get("priority", 0), enabled=data.get("enabled", True), created_at=now, updated_at=now, ) self._intents[intent.id] = intent self._save() return intent def update(self, intent_id: str, data: dict) -> Optional[Intent]: intent = self._intents.get(intent_id) if not intent: return None for field in ["name", "description", "category", "sub_category", "icon", "keywords", "patterns", "route_skill", "route_description", "priority", "enabled"]: if field in data: setattr(intent, field, data[field]) intent.updated_at = datetime.now().isoformat() self._save() return intent ``` ### Technical Analysis ...[truncated 2014 chars]
Remediation
View remediation
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill describes capabilities that imply local file read/write through JSON persistence, import/export, and generated data files, but it does not declare any explicit tool scope or permissions. This creates an authorization ambiguity where an agent or operator may enable broader filesystem access than users expect, increasing the risk of unintended file access or modification.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The activation phrases '识别意图 / 分类任务 / 智能路由' are broad, generic user intents that can easily appear in normal conversation. Overbroad triggers can cause the skill to activate unexpectedly and take over routing or classification flows, which is especially sensitive here because the skill influences downstream task selection and may expose management functionality.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The /api/categories response returns user-facing labels only in Chinese (代码类, 知识类, 任务类, 闲聊类). This imposes a specific language on all consumers of the skill without opt-in or indication that the skill is intentionally limited to a Chinese-speaking context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code persists intent data to a JSON file and is invoked from create, update, and delete flows, but there is no confirmation prompt, user-facing log, or explicit warning that local data will be modified. Because these operations affect stored user/system state, the lack of disclosure makes the side effects non-obvious to users.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The built-in intent names, descriptions, keywords, and regex patterns are predominantly Chinese, which biases routing toward a specific language/locale. In the absence of any visible opt-in, language choice, or justification in this file, this appears to impose a locale preference that may not match user expectations or organizational language policy.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The delete method removes an intent from memory and immediately saves the updated JSON file, making the operation persistent and potentially irreversible from the user's perspective. There is no confirmation step, warning, or user-visible notice around this destructive action.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The document declares lang="zh-CN", and the visible interface text throughout the page is Chinese, but there is no indication that users can opt into another language or that the tool is intentionally region-specific. This can violate organizational language/locale policy when a skill mandates a specific locale by default.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The docstring at L171 says this method will classify multiple texts at once, which implies one classification per item. However, the list comprehension calls self.classify(t) in both the condition and the true branch at L175-L176, causing duplicate classification work for each non-empty text.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

This code file contains natural-language comments in Chinese (e.g. the weight label) without any indication that the skill is intentionally locale-specific or that users can choose their preferred language. The policy explicitly calls for flagging language or locale constraints when they are imposed without user opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

Several field comments describing categories and routing semantics are written only in Chinese, which introduces a language-specific assumption in the skill artifact. Because no opt-in, multilingual alternative, or documented regional justification appears in this file, this matches the natural-language policy violation category.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The comments for confidence and matched fields include Chinese-only natural-language descriptions, indicating the file assumes a specific language context. Under the policy, language-specific instructions or descriptions should not be forced without opt-in or clear justification.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified as flask>=3.0.0, which allows any future Flask release to be installed without review. This creates a supply-chain and reproducibility risk because builds may unexpectedly pick up vulnerable or breaking versions over time.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
flask>=3.0.0

Unverifiable Dependency: flask has 10 known advisory(ies) (CVE-2025-47278 (Flask uses fallback key instead of current signing key); CVE-2018-1000656 (Flask is vulnerable to Denial of Service via incorrect encoding of JSON data); CVE-2019-1010083 (Pallets Project Flask is vulnerable to Denial of Service via Unexpected memory u) +7 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
89% confidence
Finding

Because the manifest does not pin Flask to a specific version, it is impossible to verify whether the installed package is affected by known advisories. In practice, this means deployments may resolve to a vulnerable release or change over time, undermining assurance about the package's security state.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.