Back to skill

Security audit

Machine Config Migrator

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed machine-configuration migration skill, but applying bundles can overwrite local files and optionally execute plugin installers, so it should be reviewed before use.

Use this only with bundles you created and trust. Run --dry-run first, prefer --plugin-mode suggest or none, review the manifest and file list before applying, and avoid sharing generated bundles because shell, Git, editor, Alfred, and SSH config can contain sensitive hostnames, tokens, or workflow data.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/apply_config_bundle.py:27
Finding

Archive extraction permits path traversal and unsafe link handling

Content
View full analysis
None: destination = destination.resolve() for member in archive.getmembers(): member_path = (destination / member.name).resolve() if not str(member_path).startswith(str(destination)): raise ValueError(f"Unsafe tar member path: {member.name}") archive.extractall(path=destination) ``` ### Technical Analysis The extraction guard uses a string-prefix comparison to determine whether a member remains under the extraction directory. String prefixes do not represent filesystem ancestry. For example, if the extraction directory is `/tmp/bundle`, a resolved path such as `/tmp/bundle-evil/file` still begins with the string `/tmp/bundle`. The implementation also does not reject or validate symbolic links and hard links. A crafted archive can contain a link whose target points outside the extraction directory and subsequent members that write through that link. Calling `archive.extractall()` after only validating member names does not reliably contain those link-based writes. The bundle is therefore treated as trusted filesystem input even though it can originate from another machine or an untrusted transfer channel. ### Attack Path 1. An attacker creates a tar archive containing traversal paths or archive links that resolve outside the intended temporary extraction directory. 2. The attacker supplies the archive as a migration bundle. 3. The user runs `apply_config_bundle.py --bundle `. 4. The flawed string-prefix check accepts a path that is not actually a descendant of the extraction directory, or fails to account for a malicious link target. 5. `archive.extractall()` writes an archive member outside the temporary directory. 6. Files accessible t ...[truncated 538 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/apply_config_bundle.py:232
Finding

Manifest-controlled paths can escape target and backup directories

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/apply_config_bundle.py:273
Finding

Plugin mode executes code and configuration restored from an untrusted bundle

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/apply_config_bundle.py:87
Finding

Plugin installers retrieve mutable, unpinned remote dependencies

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (13)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

Using shell=True is a classic command-execution hazard because the shell parses metacharacters, expansions, and command chaining. Here it is especially risky because the tool operates on imported configuration/manifest data and runs in the user's home directory, so any future expansion of manifest-controlled values or environment manipulation could lead to unintended command execution on the destination machine.

Content

Scanner excerpt · scripts/apply_config_bundle.py (reported line 277)May include surrounding context.

python
if args.plugin_mode == "run" and not args.dry_run:
            print("Running plugin commands...")
            for command in plugin_commands:
                result = subprocess.run(
                    command,
                    shell=True,
                    cwd=target_home,

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/collect_config_bundle.py (reported line 53)May include surrounding context.

python
],
    "ssh": [
        ".ssh/config",
        ".ssh/known_hosts",
    ],
}

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs use of local scripts that read files, write configuration, and execute shell-level actions, but it declares no explicit tool scope or permission boundaries. In an agent environment, this can allow the skill to operate with broader-than-expected capabilities, increasing the chance of unintended file modification, unsafe command execution, or access to sensitive user data during migration.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The plugin-command builder does more than provide guidance: it prepares commands for git clone, vim/neovim sync, and Emacs package installation, enabling live modification of the target environment and network retrieval. For a migration/apply tool, this broadens behavior beyond justified file restoration and creates a pathway for unintended package installation based on imported configuration state.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This skill goes beyond copying configuration files and can actively execute shell commands to install or sync plugins. In the context of applying a config bundle from another machine, the bundle should be treated as untrusted input; coupling restore operations with live command execution increases the blast radius from file overwrite to code execution and network access.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
97% confidence
Finding

The code executes plugin commands with subprocess.run(..., shell=True), which turns command strings into shell-interpreted input. While the current commands are mostly hardcoded, some are assembled from manifest-derived plugin names and environment-variable expansions, and the feature performs network-fetching/install actions on the target machine; this creates unnecessary command-execution risk in a migration tool handling potentially untrusted bundles.

Content

Scanner excerpt · scripts/apply_config_bundle.py (reported line 277)May include surrounding context.

python
if args.plugin_mode == "run" and not args.dry_run:
            print("Running plugin commands...")
            for command in plugin_commands:
                result = subprocess.run(
                    command,
                    shell=True,
                    cwd=target_home,

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/collect_config_bundle.py (reported line 8)May include surrounding context.

python
import argparse
import json
import plistlib
import re
import shutil
import tarfile

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/collect_config_bundle.py (reported line 198)May include surrounding context.

python
import argparse
import json
import plistlib
import re
import shutil
import tarfile

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/collect_config_bundle.py (reported line 203)May include surrounding context.

python
import argparse
import json
import plistlib
import re
import shutil
import tarfile

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/collect_config_bundle.py (reported line 204)May include surrounding context.

python
import argparse
import json
import plistlib
import re
import shutil
import tarfile

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · scripts/collect_config_bundle.py (reported line 205)May include surrounding context.

python
import argparse
import json
import plistlib
import re
import shutil
import tarfile

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This copy routine packages selected configuration files verbatim into a tar.gz archive, and those files can contain secrets such as SSH host aliases, tokens in git or shell configs, API keys in editor settings, and private workflow data. The script does not present an explicit warning, preview, or confirmation about sensitive contents, which increases the chance of accidental secret disclosure when users share or store the bundle.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest stores the full absolute source home path, which is not needed to restore dotfiles and can reveal the original username and host-specific directory structure to anyone who receives the bundle. In this migration context the bundle is meant to be portable, so retaining extra host-identifying metadata unnecessarily expands the exposure surface.

Content

No source excerpt is available for this finding.