T03 · Remote Payload Retrieval and Execution
- Location
SKILL.md:14- Finding
Unpinned Remote Source Is Built and Installed into a Privileged System Path
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill appears to do thermostat control as advertised, but its installation asks users to build mutable external code and place it in a system-wide path while the reviewed artifact does not include the full installable program.
Review before installing. Prefer a pinned, reviewed release with checksum or signature verification, install into a user-owned bin directory instead of using sudo, and use Keychain login rather than long-lived shell environment variables. Only allow the agent to change temperatures after explicit confirmation.
SKILL.md:14Unpinned Remote Source Is Built and Installed into a Privileged System Path
internal/api/client.go:161Thermostat Setpoints Are Submitted Without Local Finite-Value or Range Validation
The skill is presented as thermostat control, but it also handles credential storage, retrieval from environment variables, and credential clearing. That mismatch increases the chance that users or orchestrators authorize the skill for innocuous home-control tasks without realizing it can access or manipulate authentication material.
The skill explicitly stores credentials in the OS keychain and supports reading authentication secrets from environment variables. While this may be functional rather than malicious, credential handling is sensitive in an agent context because the skill can become a pathway to access, persist, or misuse secrets beyond simple thermostat control.
| `enzoldhazam status --json` | JSON output for parsing |
| `enzoldhazam get <room>` | Get specific room details |
| `enzoldhazam set <room> <temp>` | Set target temperature |
| `enzoldhazam login` | Save credentials to Keychain |
| `enzoldhazam logout` | Clear stored credentials |
## Examples
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import (
"os"
"github.com/zalando/go-keyring"
)
const (
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import (
"os"
"github.com/zalando/go-keyring"
)
const (
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import (
"os"
"github.com/zalando/go-keyring"
)
const (
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import (
"os"
"github.com/zalando/go-keyring"
)
const (
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import (
"os"
"github.com/zalando/go-keyring"
)
const (
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import (
"os"
"github.com/zalando/go-keyring"
)
const (
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import (
"os"
"github.com/zalando/go-keyring"
)
const (
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import (
"os"
"github.com/zalando/go-keyring"
)
const (
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import (
"os"
"github.com/zalando/go-keyring"
)
const (
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import (
"os"
"github.com/zalando/go-keyring"
)
const (
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
import (
"os"
"github.com/zalando/go-keyring"
)
const (
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Serial string
}
// Save stores credentials in the macOS Keychain
func Save(creds Credentials) error {
if err := keyring.Set(serviceName, userKey, creds.Username); err != nil {
return err
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Serial string
}
// Save stores credentials in the macOS Keychain
func Save(creds Credentials) error {
if err := keyring.Set(serviceName, userKey, creds.Username); err != nil {
return err
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Serial string
}
// Save stores credentials in the macOS Keychain
func Save(creds Credentials) error {
if err := keyring.Set(serviceName, userKey, creds.Username); err != nil {
return err
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
}, nil
}
// Fall back to keychain
username, err := keyring.Get(serviceName, userKey)
if err != nil {
return nil, err
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
}, nil
}
// Fall back to keychain
username, err := keyring.Get(serviceName, userKey)
if err != nil {
return nil, err
The README instructs users to place their account username and password in environment variables, but does not warn that environment variables can be exposed through shell history, process inspection, crash reports, logs, or inherited subprocess environments. For a tool that controls smart-home thermostats and accesses a real account, this creates a realistic credential disclosure risk rather than a purely theoretical documentation issue.
The skill invokes environment-based credentials and operational CLI commands but does not declare any explicit tool scope or permissions boundary. In an agent setting, missing scope declarations can allow the skill to be selected or executed without clear user/admin review of its access to secrets and local execution capabilities.
The trigger language is broad enough to match ordinary conversation about temperature or heating, which can cause over-invocation of a state-changing skill. In context, this is more dangerous because the skill can control real smart-home devices, so an accidental match could lead to unintended thermostat changes or related credential prompts.
The setup instructions require sudo mv into /usr/local/bin, normalizing privileged execution during installation. Encouraging root-level file operations for an unverified downloaded binary increases the blast radius if the repository or build process is compromised.
git clone https://github.com/daniel-laszlo/enzoldhazam.git cd enzoldhazam go build -o enzoldhazam ./cmd/enzoldhazam sudo mv enzoldhazam /usr/local/bin/
2. Login (credentials stored in macOS Keychain):
This function collects a username and password and sends them in an HTTP POST request to a remote service, but the code provides no user-facing confirmation, logging, or warning that credentials will be transmitted. The surrounding comments describe the implementation steps, but they are developer-oriented rather than disclosure to the user.
This method performs a remote POST request that changes thermostat settings, which is a state-changing operation affecting the user's environment. Although the function name and comments describe its purpose, there is no visible confirmation prompt or user-facing disclosure in this file before the action is sent.
The code reads username, password, and serial values from environment variables, which is a sensitive credential-access operation. While comments describe the control flow, there is no user-facing warning, logging, confirmation, or broader disclosure that credentials may be sourced from process environment variables.
No suspicious patterns detected.