Back to skill

Security audit

weeek-tasks

Security checks for vulnerabilities and agentic risk

Overview

This is a straightforward WEEEK task-management helper that uses a user-provided WEEEK token to read and modify WEEEK tasks, with no hidden persistence or unrelated access found.

Install only if you intend to let the agent use your WEEEK account token for task operations. Use the narrowest WEEEK token available, avoid exposing it in logs or shared shells, and confirm before asking the agent to create, update, complete, reopen, or move tasks because those commands affect live WEEEK data.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/weeek_api.py:21
Finding
Bearer Authorization Token May Be Forwarded Across Redirects## Vulnerability Details **File Location**: `scripts/weeek_api.py`, lines 21–30 **Vulnerability Type**: Unsafe handling of authenticated HTTP redirects **Risk Level**: Medium ```python def request(method, path, params=None, body=None): token = os.environ.get("WEEEK_TOKEN") if not token: raise SystemExit("WEEEK_TOKEN не задан в окружении") url = BASE_URL + path if params: query = urllib.parse.urlencode({k: v for k, v in params.items() if v is not None}, doseq=True) url = url + ("?" + query if query else "") data = None headers = { "Authorization": f"Bearer {token}", "Content-Type": "application/json", } if body is not None: data = json.dumps(body).encode("utf-8") req = urllib.request.Request(url, data=data, headers=headers, method=method) with urllib.request.urlopen(req) as resp: raw = resp.read().decode("utf-8") if not raw: return None try: return json.loads(raw) except json.JSONDecodeError: return raw ``` ### Technical Analysis Sending `WEEEK_TOKEN` to the fixed WEEEK HTTPS API is necessary for the Skill's declared task-management functionality. However, `urllib.request.urlopen()` follows supported HTTP redirects automatically, and the implementation neither disables redirects nor validates the final response origin. Because the bearer token is placed in the ordinary request headers, redirect processing may copy the `Authorization` header into a redirected request. If `api.weeek.net` returns a redirect to a different origin, the authenticated client may consequently disclose the token to that origin. The implementation also does not enforce an explicit HTTPS-only, same-host redirect policy. This is not evidence of intentional exfiltration: the original destination is the documented WEEEK API, and no attacker-controlled destination is e ...[truncated 1532 chars]
Remediation
## Remediation Suggestions 1. Disable automatic redirects for authenticated API requests unless redirects are explicitly required by the WEEEK API. 2. If redirects must be supported, implement a custom `urllib.request.HTTPRedirectHandler` that permits redirects only when: - The destination scheme is `https`. - The destination hostname is exactly `api.weeek.net`. - The destination port remains the expected HTTPS port. 3. Strip the `Authorization` header before following every cross-origin redirect, including redirects involving a hostname, scheme, or port change. 4. Validate the final response URL before processing its contents. 5. Add a finite network timeout to `urlopen()` to prevent indefinite blocking. 6. Add automated tests covering same-origin redirects, cross-origin redirects, HTTPS-to-HTTP redirects, and authorization-header removal. 7. Document that users should issue narrowly scoped API tokens where WEEEK supports token-level permission restrictions and should revoke a token immediately if unintended redirection is observed.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • 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 (12)

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

Critical
Category
Data Flow
Content
data = json.dumps(body).encode("utf-8")

    req = urllib.request.Request(url, data=data, headers=headers, method=method)
    with urllib.request.urlopen(req) as resp:
        raw = resp.read().decode("utf-8")
        if not raw:
            return None
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill clearly relies on environment variables and network access to call the WEEEK API, but it does not declare an explicit tool scope or permission boundary. In an agent setting, this can cause the skill to run with broader-than-expected capabilities, increasing the chance of unintended secret access or outbound requests beyond what users expect.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill tells users to place an authorization token in an environment variable but provides no guidance on secure handling, storage, rotation, or avoiding accidental disclosure. In agent environments, secrets may be echoed in logs, inherited by subprocesses, or exposed to unrelated tooling if not carefully constrained.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The documentation describes create, update, complete, uncomplete, and move operations against a live task-management API without clearly warning that these are state-changing actions. In an agent-driven workflow, that omission raises the risk of accidental modification of production task data, especially if a user expects read-only behavior.

External Transmission

Medium
Category
Data Exfiltration
Content
import urllib.parse
import urllib.request

BASE_URL = "https://api.weeek.net/public/v1"


def request(method, path, params=None, body=None):
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
import urllib.parse
import urllib.request

BASE_URL = "https://api.weeek.net/public/v1"


def request(method, path, params=None, body=None):
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The script exposes state-changing operations such as create, update, complete, and move without any confirmation, dry-run mode, or user-facing warning. In an agent/tooling context, this increases the chance of unintended task modifications from ambiguous prompts, automation mistakes, or misuse of the skill.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The entire API reference is written in Russian, including the title and endpoint descriptions, with no indication that the skill is intentionally region-specific or that another language option is available. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy concern.

Missing User Warnings

Low
Confidence
86% confidence
Finding
The request helper accesses the WEEEK_TOKEN environment variable to authenticate outbound API calls, but the file contains no comment, docstring, or user-facing message explaining that a credential from the environment will be used for network requests. This matches the code-file criterion for sensitive environment variable access lacking disclosure.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The script emits a Russian-only error message when WEEEK_TOKEN is missing, which imposes a specific language on users without offering a language choice or documenting that the tool is intentionally locale-specific. That is a natural-language locale policy issue under the stated rule.

Description-Behavior Mismatch

Low
Confidence
91% confidence
Finding
The manifest description says the skill manages tasks and can list boards and columns, but it does not mention projects. The code adds a `list-projects` command that retrieves `/tm/projects`, expanding the described behavior beyond the stated task/board/column scope.

Static analysis

No suspicious patterns detected.