Back to skill

Security audit

The 4D Acoustic Engine

Security checks for vulnerabilities and agentic risk

Overview

The skill is not clearly malicious, but it needs review because enabling real mode can control Home Assistant devices with a bearer token over plaintext local HTTP and weak destination scoping.

Install only if you intentionally want this skill to connect to Home Assistant. Keep dry-run enabled until tested, use an HTTPS Home Assistant endpoint where possible, use a dedicated least-privilege token, avoid broad administrator tokens, and review or update the pinned dependencies before live use.

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

T09 · Insecure Skill Coding Practices

Error
Location
skill.py:138
Finding
Bearer Token Transmitted over Unencrypted HTTP<![CDATA[ ## Vulnerability Details **File Location**: `skill.py:25-26`, `skill.py:125`, `skill.py:138`; insecure example at `env_template.txt:8` **Vulnerability Type**: Plaintext transmission of sensitive authentication credentials **Risk Level**: High ### Vulnerable Code ```python HA_BASE_URL = os.getenv("HA_BASE_URL", "http://127.0.0.1:8123/api") HA_BEARER_TOKEN = os.getenv("HA_BEARER_TOKEN", "UNCONFIGURED_SANDBOX_TOKEN") ``` ```python headers = {"Authorization": f"Bearer {HA_BEARER_TOKEN}", "Content-Type": "application/json"} ``` ```python requests.post(url, headers=headers, json=req_payload, timeout=5) ``` The supplied environment template also encourages plaintext HTTP: ```text HA_BASE_URL=http://homeassistant.local:8123/api ``` ### Technical Analysis When real actuation is enabled, the Skill places the long-lived Home Assistant bearer token in the HTTP `Authorization` header. Neither the implementation nor the supplied configuration template requires TLS. Consequently, a non-loopback Home Assistant endpoint can receive sensitive credentials over unencrypted HTTP. The local-network address check does not provide transport confidentiality or server authentication. Restricting a destination to a private network therefore does not prevent interception, ARP spoofing, malicious access points, DNS manipulation, or traffic modification by another compromised device on the same network. The outbound request is consistent with the declared smart-home actuation functionality and is disabled by default. However, transmitting a long-lived credential over plaintext HTTP exceeds the minimum safe privilege and confidentiality requirements for that function. ### Attack Path 1. An operator configures `HA_BASE_URL` using the documented plaintext `http://homeassistant.local:8123/api` format. 2. The operator supplies a valid long-lived `HA_BEARER_TOKEN`. 3. `S2_ENABLE_REAL_ACTUATION` is set to `True`. 4. A matching plan causes `SafeActuator.execute_timeline()` to e ...[truncated 883 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require `https://` for every non-loopback endpoint and reject insecure schemes during configuration validation. 2. Permit loopback HTTP only through an explicit development-only option that is disabled by default. 3. Configure `requests` to verify the server certificate; do not disable TLS verification. 4. Support a private certificate authority or certificate pinning where Home Assistant uses an internally issued certificate. 5. Replace the documented URL with an HTTPS example and clearly warn that bearer tokens must not traverse plaintext networks. 6. Use a dedicated, narrowly scoped Home Assistant credential rather than a broadly privileged administrator token. 7. Prevent redirects or validate every redirect destination before forwarding the Authorization header. 8. Add automated tests confirming that non-loopback HTTP URLs are rejected before any request is sent. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
skill.py:35
Finding
SSRF Validation Is Vulnerable to DNS Rebinding and Uses an Overly Broad Internal-Network Trust Boundary<![CDATA[ ## Vulnerability Details **File Location**: `skill.py:35-52`, `skill.py:135-138` **Vulnerability Type**: Incomplete server-side request forgery protection and DNS time-of-check/time-of-use flaw **Risk Level**: Medium ### Vulnerable Code ```python @staticmethod def validate_local_network(url): try: parsed = urlparse(url) hostname = parsed.hostname if not hostname: return False # 真实 DNS 解析与底层 IP 数学校验 resolved_ip_str = socket.gethostbyname(hostname) ip_obj = ipaddress.ip_address(resolved_ip_str) # 仅允许私有网段与回环地址 is_safe = ip_obj.is_private or ip_obj.is_loopback if not is_safe: print(f"🚨 [安全拦截] 目标 IP ({resolved_ip_str}) 为公网地址!拦截 SSRF 攻击!") return is_safe except (socket.gaierror, ValueError): print(f"🚨 [安全拦截] 无效的 IP 或域名解析失败: {url}") return False ``` The validated name is subsequently passed to `requests`, which can perform a separate DNS lookup: ```python if SecurityEnforcer.validate_local_network(url): try: requests.post(url, headers=headers, json=req_payload, timeout=5) print(f" └─ ✅ [硬件响应] 成功调用本地物理设备!") ``` ### Technical Analysis The validation routine resolves the hostname once with `socket.gethostbyname()` and checks only that the resulting address is considered private or loopback. The actual HTTP client then receives the original hostname and may resolve it again while opening the connection. This creates a time-of-check/time-of-use gap. A hostname controlled by an attacker can return an allowed address during validation and a different address during the HTTP client's lookup. The validation result is not cryptographically or operationally bound to the destination used by `requests`. The trust boundary is also broader than necessary. Any address accepted as private or loopback is allowed instead of limiting access to the configured Home Assistant ho ...[truncated 2294 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Allowlist the exact Home Assistant hostname or IP address and expected port instead of trusting every private or loopback address. 2. Restrict accepted schemes to `https`; allow loopback `http` only under an explicit development policy. 3. Resolve all IPv4 and IPv6 addresses using `socket.getaddrinfo()` and reject the destination if any returned address is outside the approved allowlist. 4. Explicitly reject link-local, multicast, unspecified, reserved, documentation, and cloud metadata address ranges. 5. Eliminate the DNS time-of-check/time-of-use gap by connecting to a validated, pinned IP address while preserving and validating the expected TLS hostname through SNI and certificate verification. 6. Disable HTTP redirects for actuator requests, or independently validate and pin every redirect destination before following it. 7. Do not forward the Authorization header across a host, scheme, or port change. 8. Apply outbound firewall or container network policy rules so the process can reach only the intended Home Assistant address and port. 9. Add security tests for DNS rebinding, multiple DNS answers, IPv6 destinations, metadata addresses, alternate schemes, redirects, and user-info URL parsing edge cases. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (19)

Tainted flow: 'url' from os.getenv (line 129, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
if SecurityEnforcer.validate_local_network(url):
                        try:
                            requests.post(url, headers=headers, json=req_payload, timeout=5)
                            print(f"      └─ ✅ [硬件响应] 成功调用本地物理设备!")
                        except Exception as e:
                            print(f"      └─ ❌ [连接失败] 物理网络异常: {e}")
Confidence
91% confidence
Finding
The POST target is derived from an environment-controlled base URL and sent over the network. Although the code attempts SSRF protection by resolving the hostname and requiring a private/loopback IP, this is not a complete defense against all SSRF and DNS-rebinding style issues, and it still permits arbitrary requests to internal services if HA_BASE_URL is misconfigured or attacker-controlled.

Credential Access

High
Category
Privilege Escalation
Content
# S2-Voice-Multimodal-Aligner 环境变量模板
# 使用方法:将此文件重命名为 .env 并填入真实凭证(.env 默认会被 .gitignore 忽略)

# 【物理控制保险栓】 默认 False (安全沙盒模式,不发送真实请求)
S2_ENABLE_REAL_ACTUATION=False
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# S2-Voice-Multimodal-Aligner 环境变量模板
# 使用方法:将此文件重命名为 .env 并填入真实凭证(.env 默认会被 .gitignore 忽略)

# 【物理控制保险栓】 默认 False (安全沙盒模式,不发送真实请求)
S2_ENABLE_REAL_ACTUATION=False
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# S2-Voice-Multimodal-Aligner 环境变量模板
# 使用方法:将此文件重命名为 .env 并填入真实凭证(.env 默认会被 .gitignore 忽略)

# 【物理控制保险栓】 默认 False (安全沙盒模式,不发送真实请求)
S2_ENABLE_REAL_ACTUATION=False
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# S2-Voice-Multimodal-Aligner 环境变量模板
# 使用方法:将此文件重命名为 .env 并填入真实凭证(.env 默认会被 .gitignore 忽略)

# 【物理控制保险栓】 默认 False (安全沙盒模式,不发送真实请求)
S2_ENABLE_REAL_ACTUATION=False
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# S2-Voice-Multimodal-Aligner 环境变量模板
# 使用方法:将此文件重命名为 .env 并填入真实凭证(.env 默认会被 .gitignore 忽略)

# 【物理控制保险栓】 默认 False (安全沙盒模式,不发送真实请求)
S2_ENABLE_REAL_ACTUATION=False
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# S2-Voice-Multimodal-Aligner 环境变量模板
# 使用方法:将此文件重命名为 .env 并填入真实凭证(.env 默认会被 .gitignore 忽略)

# 【物理控制保险栓】 默认 False (安全沙盒模式,不发送真实请求)
S2_ENABLE_REAL_ACTUATION=False
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# S2-Voice-Multimodal-Aligner 环境变量模板
# 使用方法:将此文件重命名为 .env 并填入真实凭证(.env 默认会被 .gitignore 忽略)

# 【物理控制保险栓】 默认 False (安全沙盒模式,不发送真实请求)
S2_ENABLE_REAL_ACTUATION=False
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"required": false,
      "sensitive": true,
      "default": "UNCONFIGURED_SANDBOX_TOKEN",
      "description": "Sensitive access token. Must be provided via system ENV or local .env file. Reference .env.example."
    }
  },
  "language": "python",
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The documentation instructs users to place real Home Assistant credentials into a local .env file and run the skill, but it does not clearly warn about the privacy, safety, and real-world actuation risks of connecting to a live home-automation system. Because the skill claims to analyze medical/acoustic signals and may trigger HTTP POST-based actuation, users could expose sensitive tokens or unintentionally connect a powerful automation system without understanding the consequences.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The manifest frames the skill as a voice/multimodal aligner, yet it also advertises Home Assistant actuation and bearer-token-backed API access. That capability mismatch is dangerous because it can obscure privileged smart-home control behind an innocuous description, reducing operator scrutiny and enabling over-privileged deployment.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
Remote actuation of Home Assistant appears broader than what is justified by the stated 'aligner' purpose in the manifest. Unnecessary actuation capability increases risk because a skill that should only process voice or multimodal input may instead gain the ability to control physical devices or automate actions if invoked in a permissive environment.

Known Vulnerable Dependency: requests==2.31.0 — 6 advisory(ies): CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi); CVE-2026-25645 (Requests has Insecure Temp File Reuse in its extract_zipped_paths() utility func) +3 more

Medium
Category
Supply Chain
Confidence
97% confidence
Finding
The dependency pin `requests==2.31.0` matches a version with published security advisories, so this is a genuine supply-chain vulnerability rather than a false positive. Even in a simple requirements file, vulnerable HTTP client behavior can expose credentials, weaken TLS/request validation, or enable unsafe file handling if affected code paths are used by the skill.

Known Vulnerable Dependency: python-dotenv==1.0.0 — 2 advisory(ies): CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)

Medium
Category
Supply Chain
Confidence
93% confidence
Finding
`python-dotenv==1.0.0` is flagged with published advisories involving unsafe file handling, including symlink-related overwrite risks in `set_key`. If the skill writes or edits `.env` files in attacker-influenced locations, this could lead to arbitrary file overwrite or unintended environment manipulation.

Natural-Language Policy Violations

Medium
Confidence
88% confidence
Finding
The skill's natural-language interface is consistently presented in Chinese, including status messages, warnings, and descriptive comments, with no indication that the user can choose another language. This can violate language/locale policy when a skill imposes a specific language without opt-in or documented regional justification.

External Transmission

Medium
Category
Data Exfiltration
Content
if SecurityEnforcer.validate_local_network(url):
                        try:
                            requests.post(url, headers=headers, json=req_payload, timeout=5)
                            print(f"      └─ ✅ [硬件响应] 成功调用本地物理设备!")
                        except Exception as e:
                            print(f"      └─ ❌ [连接失败] 物理网络异常: {e}")
Confidence
88% confidence
Finding
The skill performs an outbound HTTP POST carrying an authorization bearer token and actuation payload to a configurable endpoint. In this skill context, that external transmission directly controls physical/home-automation actions, so misdelivery, interception on plain HTTP, or endpoint manipulation can affect both secrets and real-world device state.

Natural-Language Policy Violations

Low
Confidence
77% confidence
Finding
The document presents the skill title and content bilingually, prominently including Chinese text, but does not state that language selection is optional or user-configurable. Under the policy, locale or language behavior should either offer user choice or clearly justify the constraint; this file does neither.

Vague Triggers

Low
Confidence
79% confidence
Finding
The manifest describes the skill in broad marketing terms and tags such as "Voice" and "Smart Home," but it does not provide any explicit activation phrases, scope boundaries, or exclusion conditions. In a manifest file, this absence can make it unclear when the skill should be invoked versus ignored, increasing the chance of unintended activation by loosely related requests.

Missing User Warnings

Low
Confidence
82% confidence
Finding
This code unconditionally creates the `s2_voice_vault` directory via `os.makedirs`, which is a filesystem write operation. Although the code logs network and actuation behavior, there is no comparable user disclosure here about creating local storage or what data may be stored in it.

Static analysis

Detected: suspicious.install_untrusted_source

Install source points to URL shortener or raw IP.

Warn
Code
suspicious.install_untrusted_source
Location
manifest.json:24