Back to skill

Security audit

Manage quark-auto-save(QAS, 夸克自动转存, 夸克转存, 夸克订阅) tasks via CLI.

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent Quark Auto Save manager, but it handles tokens and cloud-storage mutations with enough under-scoped, persistent, and irreversible behavior that users should review it carefully before installing.

Install only if you trust the configured QAS server and are comfortable giving the agent authority to add, run, update, and delete QAS tasks and cloud files. Use HTTPS where possible, avoid putting real cookies or tokens into persistent notes, and require manual confirmation before delete-file, delete-task, update-config, or broad run-task actions.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/qas_client.py:64
Finding

API Token Exposed in URL Query Strings and Potentially Transmitted over Plaintext HTTP

Content
View full analysis
dict: """GET request to QAS API""" url = f"{QAS_BASE_URL}{endpoint}" params = params or {} params["token"] = QAS_TOKEN query = urllib.parse.urlencode(params) full_url = f"{url}?{query}" if params else url try: resp = urllib.request.urlopen(full_url, timeout=30) return json.loads(resp.read().decode("utf-8")) except urllib.error.HTTPError as e: return {"success": False, "message": f"HTTP {e.code}: {e.reason}"} except Exception as e: return {"success": False, "message": str(e)} def post(endpoint: str, data: dict = {}, raw: bool = False) -> dict: """POST request to QAS API - token must be in query param, not body""" url = f"{QAS_BASE_URL}{endpoint}" data = data or {} # Token goes in query param, NOT in body (server ignores token in body) query = f"token={QAS_TOKEN}" full_url = f"{url}?{query}" json_data = json.dumps(data).encode("utf-8") req = urllib.request.Request( full_url, data=json_data, headers={"Content-Type": "application/json"} ) try: resp = urllib.request.urlopen(req, timeout=30) ``` The documentation also explicitly permits an HTTP endpoint: ```markdown - `QAS_BASE_URL` - User provided, e.g., http://192.168.1.x:5005 ``` ### Technical Analysis Every GET and POST request appends `QAS_TOKEN` to the request URL. URLs are routinely retained in reverse-proxy access logs, web server logs, monitoring systems, browser or intermediary diagnostics, and error telemetry. Anyone who can read those records may recover the credential. The client does not validate the scheme, host, or trustworthiness of `QAS_BASE_URL`. Because `SKILL.md` gives a plaintext HTTP UR ...[truncated 1640 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/qas_client.py:52
Finding

Implicit JSON-or-File Parsing Enables Unrestricted Local JSON File Reads and Transmission

Content
View full analysis
dict: """Parse JSON from string or file path""" try: return json.loads(arg) except json.JSONDecodeError: with open(arg, "r", encoding="utf-8") as f: return json.load(f) ``` This function is used by operations that subsequently send parsed data to the configured QAS endpoint, including `add-task`, `update-config`, and `update-task`. ### Technical Analysis The function first attempts to parse an argument as inline JSON. If parsing fails for any reason represented by `JSONDecodeError`, it automatically interprets the same untrusted string as a local filesystem path. There is no explicit `--file` option, approved-directory restriction, canonical-path validation, symlink check, or user confirmation. Consequently, an invocation influenced by untrusted content can cause the process to open any readable JSON file. The resulting object is then used as a request body in configuration or task-management API calls. This creates a local data disclosure primitive. The exploit is limited to files that are readable by the account running the Skill and that contain valid JSON, but such files commonly include application configuration, API credentials, deployment metadata, or service-account material. ### Attack Path 1. An attacker supplies prompt content or operational instructions that influence the agent to run a command such as: ```bash python3 scripts/qas_client.py update-config /path/to/sensitive-config.json ``` 2. The argument is not valid inline JSON, causing `json.loads()` to raise `JSONDecodeError`. 3. `parse_json_arg()` treats the argument as a path and opens the file with the agent's local filesystem privileges. 4. The file is parsed as JSON. 5. The ...[truncated 821 chars]
Remediation
View remediation
dict: return json.loads(arg) ``` 2. If file-based input is necessary, require a distinct and explicit `--file` option rather than falling back automatically. 3. Restrict file input to a dedicated approved directory and compare canonical paths using `os.path.realpath()` or `pathlib.Path.resolve()`. 4. Reject symlinks and non-regular files where practical. 5. Require explicit user confirmation before transmitting data loaded from a local file. 6. Apply strict schemas and allowed-field lists to each operation so unrelated secrets cannot be forwarded as task or configuration properties. 7. Avoid catching `JSONDecodeError` as an implicit signal that the input should be interpreted as a path; instead, return a clear validation error. ]]>

other

Warning
Location
SKILL.md:32
Finding

Mandatory Habit Analysis Retrieves and May Persist Excessive Sensitive Configuration

Content
View full analysis
Remediation
View remediation
Record only generalized directory and filename-format preferences. Never write tokens, cookies, share URLs, notification credentials, or raw configuration values to TOOLS.md. 4. Redact sensitive keys recursively before displaying API responses. 5. Request explicit user consent before persisting even non-secret preference summaries. 6. Minimize retention by storing generalized patterns rather than exact private paths or task inventories. 7. Apply restrictive filesystem permissions to persistent workspace files that contain user preferences. ]]>
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (7)

Tainted flow: 'full_url' from os.environ.get (line 87, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/qas_client.py (reported line 73)May include surrounding context.

python
query = urllib.parse.urlencode(params)
    full_url = f"{url}?{query}" if params else url
    try:
        resp = urllib.request.urlopen(full_url, timeout=30)
        return json.loads(resp.read().decode("utf-8"))
    except urllib.error.HTTPError as e:
        return {"success": False, "message": f"HTTP {e.code}: {e.reason}"}

Tainted flow: 'req' from os.environ.get (line 89, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/qas_client.py (reported line 93)May include surrounding context.

python
full_url, data=json_data, headers={"Content-Type": "application/json"}
    )
    try:
        resp = urllib.request.urlopen(req, timeout=30)
        content = resp.read().decode("utf-8")
        # Some endpoints return raw text (SSE) instead of JSON
        if raw:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill exposes capabilities that can access environment variables, read local files, and make network requests, but it does not declare any explicit tool scope or allowed-tools boundary. In practice, this weakens containment and increases the chance the agent will invoke sensitive operations or handle secrets such as QAS_TOKEN without clear policy constraints.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger condition says that when a user sends a Quark share link, the skill should fetch details and add a task, which is broad enough to auto-activate on arbitrary matching links. That can cause unintended execution and state-changing actions from casual messages, especially because the workflow leads quickly to network access and task creation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill documents destructive operations such as delete-file, delete-task, update-task, and update-config without prominent warnings, confirmation requirements, or guardrails around their effects. In an agent setting, this raises the risk of accidental data loss, unwanted task modification, or service misconfiguration if commands are issued from ambiguous prompts or misinterpreted intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The delete-task command mutates remote task state without any confirmation, preview, or safeguard against accidental invocation. In a skill designed to manage automation tasks, deleting the wrong task could disable scheduled operations or remove important configuration with little user awareness.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The delete-file command performs irreversible remote deletion immediately with no confirmation prompt, dry-run mode, or explicit warning. In an agent or automation context, malformed input, prompt-induced misuse, or operator error could cause unintended loss of cloud data at scale.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.