Why this verdict
- suspicious: finding skill:skills/xlsx:skills/xlsx/scripts/recalc.py:13:SUPPLY
- suspicious: finding skill:skills/xlsx:skills/xlsx/scripts/recalc.py:92:EXEC
Security findings 2
Code execution
highContextual riskmedium confidencerecalc.py passes the environment for every soffice subprocess through get_soffice_env() imported from office/soffice.py, which the repository does not ship, so the environment configuration applied at execution time is unreviewable and will come from whatever module occupies that path at runtime.
result = subprocess.run(cmd, capture_output=True, text=True, env=get_soffice_env())
vector:code
Counter-argument considered
Line 92 feeds every soffice subprocess an environment produced by get_soffice_env(), and the follow-up confirms the providing module is NOT IN REPOSITORY, so the environment configuration applied at execution time comes from whatever office.soffice occupies sys.path at runtime — undeclared, unreviewable, and a concrete runtime-module→subprocess-env chain; spawning LibreOffice is arguably core spreadsheet work, but no carve-out covers resolving the env producer from unshipped code, so the finding stands.
Supply chain
mediumContextual riskmedium confidenceskills/xlsx/scripts/recalc.py imports get_soffice_env from office/soffice.py, which the repository does not ship, so the environment for the soffice subprocess is produced by whatever office.soffice module resolves on sys.path at runtime — unreviewable code executing in the agent's process.
from office.soffice import get_soffice_env
vector:code
Counter-argument considered
The served follow-up confirms office/soffice.py is NOT IN REPOSITORY after checks at every plausible location, so this module-level import makes the agent load and execute whatever office.soffice resolves on sys.path at runtime — unreviewable code in the agent's process; no carve-out, declared claim, or mitigation applies, and the import→runtime-resolution→execution chain is concrete, so the finding stands.
Open questions 5
What the analysis could not settle from the code alone.
[file request office/soffice.py] What does get_soffice_env() return and does it set, remove, or redirect environment variables beyond LibreOffice-specific configuration, or read credentials or fetch remote content, when used as the env for the soffice subprocesses in skills/xlsx/scripts/recalc.py?
Code execution
[file request skills/xlsx/scripts/recalc.py] What does setup_libreoffice_macro() write or execute (does it overwrite existing user macros under MACRO_DIR_MACOS/MACRO_DIR_LINUX), and do these lines manipulate sys.path or otherwise determine where the office.soffice import resolves?
Persistence
[file request skills/xlsx/scripts/recalc.py] What do the remaining lines of recalc.py (entry point/CLI) do with the filename argument, and do they fetch remote content or touch files beyond the target spreadsheet?
Code execution
[file request skills/xlsx/office/soffice.py] What does get_soffice_env() return and does it set, remove, or redirect any environment variables beyond LibreOffice-specific configuration (e.g., PATH, HOME, proxy or update/telemetry settings) when used as the env for the subprocess calls in scripts/recalc.py?
Code execution
[file request skills/xlsx/scripts/office/soffice.py] recalc.py imports 'from office.soffice import get_soffice_env' and passes its result as the environment for the soffice subprocess; what does get_soffice_env() do — does it only construct benign environment variables (e.g., HOME/profile isolation) for soffice, or does it read sensitive data (env tokens, credentials, key files) or fetch remote content?
Code execution
Execution chain 10
What it calls, runs, installs, reads and writes, with the line that does it.
Commands run 3
soffice --headless --terminate_after_init
URLs 3
http://openoffice.org/2000/script
https://www.anthropic.com/legal/commercial-terms
https://www.anthropic.com/legal/consumer-terms
Refuted findings 2
Candidates the review stage examined and rejected, kept for transparency.
Persistence
criticalRefutedmedium confidenceThe skill's recalc helper writes a LibreOffice Basic macro (Module1.xba) into the user's LibreOffice profile directory, where it persists as trusted application-level macro code with no cleanup after the task — a persistent host-config write beyond core spreadsheet editing, disclosed in SKILL.md ('Automatically sets up LibreOffice macro on first run') but never removed; the residue execs R1 (gtimeout --version) and R2 (soffice --headless --terminate_after_init) were adjudicated necessary for this declared recalc functionality.
Path(macro_file).write_text(RECALCULATE_MACRO)
Why it was refuted
The macro write is explicitly declared in the skill text and the persisted macro's content is fixed and benign (calculateAll/store/close) in direct service of the declared mandatory recalculation step, so there is no concealed, contradicted, or non-core behavior; the disclosed residue grants no capability beyond what the declared recalc flow already uses.
Code execution
criticalRefutedlow confidenceThe skill text directs the agent to run the bundled scripts/recalc.py (declared mandatory whenever formulas are used), and discloses that this script self-configures LibreOffice on first run, including in sandboxed environments where Unix sockets are restricted, i.e. an environment-restriction workaround whose concrete actions are not shown in the instruction surface.
The script automatically configures LibreOffice on first run, including in sandboxed environments where Unix sockets are restricted
Why it was refuted
The self-configuration the finding flags is declared verbatim in the skill text, and running scripts/recalc.py is the declared mandatory step of the core formula-recalculation capability, so the behavior is disclosed core functionality with its concrete actions visible in the shipped script, not a concealed environment-restriction workaround.
Coverage gaps 11
Parts of the artifact the static analysis could not fully examine.
context:pyc_undecodable pyc for Python 3.11; analyzer runs 3.14
skills/skill-creator/scripts/__pycache__/encoding_utils.cpython-311.pyc
context:pyc_undecodable pyc for Python 3.13; analyzer runs 3.14
skills/skill-creator/scripts/__pycache__/encoding_utils.cpython-313.pyc
context:bytecode_semantics_partial names/constants only; bytecode control flow and source equivalence are not verified
skills/skill-creator/scripts/__pycache__/encoding_utils.cpython-314.pyc
context:pyc_undecodable pyc for Python 3.13; analyzer runs 3.14
skills/skill-creator/scripts/__pycache__/quick_validate.cpython-313.pyc
context:bytecode_semantics_partial names/constants only; bytecode control flow and source equivalence are not verified
skills/skill-creator/scripts/__pycache__/quick_validate.cpython-314.pyc
context:unanalyzable_binary binary content is only byte-scanned
ui/desktop/build/darwin/iconfile.icns
context:unanalyzable_binary binary content is only byte-scanned
ui/desktop/build/windows/icon.ico
skill_frontmatter_invalid missing name/description frontmatter
skills/workspace-organizing/SKILL.md
context:decoded_views_exceeded 120 derived view(s) beyond the per-file view cap: decoded:base64
internal/tokencount/cl100k_base.tiktoken.gz!/cl100k_base.tiktoken
context:frontmatter_unparseable mapping values are not allowed here
skills/workspace-organizing/SKILL.md
invalid_judge_finding request.1