T03 · Remote Payload Retrieval and Execution
- Location
scripts/diagnose_and_install.py:198- Finding
Automatic Execution of an Unverified Remote Installation Script
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This setup skill is mostly aligned with its stated automation purpose, but it automatically runs mutable remote installers and installs broad unpinned components in ways users should review carefully before use.
Install only in a disposable or low-privilege environment after reviewing each external source. Do not run the automatic setup on a machine with sensitive credentials, and avoid using downloaded persona text as a system prompt unless you have manually reviewed and pinned it. Protect or rotate any API keys entered into the generated .env file.
scripts/diagnose_and_install.py:198Automatic Execution of an Unverified Remote Installation Script
scripts/diagnose_and_install.py:305Unverified Remote Persona Downloaded with TLS Validation Disabled
scripts/diagnose_and_install.py:402Unpinned Packages, Skills, and Repository Branches Create a Broad Supply-Chain Risk
scripts/diagnose_and_install.py:134Secrets Are Echoed During Entry and Written Without Explicit Restrictive Permissions
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
print(f"{Colors.RED}拒绝 (请检查文件夹权限){Colors.ENDC}")
def check_env_file():
print(f" - .env 配置文件: ", end="", flush=True)
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
env_path = os.path.join(base_dir, ".env")
if os.path.exists(env_path):
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
print(f"{Colors.RED}拒绝 (请检查文件夹权限){Colors.ENDC}")
def check_env_file():
print(f" - .env 配置文件: ", end="", flush=True)
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
env_path = os.path.join(base_dir, ".env")
if os.path.exists(env_path):
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
print(f"{Colors.RED}拒绝 (请检查文件夹权限){Colors.ENDC}")
def check_env_file():
print(f" - .env 配置文件: ", end="", flush=True)
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
env_path = os.path.join(base_dir, ".env")
if os.path.exists(env_path):
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
print(f"{Colors.RED}拒绝 (请检查文件夹权限){Colors.ENDC}")
def check_env_file():
print(f" - .env 配置文件: ", end="", flush=True)
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
env_path = os.path.join(base_dir, ".env")
if os.path.exists(env_path):
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
print(f"{Colors.RED}拒绝 (请检查文件夹权限){Colors.ENDC}")
def check_env_file():
print(f" - .env 配置文件: ", end="", flush=True)
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
env_path = os.path.join(base_dir, ".env")
if os.path.exists(env_path):
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
print(f"{Colors.RED}拒绝 (请检查文件夹权限){Colors.ENDC}")
def check_env_file():
print(f" - .env 配置文件: ", end="", flush=True)
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
env_path = os.path.join(base_dir, ".env")
if os.path.exists(env_path):
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def check_env_file():
print(f" - .env 配置文件: ", end="", flush=True)
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
env_path = os.path.join(base_dir, ".env")
if os.path.exists(env_path):
print(f"{Colors.GREEN}已发现{Colors.ENDC}")
else:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def check_env_file():
print(f" - .env 配置文件: ", end="", flush=True)
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
env_path = os.path.join(base_dir, ".env")
if os.path.exists(env_path):
print(f"{Colors.GREEN}已发现{Colors.ENDC}")
else:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
def check_env_file():
print(f" - .env 配置文件: ", end="", flush=True)
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
env_path = os.path.join(base_dir, ".env")
if os.path.exists(env_path):
print(f"{Colors.GREEN}已发现{Colors.ENDC}")
else:
This line writes user-supplied secrets into a .env file without applying restrictive permissions or other protections. In a setup assistant, storing API keys in plaintext can lead to credential exposure through local compromise, accidental commits, shared systems, or permissive umasks.
val = input(f" > {key}: ").strip()
final_config.append(f"{key}={val}\n")
# 写入 .env
with open(env_path, 'w', encoding='utf-8') as f:
f.writelines(final_config)
This workflow executes a remote installer script directly from the network through a shell pipeline without a meaningful safety warning or confirmation. In a setup tool that automatically installs components, this is especially dangerous because it normalizes blind remote code execution for users who may not inspect the source.
Fetching a shell script from the internet and piping it directly into bash is a classic high-risk remote code execution pattern. In an automation helper that users may trust to bootstrap environments, this is especially dangerous because compromise of the remote source immediately compromises the host.
print_step("正在自动部署 Tencent SkillHub (国内加速源)...")
try:
# 使用用户提供的快速安装脚本
install_cmd = "curl -fsSL https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/install/install.sh | bash -s -- --no-skills"
result = subprocess.run(install_cmd, shell=True, text=True)
if result.returncode == 0:
print(f"{Colors.GREEN}SkillHub CLI 部署成功{Colors.ENDC}")
Using subprocess.run with shell=True on a command string that fetches and executes remote content compounds the risk: the shell interprets the pipeline and any environment-sensitive behavior, while the fetched script gains full execution. This is a strong true positive even though the command string is constant, because the tool is being used to perform arbitrary remote-code installation.
try:
# 使用用户提供的快速安装脚本
install_cmd = "curl -fsSL https://skillhub-1388575217.cos.ap-guangzhou.myqcloud.com/install/install.sh | bash -s -- --no-skills"
result = subprocess.run(install_cmd, shell=True, text=True)
if result.returncode == 0:
print(f"{Colors.GREEN}SkillHub CLI 部署成功{Colors.ENDC}")
# 自动将本地路径加入当前进程环境,确保后续直接调用有效
The persona downloader suppresses transport verification and silently writes remote content into a local file presented as agent persona material. Because the script later encourages using that content as a system prompt, this becomes a high-risk trust-boundary violation rather than a harmless convenience feature.
The comment says SSL warnings are merely ignored, but the code actually disables both hostname and certificate verification before downloading remote content. That materially weakens transport security and allows man-in-the-middle tampering of files that are then saved for later use in the agent environment.
The skill advertises automated setup, package installation, configuration changes, and network retrieval from external sources without prominently warning users that it will modify the local environment and reach out to third-party services. This is dangerous because users may invoke it expecting guidance only, while it could trigger shell scripts, dependency installs, or repository fetches that alter system state and expand the attack surface.
The phrase claiming automatic bypass of login restrictions and network barriers is a strong red flag because it normalizes evasion of access controls as a convenience feature. In a skill whose purpose is to fetch and install external content, this could enable unauthorized access paths, unsafe mirrors, or tooling designed to circumvent platform controls, significantly increasing the risk of policy violations and supply-chain compromise.
The guide instructs users to enter Feishu secrets and AI API keys and states that a .env file will be generated automatically, but it gives no warning about secure storage, file permissions, exclusion from version control, or risks of exposing credentials. In a setup assistant that normalizes one-click automation, this increases the chance users will mishandle secrets or leave them in an insecure location.
The guide normalizes downloading third-party personas and injecting them directly as the agent's system prompt, which gives untrusted external content the highest instruction priority in many agent architectures. This can introduce prompt injection, unsafe tool use directives, data exfiltration instructions, or policy overrides that are hard for end users to detect.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
print(f" - 网络连通性 ({host}): ", end="", flush=True)
try:
# 使用 ping 测试 (Mac/Linux -c 1)
subprocess.check_output(['ping', '-c', '1', '-W', '2', host], stderr=subprocess.STDOUT)
print(f"{Colors.GREEN}畅通{Colors.ENDC}")
return True
except:
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
print(f" - OpenClaw 版本: ", end="", flush=True)
try:
# 尝试通过 CLI 获取版本
result = subprocess.run(['openclaw', '--version'], capture_output=True, text=True)
version = result.stdout.strip().split('\n')[-1] # 取最后一行
if version:
print(f"{Colors.GREEN}{version}{Colors.ENDC}")
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
IS_CLAWHUB_LOGGED_IN = False
try:
# 探测版本
result = subprocess.run(['npx', 'clawhub', '--cli-version'], capture_output=True, text=True, timeout=5)
if result.returncode == 0:
version = result.stdout.strip().split()[-1]
# 增加登录状态检测
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
if result.returncode == 0:
version = result.stdout.strip().split()[-1]
# 增加登录状态检测
login_check = subprocess.run(['npx', 'clawhub', 'whoami'], capture_output=True, text=True)
if login_check.returncode == 0:
print(f"{Colors.GREEN}已登录 ({version}){Colors.ENDC}")
IS_CLAWHUB_LOGGED_IN = True
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
print(f" - 飞书官方工具栈: ", end="", flush=True)
try:
# 探测飞书官方工具包
result = subprocess.run(['npx', '@larksuite/openclaw-lark-tools', '--help'],
capture_output=True, text=True, timeout=5)
if result.returncode == 0:
print(f"{Colors.GREEN}发现并可用{Colors.ENDC}")
The script interactively collects secrets such as API keys and writes them into a .env file without warning about local secret storage, file permissions, or operational handling. In a setup assistant this increases the chance users expose credentials through weak filesystem protections, backups, logs, or accidental commits.
No suspicious patterns detected.