T09 · Insecure Skill Coding Practices
- Location
convert.py:16- Finding
OS Command Injection Through Shell-Based Command Construction
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill mostly matches its astrology purpose, but it needs Review because it ships an unsafe shell-based helper and automatically uses local model credentials/configuration for external LLM calls.
Install only if you are comfortable with a Chinese-language astrology skill sending birth details and questions to your configured OpenAI/OpenClaw-compatible provider. Before use, remove or fix convert.py, avoid running it with untrusted input, pin dependencies, and explicitly review which API key/base URL/model the skill will load, including any ~/.openclaw/openclaw.json fallback.
convert.py:16OS Command Injection Through Shell-Based Command Construction
requirements.txt:1Unpinned and Unverified Third-Party Dependencies
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
如果运行环境没有注入这些变量,可以复制 .env.example 后填写本地配置:
cp .env.example .env
The code clearly supports core astrology computation: bazi chart generation and dayun analysis, including related annotations such as shensha and ten-deity relationships. However, the declared description also claims full-report generation and chat context building, which are not present in this code chunk. The code is strictly a computational backend/CLI module with parsing and data construction, not a report composer or chat-context builder. Additionally, it includes liunian calculation, an analysis capability omitted from the description. Therefore the description does not accurately represent the supplied code's actual behavior.
The declared description presents an active skill that performs multiple user-facing operations: generating bazi charts, analyzing dayun, producing full reports, and building chat context. However, the supplied code chunk contains only imported symbols and extensive constant dictionaries/lookup tables with interpretive text. There are no functions, classes, I/O paths, control flow, request handlers, or orchestration logic that carry out those declared tasks. While these data structures may support an astrology system elsewhere, this specific chunk’s actual behavior is limited to defining static reference data. Therefore the description does not accurately represent what this code chunk itself does.
The code is clearly related to Chinese astrology/Bazi: it contains heavenly stems, earthly branches, 60 ganzhi mappings, ten deities, element relationships, branch interactions, descriptive texts, and health/fortune lookup tables. It also includes small utility functions such as getGZ(), get_jizhu(), get_year_of_ganzhi(), and get_current_year(). However, the declared description claims broader operational capabilities: running bazi chart generation, dayun analysis, full-report generation, and chat context building. None of those higher-level workflows are present in this code chunk. There is no input handling for birth datetime, no construction of a full four-pillar chart, no dayun/luck-cycle computation logic, no report assembly/output generation, and no conversation/context-building logic. There are also no suspicious undeclared permissions or resource accesses; the mismatch is about overstating implemented functionality relative to what this specific code chunk actually does.
There is a clear description-behavior mismatch. The declared purpose claims substantial astrology functionality, but the supplied code chunk contains only a stub function with no analysis, report generation, context building, input handling, or external/resource access. Its actual purpose is merely to provide a placeholder return value and prevent import failures.
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).
for item in zip(options.gans, options.zhis):
result = result + "".join(item) + " "
#subprocess.call("cls", shell=True)
print(result)
print(subprocess.check_output("python bazi.py -b " + result, shell=True).decode('gbk'))
Model output is used without validation or sanitization. Unvalidated output injected into downstream contexts (SQL, shell, HTML) enables injection attacks and arbitrary code execution.
#subprocess.call("cls", shell=True)
print(result)
print(subprocess.check_output("python bazi.py -b " + result, shell=True).decode('gbk'))
This finding is valid because the skill's stated purpose is astrology chart generation, yet it exposes shell execution using user-derived input. That unnecessary shell capability materially increases risk, since the attacker can potentially turn a chart-generation input into arbitrary command execution.
User input is transformed into result and then passed as part of a shell command string to subprocess.check_output with shell=True. This is a classic tool-parameter abuse vector: an attacker can supply shell metacharacters or additional commands, causing execution beyond the intended astrology parameters.
#subprocess.call("cls", shell=True)
print(result)
print(subprocess.check_output("python bazi.py -b " + result, shell=True).decode('gbk'))
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
"""
complete_dayun_text = format_complete_dayun(complete_dayun)
if analysis_type in PROMPT_TEMPLATES:
return PROMPT_TEMPLATES[analysis_type].format(
bazi_info=bazi_info,
complete_dayun=complete_dayun_text,
dayun_list="未提供当前三步大运信息。",
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
"""
complete_dayun_text = format_complete_dayun(complete_dayun)
if analysis_type in PROMPT_TEMPLATES:
return PROMPT_TEMPLATES[analysis_type].format(
bazi_info=bazi_info,
complete_dayun=complete_dayun_text,
dayun_list="未提供当前三步大运信息。",
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
"""
complete_dayun_text = format_complete_dayun(complete_dayun)
if analysis_type in PROMPT_TEMPLATES:
return PROMPT_TEMPLATES[analysis_type].format(
bazi_info=bazi_info,
complete_dayun=complete_dayun_text,
dayun_list="未提供当前三步大运信息。",
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
"""
complete_dayun_text = format_complete_dayun(complete_dayun)
if analysis_type in PROMPT_TEMPLATES:
return PROMPT_TEMPLATES[analysis_type].format(
bazi_info=bazi_info,
complete_dayun=complete_dayun_text,
dayun_list="未提供当前三步大运信息。",
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
"""
complete_dayun_text = format_complete_dayun(complete_dayun)
if analysis_type in PROMPT_TEMPLATES:
return PROMPT_TEMPLATES[analysis_type].format(
bazi_info=bazi_info,
complete_dayun=complete_dayun_text,
dayun_list="未提供当前三步大运信息。",
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
"""
complete_dayun_text = format_complete_dayun(complete_dayun)
if analysis_type in PROMPT_TEMPLATES:
return PROMPT_TEMPLATES[analysis_type].format(
bazi_info=bazi_info,
complete_dayun=complete_dayun_text,
dayun_list="未提供当前三步大运信息。",
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.
"""
complete_dayun_text = format_complete_dayun(complete_dayun)
if analysis_type in PROMPT_TEMPLATES:
return PROMPT_TEMPLATES[analysis_type].format(
bazi_info=bazi_info,
complete_dayun=complete_dayun_text,
dayun_list="未提供当前三步大运信息。",
The README states that the skill returns analysis suitable for the user to read in Chinese, which imposes a language choice by default. There is no indication of user opt-in, alternative language support, or a documented reason that the skill must only respond in Chinese.
The README says the skill should respond when the user says phrases like “帮我分析一下”, which is a very common, non-domain-specific expression. Without stronger constraints or negative examples, this can cause unintended invocation for generic requests unrelated to bazi astrology.
The README explicitly states that the skill can be called even when the user only says “帮我分析一下”, after which it asks for missing birth details. This makes the activation boundary unclear and broad, since a commonplace phrase by itself is treated as sufficient to invoke the skill.
Without declared permissions the skill's intent is opaque and cannot be validated.
The user-facing requirements and examples are written as Chinese-only interaction patterns, including required input phrasing and example requests, but the document does not state that this is a region-specific skill or offer users a language/locale option. This can violate language/locale policy when a skill implicitly constrains interaction to a specific language without opt-in.
This markdown file describes generic user requests such as “帮我分析” and broad categories like 'concrete question' and 'time-related questions' as activation conditions. Those phrases are common and underspecified, and the file does not provide negative examples or tighter scope constraints to distinguish when the skill should or should not be invoked.
This file contains user-facing strings and instructions in Chinese throughout, indicating the skill expects and responds in a single language. There is no indication that users may choose another language or locale, which conflicts with the policy against forcing a language without opt-in.
The skill reads ~/.openclaw/openclaw.json plus multiple environment variables to automatically inherit host model configuration and API credentials. That expands the skill's privilege boundary beyond astrology-specific inputs and can let the skill silently use host secrets or externally configured backends without explicit user or operator consent.
The skill assembles detailed birth data, Bazi chart information, and analysis context, then sends it to an external LLM via chat completions. Birth date/time and derived profile data are sensitive personal information, and this code provides no consent flow, minimization, or warning before transmitting that data off-box.