Back to skill

Security audit

alibabacloud-live-assistant

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly performs declared Alibaba Cloud Live diagnostics, but it has under-disclosed external lookups and some network-probing/log-download behaviors that need review before use.

Review this skill before installing in sensitive environments. Use least-privilege Alibaba Cloud RAM permissions exactly as documented, avoid --verbose unless third-party disclosure of node IPs to ipinfo.io is acceptable, avoid --trace-origin unless the inferred target is explicitly authorized, and treat generated signed push/pull URLs and downloaded access logs as sensitive. Run traffic-theft analysis with bounded, trusted log windows where possible.

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

Warning
Location
scripts/live_theft_handler.py:297
Finding
Unvalidated Server-Provided Log URL Enables Server-Side Request Forgery<![CDATA[ ## Vulnerability Details **File Location**: `scripts/live_theft_handler.py:297-327` **Vulnerability Type**: Server-side request forgery through unrestricted URL retrieval **Risk Level**: Medium ### Complete Code Snippet ```python for group in resp.get("DomainLogDetails", {}).get("DomainLogDetail", []): for detail in group.get("LogInfos", {}).get("LogInfoDetail", []): log_url = detail.get("LogPath", "") if log_url: # The LogPath returned by the API sometimes lacks a scheme if not log_url.startswith(("http://", "https://")): log_url = "https://" + log_url paths.append(log_url) return paths def download_log_text(url, timeout=60): """Download a log file (supports .gz and plain text) and return its text.""" try: req = urllib.request.Request(url) with urllib.request.urlopen(req, timeout=timeout) as resp: data = resp.read() content_encoding = resp.headers.get("Content-Encoding", "").lower() except urllib.error.HTTPError as e: body = e.read().decode("utf-8", errors="replace") raise RuntimeError(f"Failed to download log, HTTP {e.code}: {body}") from e # Detect gzip via Content-Encoding, magic bytes, or file extension is_gzip = ( content_encoding == "gzip" or data.startswith(b"\x1f\x8b") or url.split("?")[0].endswith(".gz") ) if is_gzip: with gzip.GzipFile(fileobj=io.BytesIO(data)) as gz: return gz.read().decode("utf-8", errors="replace") return data.decode("utf-8", errors="replace") ``` ### Technical Analysis The complete `LogPath` returned by the Alibaba Cloud API is accepted as a network destination. The implementation checks only whether the string begins with `http://` or `https://`; it does not validate the destination hostname, resolved address, port, or redirect chain. Consequently, a manipulated API response, compromised account-side log recor ...[truncated 1974 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require HTTPS and reject plaintext HTTP log URLs. 2. Allowlist the exact Alibaba Cloud storage and log-delivery host suffixes documented for `DescribeLiveDomainLog`. 3. Parse URLs with `urllib.parse.urlsplit()` and reject: - Embedded credentials - Unexpected ports - Missing hostnames - IP-literal hosts unless explicitly required 4. Resolve the hostname before connecting and reject loopback, private, link-local, multicast, reserved, and unspecified addresses using Python's `ipaddress` module. 5. Disable automatic redirects or implement a redirect handler that repeats all validation for every destination. 6. Protect against DNS rebinding by connecting only to a validated resolved address while preserving the expected TLS hostname, or use a networking library that supports controlled resolution safely. 7. Return a structured error when a URL falls outside the approved Alibaba log-delivery boundary. 8. Avoid including complete signed log URLs in output because their query parameters may provide temporary access to sensitive logs. ]]>

other

Note
Location
scripts/live_node.py:158
Finding
Verbose Node Analysis Discloses Target Infrastructure to an Undeclared Third Party<![CDATA[ ## Vulnerability Details **File Location**: `scripts/live_node.py:158-174, 242-247` **Vulnerability Type**: Undeclared third-party infrastructure disclosure **Risk Level**: Low ### Complete Code Snippet ```python def get_ip_region(ip): """Get IP geolocation info (best effort). Falls back to 'unknown' on any failure so that the main analysis flow is never blocked by the geolocation lookup. """ try: cmd = ["curl", "-s", "--connect-timeout", "3", "--max-time", "5", f"https://ipinfo.io/{ip}/json"] stdout, rc = run_cmd(cmd, timeout=8) if rc == 0 and stdout: data = json.loads(stdout) return { "ip": ip, "country": data.get("country", "unknown"), "region": data.get("region", "unknown"), "city": data.get("city", "unknown"), "org": data.get("org", "unknown"), } except Exception: pass return {"ip": ip, "country": "unknown", "region": "unknown", "city": "unknown", "org": "unknown"} ``` ```python # Region info (verbose mode only) if verbose: region_info = get_ip_region(ip) node["region"] = region_info.get("region", "unknown") node["city"] = region_info.get("city", "unknown") node["org"] = region_info.get("org", "unknown") ``` ### Technical Analysis When verbose mode is enabled, the script sends each DNS-resolved CDN node IP address to `https://ipinfo.io`. The Skill documentation describes Alibaba Cloud APIs and local network probes but does not disclose this third-party recipient. The geolocation request exposes more than is required to determine node reachability and latency. The third party can observe: - The resolved target infrastructure IP - The audit operator's source IP - Request timing - Repeated investigations involving the same infrastructure The request uses HTTPS, and no Alibaba credentials or log contents are deliberately attached. Theref ...[truncated 1107 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the ipinfo.io request from the default Skill implementation. 2. If region information is needed, use an approved offline IP-to-region database. 3. If the external service must remain: - Document the service and disclosed data in `SKILL.md` - Require separate, explicit user consent before the request - Make third-party lookup opt-in rather than part of general verbose output - Provide a flag such as `--external-geolocation` 4. Confirm applicable privacy, retention, and data-processing terms before enabling the integration. 5. Avoid sending any additional stream URL, domain, access-log content, credential, or signed URL to the geolocation provider. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/live_node.py:273
Finding
Origin Tracing Guesses and Probes a Domain Not Explicitly Authorized by the User<![CDATA[ ## Vulnerability Details **File Location**: `scripts/live_node.py:273-283` **Vulnerability Type**: Unauthorized target derivation and network probing **Risk Level**: Medium ### Complete Code Snippet ```python # 4. Origin probing (if the pull domain differs from the push domain, # try probing the inferred push domain) if trace_origin: push_domain = domain.replace("pull", "push").replace("live", "push") if push_domain != domain: push_ips = resolve_domain(push_domain) if push_ips: origin_result = ping_host(push_ips[0], count=2) result["origin"] = { "domain": push_domain, "ip": push_ips[0], "reachable": origin_result["reachable"], "latency_ms": origin_result.get("avg_ms"), } ``` ### Technical Analysis The `--trace-origin` workflow derives a new hostname through broad string replacement and then performs DNS resolution and ICMP probing against it. The user supplied only the original stream domain. This contradicts the Skill's declared `USER-PROVIDED TARGETS ONLY` boundary, which prohibits guessing, deriving, or scanning domains not explicitly supplied by the user. It also conflicts with least-privilege expectations because origin diagnosis does not justify probing an unverified hostname. The transformation is not limited to a validated label such as `pull.example.com`. It replaces every occurrence of `pull` and then every occurrence of `live`, which can generate an unrelated but valid hostname. Ownership or Alibaba Cloud domain mapping is never verified before the probe. ### Attack Path 1. A user supplies a domain and enables `--trace-origin`. 2. The script modifies the hostname with: - `pull` to `push` - `live` to `push` 3. The resulting hostname may belong to another service, account, or third party. 4. The script resolves the guessed hostname. 5. If resolution succeeds, the script sends ICMP echo requests to its f ...[truncated 804 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove heuristic hostname replacement. 2. Resolve the push and pull domain relationship through the declared read-only `describe-live-domain-mapping` API. 3. Verify that the mapped domain belongs to the same authorized Alibaba Cloud account and corresponds to the supplied domain. 4. Display the mapped hostname and request explicit user confirmation before sending any network probe to it. 5. If credentials or domain mapping are unavailable, stop origin probing and report that the origin cannot be safely determined. 6. Validate all targets as hostnames and reject malformed values, IP literals outside the expected scope, and unexpected mapping results. 7. Clearly distinguish a verified mapped ingest domain from a CDN origin; domain mapping alone should not be represented as proof of the actual origin server. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/live_theft_handler.py:307
Finding
Unbounded Log Download and Gzip Decompression Allow Memory Exhaustion<![CDATA[ ## Vulnerability Details **File Location**: `scripts/live_theft_handler.py:307-327, 672-682` **Vulnerability Type**: Unbounded remote-data processing and decompression denial of service **Risk Level**: Medium ### Complete Code Snippet ```python def download_log_text(url, timeout=60): """Download a log file (supports .gz and plain text) and return its text.""" try: req = urllib.request.Request(url) with urllib.request.urlopen(req, timeout=timeout) as resp: data = resp.read() content_encoding = resp.headers.get("Content-Encoding", "").lower() except urllib.error.HTTPError as e: body = e.read().decode("utf-8", errors="replace") raise RuntimeError(f"Failed to download log, HTTP {e.code}: {body}") from e # Detect gzip via Content-Encoding, magic bytes, or file extension is_gzip = ( content_encoding == "gzip" or data.startswith(b"\x1f\x8b") or url.split("?")[0].endswith(".gz") ) if is_gzip: with gzip.GzipFile(fileobj=io.BytesIO(data)) as gz: return gz.read().decode("utf-8", errors="replace") return data.decode("utf-8", errors="replace") ``` ```python combined_text = "" if log_paths: for path in log_paths: try: combined_text += download_log_text(path) + "\n" except Exception as e: # A single unreachable log URL must not abort the whole # analysis; record it and continue with the rest. log_download_failures.append({"url": path, "error": redact_secrets(e)[:300]}) print(f"[warn] failed to download log, skipping: {redact_secrets(e)[:200]}", file=sys.stderr) ``` ### Technical Analysis The implementation performs several unbounded memory operations: 1. `resp.read()` loads the complete compressed or plaintext response into memory. 2. `gz.read()` decompresses the entire gzip payload without an expansion limit. 3. `.decode()` creates another full in-m ...[truncated 1676 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Stream log content in bounded chunks instead of calling `resp.read()` without a size. 2. Enforce independent limits for: - Maximum number of log files - Maximum compressed bytes per file - Maximum decompressed bytes per file - Maximum total bytes for the complete analysis - Maximum parsed lines 3. Reject responses whose declared `Content-Length` exceeds policy, while still enforcing a runtime byte counter because the header may be absent or false. 4. Decompress incrementally and stop once the decompressed-byte limit is reached. 5. Parse and aggregate counters line by line instead of retaining complete log text. 6. Replace repeated string concatenation with streaming analysis; if aggregation is unavoidable, use a bounded list and `"".join()`. 7. Apply CPU and memory limits to the analysis subprocess where supported. 8. Return a clear partial-analysis result when limits are reached rather than silently treating the logs as complete. 9. Limit HTTP error-body reads as well, because `e.read()` is also currently unbounded. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (5)

Tp4

High
Category
MCP Tool Poisoning
Confidence
83% confidence
Finding
The skill markets itself as read-only and never changing configuration, but it also supports local process management that can terminate active recording jobs via `stop --recording-id` and `stop --all`. Even if limited to tool-tracked PIDs, that is still a state-changing action on the local host, and the mismatch can mislead operators or automation into granting broader trust than warranted.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
In verbose mode, the skill sends discovered CDN node IP addresses to ipinfo.io, a third-party service, even though geolocation is not necessary for basic reachability diagnostics. This leaks infrastructure metadata outside the Alibaba Cloud environment and may expose customer network details or operational patterns without clear consent.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The CLI exposes --verbose as if it only increases detail, but in practice it triggers outbound disclosure of probed IPs to a third-party service. Because the user-facing flag description does not clearly warn about this data transfer, operators may unintentionally leak sensitive node information during troubleshooting.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The tool prints fully usable signed push and pull URLs in its JSON output, and those URLs can temporarily grant publishing or playback access to a live stream. Although the script masks the underlying auth key, the generated signed URLs themselves are bearer-style credentials during their validity window, so exposing them in normal output increases the risk of accidental sharing, logging, or reuse.

Unvalidated Output Injection

High
Category
Output Handling
Content
# Capture the snapshot
    try:
        proc = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
        if proc.returncode == 0 and os.path.isfile(output):
            result["status"] = "captured"
            result["file_size"] = os.path.getsize(output)
Confidence
77% confidence
Finding
On snapshot failure, the code extracts lines from ffmpeg stderr and places them directly into JSON output. Because ffmpeg error text can include attacker-controlled URL content or stream metadata, a malicious input source could inject misleading content, control characters, or hostile strings into downstream logs, consoles, or agents that consume this JSON.

Static analysis

No suspicious patterns detected.