T07 · Tool Hijacking and Spoofing
Warning
- Location
- recalc.py:20
- Finding
- Unsafe Persistent Installation and Reuse of a Global LibreOffice Macro<![CDATA[ ## Vulnerability Details **File Location**: `recalc.py`, lines 20-76 **Vulnerability Type**: Persistent modification and unsafe trust of a local tool macro **Risk Level**: Medium ### Vulnerable Code ```python def setup_libreoffice_macro(): """Setup LibreOffice macro for recalculation if not already configured""" if platform.system() == 'Darwin': macro_dir = os.path.expanduser('~/Library/Application Support/LibreOffice/4/user/basic/Standard') else: macro_dir = os.path.expanduser('~/.config/libreoffice/4/user/basic/Standard') macro_file = os.path.join(macro_dir, 'Module1.xba') if os.path.exists(macro_file): with open(macro_file, 'r') as f: if 'RecalculateAndSave' in f.read(): return True if not os.path.exists(macro_dir): subprocess.run(['soffice', '--headless', '--terminate_after_init'], capture_output=True, timeout=10) os.makedirs(macro_dir, exist_ok=True) macro_content = '''<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd"> <script:module xmlns:script="http://openoffice.org/2000/script" script:name="Module1" script:language="StarBasic"> Sub RecalculateAndSave() ThisComponent.calculateAll() ThisComponent.store() ThisComponent.close(True) End Sub </script:module>''' try: with open(macro_file, 'w') as f: f.write(macro_content) return True except Exception: return False ``` The resulting global macro is subsequently invoked as follows: ```python cmd = [ 'soffice', '--headless', '--norestore', 'vnd.sun.star.script:Standard.Module1.RecalculateAndSave?language=Basic&location=application', abs_path ] ``` ### Technical Analysis The script installs `Module1.xba` in LibreOffice's persistent per-user profile instead of creating an isol ...[truncated 2692 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Create a unique temporary LibreOffice user profile for every recalculation run. - Launch LibreOffice with an isolated profile, for example through `-env:UserInstallation=file:///path/to/temporary/profile`. - Install the generated macro only inside that temporary profile and remove the profile after processing. - Do not write to or overwrite the user's global `Standard/Module1.xba`. - If persistent installation is unavoidable, validate the complete file contents against the exact expected macro rather than checking for a substring. - Check file ownership and permissions before trusting any existing macro. - Use a uniquely named module and procedure to reduce collisions with user-managed macros. - Back up existing configuration before any modification and restore it after the operation. - Restrict permissions on generated profile files so that other local users cannot modify them. ]]>
