T03 · Remote Payload Retrieval and Execution
- Location
scripts/create_feishu_bot.py:254- Finding
Mutable Remote Python Script Is Downloaded and Executed During Initialization
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill does create Feishu bots as advertised, but it uses broad Feishu permissions, unsafe credential handling, and risky runtime installation behavior that should be reviewed before use.
Install only if you are comfortable letting this skill automate Feishu developer actions from your logged-in session, request many high-impact Feishu permissions, modify the local Python/system environment during setup, and expose the generated app_secret through chat history. Prefer a revised version with minimal opt-in permission profiles, pinned dependencies, no remote bootstrap execution, verified TLS, isolated temp paths, and secret delivery outside persistent chat.
scripts/create_feishu_bot.py:254Mutable Remote Python Script Is Downloaded and Executed During Initialization
requirements.txt:1Unpinned Dependencies and Configurable Browser Download Source Create Supply-Chain Risk
scripts/create_feishu_bot.py:103Automatically Requested Feishu Permissions Substantially Exceed Bot-Creation Requirements
scripts/create_feishu_bot.py:450TLS Verification Is Disabled for User-Selectable Avatar Retrieval and Feishu Upload
scripts/create_feishu_bot.py:1023Application Secret Is Transmitted in a Persistent Feishu Chat Message
Referenced artifact was not completely inspected
- `scripts/create_feishu_bot.py`:执行实际创建流程的脚本
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.
def _build_playwright_install_env() -> dict:
env = os.environ.copy()
env["PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD"] = "0"
env["DEBIAN_FRONTEND"] = "noninteractive"
env.setdefault("PLAYWRIGHT_DOWNLOAD_CONNECTION_TIMEOUT", "120000")
The avatar upload request sends authenticated browser cookies and CSRF token over a request that explicitly disables TLS verification. This enables credential/session theft or request tampering by an on-path attacker, potentially compromising the logged-in Feishu developer session and all subsequent app-management actions.
The skill instructs the agent to run a local Python script with broad capabilities including shell execution, file reads/writes, environment-variable input, and network access, but it declares no explicit tool scope or permission boundaries. This creates an authorization gap: an agent may execute a powerful workflow without users or policy engines having a clear, machine-readable declaration of what capabilities the skill requires.
The workflow relies on persistent local state across steps: environment variables carry input into the create phase, and a login QR code is written to a predictable local file path in /tmp for later retrieval. This can expose sensitive session artifacts or cause cross-run confusion if another local process or concurrent session reads, replaces, or reuses the same files or inherited environment state.
按已收集的信息设置环境变量,再执行:
python3 ~/.openclaw/workspace/skills/feishu-bot-creator/scripts/create_feishu_bot.py create
The workflow relies on persistent local state across steps: environment variables carry input into the create phase, and a login QR code is written to a predictable local file path in /tmp for later retrieval. This can expose sensitive session artifacts or cause cross-run confusion if another local process or concurrent session reads, replaces, or reuses the same files or inherited environment state.
按已收集的信息设置环境变量,再执行:
python3 ~/.openclaw/workspace/skills/feishu-bot-creator/scripts/create_feishu_bot.py create
The file documents a very broad set of tenant- and user-level permissions, including message access, message sending/modification, file/document access, search, offline access, and event subscriptions, without any warning or guidance on scope minimization, consent, or data handling implications. In the context of a skill that automates Feishu bot/app creation, this can normalize over-privileged app creation and lead users to grant unnecessary access to chats, documents, contacts, and user data.
The avatar download path disables TLS certificate verification, allowing a man-in-the-middle attacker to substitute arbitrary content. While the immediate payload is an image, this still permits silent tampering and normalizes unsafe transport handling in a script that later processes authenticated operations.
The skill performs dependency installation, downloads bootstrap code, and invokes OS package managers, which materially exceed the advertised bot-creation workflow. In a hostile or tightly controlled environment, this broadens attack surface and enables unreviewed code execution and system modification.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
pass
try:
subprocess.check_call(
[sys.executable, "-m", "ensurepip", "--upgrade"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
The script downloads get-pip.py from the network and immediately executes it with Python. This creates a remote code execution path through any compromise of the download channel, TLS interception, or upstream content tampering, and it exceeds the stated purpose of merely creating a Feishu bot.
with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as f:
urllib.request.urlretrieve("https://bootstrap.pypa.io/get-pip.py", f.name)
subprocess.check_call(
[sys.executable, f.name, "--quiet", "--break-system-packages"]
)
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
if not path or not os.path.isfile(path) or not os.access(path, os.X_OK):
return False
try:
subprocess.check_call(
[path, "--version"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
(["apt-get", "install", "-y"], libs_apt),
]:
try:
subprocess.check_call(
[pkg_mgr[0], "--version"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
The script invokes system package managers to install libraries automatically, modifying the host OS beyond the skill's advertised purpose. In an agent environment this can be abused or cause unsafe state changes, especially if repository configuration is untrusted or the process runs with elevated privileges.
except (FileNotFoundError, subprocess.CalledProcessError):
continue
try:
subprocess.call(
pkg_mgr + libs,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
The script automatically installs Python packages at runtime using pip, which changes the host environment and introduces supply-chain risk. In a security-sensitive agent context, automatic package installation from remote repositories can lead to execution of malicious package code or unintended privilege-impacting changes.
if missing:
_status("init", f"安装 Python 依赖: {', '.join(missing)}")
_ensure_pip()
subprocess.check_call(
[sys.executable, "-m", "pip", "install", "--quiet", "--break-system-packages"] + missing
)
importlib.invalidate_caches()
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
host = env.get("PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST") or env.get("PLAYWRIGHT_DOWNLOAD_HOST")
if host:
_status("init", f"使用下载源: {host}")
subprocess.check_call(
[sys.executable, "-m", "playwright", "install", "chromium"],
env=env,
)
QR_PNG_PATH is derived from an environment variable and used directly for file write. If an attacker can influence the environment, they can redirect output to arbitrary writable filesystem locations, potentially overwriting files or placing sensitive login artifacts in unsafe locations.
qr.make(fit=True)
img = qr.make_image(fill_color="black", back_color="white")
img = img.convert("RGB")
with open(QR_PNG_PATH, "wb") as f:
img.save(f)
_status("login", f"已写入登录二维码 PNG: {QR_PNG_PATH}")
except Exception as e:
The script launches a browser binary taken from FEISHU_BOT_BROWSER_PATH or PATH and executes it with subprocess.Popen. In an agent setting, a malicious or compromised environment can point this to an attacker-controlled executable, causing arbitrary code execution under the agent's privileges.
raise FileNotFoundError(f"Chromium 不存在: {chrome_path}")
os.makedirs(PROFILE_DIR, exist_ok=True)
proc = subprocess.Popen(
[
chrome_path,
"--headless=new",
The created app is configured with only zh_cn localization and sets primaryLang to zh_cn, which forces a specific language/locale. There is no visible opt-in, fallback, or justification indicating this skill is intended only for a Chinese-language context.
The skill sends the newly created app's app_id and app_secret over Feishu message to the creator. App secrets are sensitive credentials; transmitting them through chat increases exposure via message retention, account compromise, client-side leakage, or unintended recipients.
Natural-language policy issues include forcing a specific language without user opt-in. This file presents all user-facing documentation in Chinese and does not offer an alternative language or note that the locale is intentionally limited to a specific audience.
The dependency uses a lower-bound version specifier instead of an exact pin, which makes builds non-reproducible and can cause the environment to resolve to different upstream releases over time. That increases supply-chain risk because a newly published vulnerable or malicious version could be installed without any code change in this project.
playwright>=1.40.0
qrcode>=7.4.2
pillow>=10.0.0
The dependency is unpinned and only constrained by a minimum version, so future installs may pull different releases than the ones originally tested. In an automation skill that interacts with external services, this creates supply-chain and stability risk if an upstream package release introduces a vulnerability or malicious code.
playwright>=1.40.0
qrcode>=7.4.2
pillow>=10.0.0
pillow is not pinned, so dependency resolution may select varying releases over time, including versions affected by known security issues. Because Pillow processes image data, vulnerable releases can expose the skill to denial-of-service, memory corruption, or potentially code-execution risks when handling untrusted images such as generated or imported QR-related assets.
playwright>=1.40.0
qrcode>=7.4.2
pillow>=10.0.0
The manifest does not pin pillow, and the package has multiple known advisories across versions, so it is impossible to verify from this file whether deployment will install a safe release. In the context of a bot-creation skill that includes QR/image-related libraries, image parsing may be reachable, which makes unresolved Pillow version risk more meaningful than a purely theoretical issue.