T09 · Insecure Skill Coding Practices
- Location
scripts/recalc.py:25- Finding
Persistent Overwrite of a User LibreOffice Macro Module
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a coherent spreadsheet helper, but its formula recalculation script can persistently modify and overwrite a user's LibreOffice macro module without clear consent.
Review this before installing if you use LibreOffice macros or process untrusted spreadsheets. Prefer fixing the recalculation helper to use a temporary LibreOffice profile, a skill-specific macro name, file-type allowlisting, and backups or explicit consent before any profile changes. Use copies of important workbooks until that is addressed.
scripts/recalc.py:25Persistent Overwrite of a User LibreOffice Macro Module
The skill is presented as spreadsheet-specific, but it describes launching LibreOffice/soffice and recalculation helpers in a way that could operate on arbitrary LibreOffice-supported files if inputs are not constrained. That mismatch matters because generic document execution/conversion broadens the attack surface beyond spreadsheets and may allow unsafe handling of unexpected file types.
The skill is presented as spreadsheet-specific, but it describes launching LibreOffice/soffice and recalculation helpers in a way that could operate on arbitrary LibreOffice-supported files if inputs are not constrained. That mismatch matters because generic document execution/conversion broadens the attack surface beyond spreadsheets and may allow unsafe handling of unexpected file types.
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.
def get_soffice_env() -> dict:
"""Return environment dict for running soffice headlessly."""
env = os.environ.copy()
env["SAL_USE_VCLPLUGIN"] = "svp"
return env
This is a true tool-parameter abuse issue because shell=True delegates command resolution to the shell, making execution dependent on ambient environment state rather than an explicit trusted binary. In automated agent environments, adversaries may be able to influence PATH, shell behavior, or wrapper scripts, turning a benign capability check into arbitrary command execution.
if platform.system() == "Windows":
return True
try:
subprocess.run(["timeout", "--version"], capture_output=True, timeout=1, check=False, shell=True)
return True
except (FileNotFoundError, subprocess.TimeoutExpired):
return False
The skill documents and encourages capabilities that require shell execution, filesystem access, and environment-variable use, but it declares no explicit tool scope or permission boundaries. In an agentic environment, this increases the chance the skill can be invoked with broader-than-necessary privileges and perform file or process operations on unintended targets.
The description says to use the skill "any time a spreadsheet file is the primary input or output" and covers nearly any task involving open, read, edit, fix, create, or convert spreadsheet-like files. Although examples are provided, the text does not clearly define non-matching cases, making the activation scope ambiguous and prone to collisions with general data-processing requests.
The trigger list includes generic terms like "excel," "spreadsheet," and "csv" without any narrowing context or exclusion conditions. These words commonly appear in ordinary user requests and could cause unintended invocation of this skill for broad tabular-data discussions rather than explicit spreadsheet editing tasks.
The instructions require default currency formatting for CNY and USD and specify a Chinese-market-style unit example, which can force a locale-specific output convention on users who did not request it. This is a natural-language locale policy concern because the file sets a default regional formatting behavior rather than offering a user choice.
Subtle instructions detected that may alter agent decision-making or introduce hidden biases.
Always use Excel formulas instead of calculating values in Python and hardcoding them. This ensures the spreadsheet remains dynamic and updateable.
The helper exposes generic LibreOffice execution rather than constraining operations to spreadsheet-specific actions. In the context of a spreadsheet skill, this broad capability expands the attack surface because callers can drive LibreOffice against non-spreadsheet documents or with unexpected flags, potentially enabling unintended file access, macro handling, or document conversion behaviors beyond the advertised skill scope.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
"""Run soffice with the given arguments."""
soffice = _find_soffice()
env = get_soffice_env()
return subprocess.run([soffice] + args, env=env, **kwargs)
if __name__ == "__main__":
This call uses shell=True while providing a command intended to probe for the timeout utility. On POSIX systems, shell=True with a sequence can produce unexpected shell invocation behavior and may execute a different program from PATH than intended, creating command execution risk if PATH or the environment is attacker-influenced. In an agent skill context, this is more dangerous because the skill may run in varied host environments with untrusted PATH settings.
if platform.system() == "Windows":
return True
try:
subprocess.run(["timeout", "--version"], capture_output=True, timeout=1, check=False, shell=True)
return True
except (FileNotFoundError, subprocess.TimeoutExpired):
return False
The script writes a persistent LibreOffice application macro into the user's profile and then invokes it for spreadsheet processing. Persistently modifying host application macro state is dangerous because it creates long-lived code execution capability in LibreOffice outside the lifetime of this task, can interfere with other documents or workflows, and expands the blast radius if an attacker can later trigger or replace that macro. In a spreadsheet-handling skill, this is especially concerning because processing untrusted office files already carries elevated risk.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
soffice = _find_soffice()
if not os.path.exists(macro_dir):
subprocess.run(
[soffice, "--headless", "--terminate_after_init"],
capture_output=True,
timeout=10,
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
else:
cmd = ["timeout", str(timeout)] + cmd
result = subprocess.run(cmd, capture_output=True, text=True, env=get_soffice_env())
# timeout returns 124 on Linux; on Windows it's different
if result.returncode != 0:
This markdown file describes creating and editing .xlsx files, which can affect user data, but it does not include any caution about modifying existing spreadsheets or choosing output paths carefully. Under the markdown-specific SQP-2 criteria, user-facing documentation should warn about behaviors that may impact user data or system integrity.
The usage section tells users to execute a Python script that invokes LibreOffice for recalculation, but the README provides no explicit warning that an external application/process will be launched. For markdown files, behaviors that may affect system integrity or perform notable system actions should be disclosed to users.
The note says currency defaults were changed to yuan for Chinese market context, but the skill description and triggers are broad and not limited to China-specific use. Without explicit opt-in or clear regional scoping, this can lead to outputs being localized to one market by default for unrelated users.
No suspicious patterns detected.