Back to skill

Security audit

session-sync

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a real session-migration tool, but it needs Review because it can modify many AI-agent data stores and its install and dashboard behavior are broader than its top-level description consistently discloses.

Install only if you intentionally want a broad cross-agent migration tool that can read private chat histories and write or restore data into multiple local agent stores. Avoid the pipe-to-shell installer path unless the source is pinned and verified; prefer a reviewed, versioned package. Keep target apps closed before write/restore operations, run dry-runs first, and do not leave the Web UI running around untrusted local processes or browser content.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T03 · Remote Payload Retrieval and Execution

Error
Location
install.sh:5
Finding
Recommended installers execute mutable remote code without integrity verification<![CDATA[ ## Vulnerability Details **File Location**: `install.sh:5,18,61-74`; `install.ps1:3,38,54-70`; `README_EN.md:10-20`; `README.md:24-30` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: Critical ### Vulnerable Code ```bash # Online installation instruction: curl -fsSL https://raw.githubusercontent.com/Chendestiny/agent-session-sync/main/install.sh | bash ``` ```powershell # Online installation instruction: irm https://raw.githubusercontent.com/Chendestiny/agent-session-sync/main/install.ps1 | iex ``` The Unix installer then downloads another mutable artifact: ```bash DEST="$HOME/.agents/skills/session-sync" REPO_ZIP='https://github.com/Chendestiny/agent-session-sync/archive/refs/heads/main.zip' PREFIX="${ASS_GH_PREFIX:-}" # ... dl_ok=0 if command -v curl >/dev/null 2>&1; then curl -fsSL --retry 3 -o "$WORK/ass.zip" "${PREFIX}${REPO_ZIP}" 2>/dev/null && dl_ok=1 if [ "$dl_ok" -ne 1 ]; then curl -fsSL --retry 3 --ssl-no-revoke -o "$WORK/ass.zip" "${PREFIX}${REPO_ZIP}" 2>/dev/null && dl_ok=1 fi fi if [ "$dl_ok" -ne 1 ] && command -v wget >/dev/null 2>&1; then wget -q -O "$WORK/ass.zip" "${PREFIX}${REPO_ZIP}" && dl_ok=1 fi [ "$dl_ok" -eq 1 ] || die 'download failed' "$PY" -m zipfile -e "$WORK/ass.zip" "$WORK/unzip/" ``` The Windows installer follows the same model: ```powershell $prefix = [string]$env:ASS_GH_PREFIX $url = 'https://github.com/Chendestiny/agent-session-sync/archive/refs/heads/main.zip' try { Invoke-WebRequest -Uri "$prefix$url" -OutFile $zip -UseBasicParsing $dlOk = $true } catch { } if (-not $dlOk -and (Get-Command curl.exe -ErrorAction SilentlyContinue)) { & curl.exe -fsSL --retry 3 --ssl-no-revoke -o "$zip" "$prefix$url" if ($LASTEXITCODE -eq 0) { $dlOk = $true } } Expand-Archive -Path $zip -DestinationPath $tmpDir -Force ``` ### Technical Analysis The documented installation commands pipe content from a mutable GitHub `main` branch directly into a command in ...[truncated 2138 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove all `curl | bash` and `Invoke-RestMethod | Invoke-Expression` installation recommendations. 2. Publish versioned release artifacts rather than downloading the mutable `main` branch. 3. Pin downloads to an immutable release tag and commit. 4. Publish SHA-256 or stronger checksums through a separately protected channel. 5. Verify the checksum before extraction or execution, and abort on any mismatch. 6. Prefer signed release artifacts and verify signatures against a documented public key. 7. Require users to download, inspect, and execute the installer as separate steps. 8. Do not permit arbitrary mirror prefixes unless mirrors are explicitly allowlisted and provide equivalent integrity verification. 9. Avoid `--ssl-no-revoke`; fix proxy trust configuration rather than weakening transport validation. 10. Display the exact version, commit, origin, and verified digest before modifying Skill directories or command shims. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
install.ps1:125
Finding
Windows installer downloads and executes an unverified Python bootstrap script<![CDATA[ ## Vulnerability Details **File Location**: `install.ps1:125-145` **Vulnerability Type**: Remote payload retrieval and execution **Risk Level**: High ### Vulnerable Code ```powershell $pyver = '3.11.9' $pyzip = Join-Path $env:TEMP 'ass-py-embed.zip' $mirrors = @("https://www.python.org/ftp/python/$pyver/python-$pyver-embed-amd64.zip", "https://registry.npmmirror.com/-/binary/python/$pyver/python-$pyver-embed-amd64.zip") $done = $false foreach ($u in $mirrors) { try { Invoke-WebRequest $u -OutFile $pyzip; $done = $true; break } catch {} } if (-not $done) { throw 'Failed to download embedded Python (python.org and npmmirror both failed)' } New-Item -ItemType Directory -Path $rt -Force | Out-Null Expand-Archive $pyzip -DestinationPath $rt -Force Remove-Item $pyzip -Force -ErrorAction SilentlyContinue $gp = Join-Path $env:TEMP 'ass-get-pip.py' Invoke-WebRequest 'https://bootstrap.pypa.io/get-pip.py' -OutFile $gp if ((Invoke-QuietNative $embedded @($gp, '--no-warn-script-location')) -ne 0) { throw 'get-pip failed inside embedded runtime' } ``` ### Technical Analysis The installer retrieves `get-pip.py` and executes it with the newly installed Python interpreter without verifying its digest or signature. The URL does not identify an immutable artifact version in the installer. The embedded Python archive is versioned, but it is likewise accepted without checksum or signature validation and may be retrieved from a third-party mirror. HTTPS protects transport under normal conditions but does not establish artifact immutability or protect against source, mirror, certificate-authority, or endpoint compromise. Downloading and running a bootstrap program is more dangerous than retrieving passive data because the response obtains immediate code-execution capability. ### Attack Path 1. An attacker compromises the bootstrap host, third-party mirror, delivery path, or trusted certificate infrastructure. 2. The installer receives a modif ...[truncated 862 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Avoid downloading and executing `get-pip.py` at installation time. 2. Bundle a reviewed, versioned bootstrap artifact where licensing permits, or use a package-management mechanism with authenticated metadata. 3. Pin the embedded Python archive and bootstrap script to exact versions. 4. Store expected cryptographic hashes in the installer and verify every downloaded artifact before extraction or execution. 5. Prefer signed Python release artifacts and verify the publisher signature. 6. Remove the unverified third-party mirror fallback or enforce identical pinned hashes for every mirror. 7. Download to a uniquely named, access-restricted temporary directory rather than predictable shared temporary filenames. 8. Abort installation if verification cannot be completed; do not silently continue through alternate untrusted sources. ]]>

T08 · Insecure Dependencies

Warning
Location
sync.py:2243
Finding
Installer and doctor command automatically install an unpinned dependency from external indexes<![CDATA[ ## Vulnerability Details **File Location**: `install.ps1:142-165`; `sync.py:2243-2250` **Vulnerability Type**: Insecure dependency installation **Risk Level**: Medium ### Vulnerable Code ```powershell if ((Invoke-QuietNative $embedded @('-m','pip','install','zstandard','--no-warn-script-location')) -ne 0) { if ((Invoke-QuietNative $embedded @( '-m','pip','install','zstandard','--no-warn-script-location', '-i','https://mirrors.aliyun.com/pypi/simple/' )) -ne 0) { Write-Host ' [!] zstandard install into runtime failed; rerun installer or run: ass doctor' } } ``` ```powershell if ((Invoke-QuietNative $pyExe @('-c','import zstandard')) -ne 0) { if ((Invoke-QuietNative $pyExe @( '-m','pip','install','zstandard','--no-warn-script-location' )) -eq 0) { Write-Host ' Installed zstandard into the detected python' } } ``` The doctor command also performs an automatic unpinned installation: ```python try: import zstandard # noqa: F401 print(" ✔ installed") except ImportError: print(" missing → attempting automatic installation ...") r = subprocess.run( [sys.executable, "-m", "pip", "install", "zstandard"], capture_output=True, text=True, ) ``` ### Technical Analysis The package name is installed without an exact version constraint and without hash verification. Consequently, the effective package contents can change after the Skill has been reviewed. The Windows installer can additionally retry against a separate package mirror. This expands the supply-chain trust boundary and may result in different artifacts or metadata depending on which index responds. The `doctor` command is described as a health and self-repair operation, but it can modify the active Python environment by installing a package. If the active interpreter belongs to another tool or shared environment, this exceeds the minimum read-only diagnostics expected from a h ...[truncated 939 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin `zstandard` to a specifically audited version. 2. Use a hash-locked requirements file, for example with `--require-hashes`. 3. Validate wheels against published checksums or trusted signed metadata. 4. Remove silent fallback to unrelated package indexes, or enforce an explicit allowlist and identical artifact hashes. 5. Require explicit user confirmation before `doctor` installs or changes dependencies. 6. Separate diagnostic behavior from repair behavior, such as `doctor --fix-dependencies`. 7. Install dependencies into a dedicated virtual environment owned by this Skill rather than modifying an arbitrary detected interpreter. 8. Report the selected index, package version, artifact filename, and verified hash before installation. ]]>

T05 · Unauthorized Access and Privilege Escalation

Error
Location
agentsync/webui/__init__.py:425
Finding
Unauthenticated loopback Web UI exposes state-changing backup, restore, deletion, and path-binding APIs<![CDATA[ ## Vulnerability Details **File Location**: `agentsync/webui/__init__.py:425-505,511-522` **Vulnerability Type**: Missing authentication and cross-origin request protection **Risk Level**: High ### Vulnerable Code The request handler performs state-changing operations without authentication, authorization, CSRF tokens, origin checks, host validation, or content-type validation: ```python def do_POST(self) -> None: u = urlparse(self.path) if u.path == "/api/bind-path": try: n = int(self.headers.get("Content-Length") or 0) body = json.loads(self.rfile.read(n).decode("utf-8")) if n else {} out = paths.bind_override( str(body.get("source", "")), str(body.get("path", "")), ) return self._json(out, 200 if out.get("ok") else 400) except Exception as e: return self._json( {"ok": False, "detail": f"{type(e).__name__}: {e}"}, 400, ) if u.path == "/api/backup": try: n = int(self.headers.get("Content-Length") or 0) body = json.loads(self.rfile.read(n).decode("utf-8")) if n else {} from .. import backup as backup_mod src = str(body.get("source", "")) if src not in SOURCES: return self._json( {"ok": False, "detail": f"unknown source: {src}"}, 400, ) raw_ids = body.get("ids") or "" ids = {i for i in str(raw_ids).split(",") if i} or None if src in backup_mod.RAW_SOURCES: rows = backup_mod.do_raw_backup([src], paths.detect()) else: rows = backup_mod.do_backup( [src], paths.detect(), with_imports=bool(body.get("with_imports")), ids=ids, ) return self._json({"ok": True, ...[truncated 4944 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Generate a cryptographically random per-launch authentication token. 2. Require the token in an authorization header for every API request, especially all POST requests. 3. Generate and validate a separate anti-CSRF token for browser actions. 4. Validate the `Origin` header against the exact dashboard origin. 5. Validate the `Host` header against the expected loopback address and active port to mitigate DNS rebinding. 6. Require `Content-Type: application/json` and reject other content types. 7. Implement restrictive CORS behavior and do not reflect arbitrary origins. 8. Require explicit interactive confirmation immediately before restore and deletion operations. 9. Consider moving restore and deletion back to the CLI, where existing dry-run and human-confirmation controls can be applied. 10. Refuse restoration while the target application is running. 11. Separate read-only and write-capable server modes, with read-only as the default. 12. Correct the dashboard message and documentation so that they do not describe the service as read-only while write endpoints are enabled. 13. Add security headers such as a restrictive Content Security Policy and `X-Content-Type-Options: nosniff`. 14. Rate-limit sensitive endpoints and log state-changing operations with source, target, timestamp, and result. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (43)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
print("  ✔ 已安装")
    except ImportError:
        print("  缺失 → 尝试自动安装 ...")
        r = subprocess.run([sys.executable, "-m", "pip", "install", "zstandard"],
                           capture_output=True, text=True)
        if r.returncode == 0:
            fixes.append("已自动安装 zstandard")
Confidence
90% confidence
Finding
The doctor command automatically runs pip install zstandard, causing network access and local environment modification that exceed the advertised scope of a session-sync utility. In an agent skill context, silent dependency installation can violate user expectations, alter the host Python environment, and become dangerous if package sources or interpreter context are untrusted.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill advertises and documents broad capabilities including shell execution, file reads/writes across user directories, local web serving, and some network-adjacent behavior, but does not declare permissions up front. That weakens informed consent and reviewability: an agent or user may invoke a skill believing it is limited to one-way session import when it can also modify many local stores and launch services.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The manifest and summary frame the tool as a one-way sync into dsh plus archive export, but the documented behavior includes reverse writes to many other agents, canonical-store pull/push, backup/restore, metadata rewrites, pruning, and a dashboard server. This mismatch is dangerous because it can mislead operators and upstream policy engines about the true blast radius, enabling unintended data propagation, deletion, or corruption across multiple applications.

Description-Behavior Mismatch

High
Confidence
94% confidence
Finding
The skill metadata describes a one-way sync into dsh, but the README explicitly claims write support to 10 targets. This scope mismatch is dangerous because it changes the trust boundary: a user or agent expecting import-only behavior may permit operations that actually modify multiple external agent stores, increasing the risk of unintended data propagation or tampering.

Description-Behavior Mismatch

Medium
Confidence
90% confidence
Finding
The installer is documented as downloading code, registering global commands, and bridging into other agents' directories, which goes beyond a narrowly scoped session-sync tool. This is risky because it introduces persistence, environment modification, and cross-tool integration behaviors that users may not expect from the stated purpose, expanding the attack surface.

Context-Inappropriate Capability

Medium
Confidence
84% confidence
Finding
Advertising 'self-repair' and 'skill bridges' implies the tool can alter dependencies, stores, baselines, and integrations across multiple agents. In the context of a session-sync skill, such broad maintenance capabilities are more dangerous because they normalize privileged environment changes unrelated to simple import/export behavior.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The top-level overview claims one-way synchronization into dsh, yet the command list exposes broad reverse-write capabilities to codex, claude, hermes, opencode, workbuddy, minimax, pi, gemini, and cline. In a security review context, that discrepancy is itself a risky form of deceptive interface because users may approve use under a false assumption that no outbound writes to other agent stores will occur.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The file explicitly states the direction is 'only write into dsh' while elsewhere documenting many non-dsh write targets. Contradictory safety-critical documentation increases the chance of operator error, accidental exfiltration of chat histories into unintended apps, and corruption of multiple agents' local state because defenders cannot rely on the declared data-flow boundary.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
The restore path calls `syncstate.mark(s_root, [source])` after replaying snapshot data, which advances the target-side sync watermark. That directly contradicts the module docstring claiming backup/restore does not affect incremental baselines, and can cause future sync operations to skip data or treat a restored state as already synchronized. In a session-migration tool, this can silently corrupt synchronization semantics and lead to data loss or incomplete imports.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The code directly opens and mutates Codex's internal SQLite state database, deleting and reinserting rows in the threads table based on generated session metadata. Even if intended for interoperability, modifying another tool's internal state store can corrupt indexing, create inconsistent state versus on-disk rollouts, and make imported sessions appear trusted/native without validation. In this skill's context, that is more dangerous because the stated goal is cross-agent session migration into dsh/Codex, so the behavior is expected to run on real user state under ~/.codex and affects resume-visible data, not just an isolated export file.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The file implements prune and hard-delete behavior that goes beyond the stated sync/import/archive purpose, including moving session directories to trash, hard deletion, and persistent tombstoning to block future re-import. In a session-sync skill, destructive state-changing behavior materially increases the blast radius: a user expecting import/archive could lose conversation history or have sessions silently suppressed from reappearing.

Description-Behavior Mismatch

High
Confidence
95% confidence
Finding
The module-level documentation explicitly presents the dashboard as read-only, but the code exposes mutating HTTP endpoints for backup, restore, snapshot deletion, and path binding. This mismatch is dangerous because users or integrators may trust the service as safe to leave running locally, while any process able to reach 127.0.0.1 can trigger destructive local actions against session stores and backups.

Intent-Code Divergence

High
Confidence
96% confidence
Finding
The inline documentation claims that only directory-binding POST routes exist, yet the handler implements additional state-changing endpoints including backup, restore, and snapshot deletion. Security-relevant documentation drift like this increases operator error and can directly enable misuse of dangerous functionality that users were told did not exist.

Intent-Code Divergence

Medium
Confidence
90% confidence
Finding
The startup banner announces the dashboard as '只读' (read-only), while the server in fact supports multiple mutating POST actions. This can cause users to make unsafe assumptions about exposure and trust, especially in a localhost service that a browser or local malware could reach without further authentication.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The modal renderer passes an arbitrary `html` string directly into `innerHTML`, which creates a DOM-based XSS sink. If any part of that string can be influenced by imported session content, agent output, or other untrusted data, scriptable markup or event handlers could execute in the browser, compromising the Web UI and any accessible session data.

Description-Behavior Mismatch

Medium
Confidence
85% confidence
Finding
The file is explicitly marked deprecated and 'do not call', yet it still contains complete, callable logic to write directly into a live zcode SQLite database. Retaining dangerous dormant functionality increases the chance of accidental invocation, unintended wiring, or misuse by another component, especially in an agent skill that performs cross-session migration and archive operations.

Intent-Code Divergence

Medium
Confidence
86% confidence
Finding
The docstring claims zcode is 'output-only' and the module should no longer be used, but executable functions still plan and apply database imports. This mismatch is dangerous because operators and maintainers may rely on documentation for safety assumptions while the runtime still exposes destructive database modification behavior.

Description-Behavior Mismatch

Medium
Confidence
92% confidence
Finding
The installer enumerates multiple third-party agent skill directories and creates junctions into them automatically, extending the tool's reach well beyond the stated one-way sync into dsh. This broad cross-agent propagation increases the blast radius of any future bug or compromise in the skill, and users may not realize they are modifying several other agent environments at once.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
This code downloads an embedded Python runtime, get-pip.py, and Python packages from network sources during installation, then executes them locally. That creates a supply-chain risk: a compromised mirror, TLS-intercepting proxy, or upstream artifact could result in arbitrary code execution under the user's account, and the behavior is more dangerous because it is automatic and not tightly pinned or integrity-verified.

Description-Behavior Mismatch

Low
Confidence
88% confidence
Finding
The installer writes executable shims into ~/.local/bin and may overwrite existing commands named session-sync or ass. That expands the tool’s footprint beyond just placing a skill directory and can cause command hijacking, unexpected execution paths, or collisions with existing user tooling.

Description-Behavior Mismatch

High
Confidence
99% confidence
Finding
The top-level description claims one-way sync to dsh and Markdown archival, but the CLI can write into many other agents and even mutate live agent stores. This mismatch is dangerous because users or higher-level agents may grant trust based on the narrow description while the tool actually has broad write capabilities across multiple local applications.

Description-Behavior Mismatch

Medium
Confidence
86% confidence
Finding
The skill metadata omits that the script can launch a local web server and browser-facing dashboard. Undisclosed network-listening behavior increases risk because operators may invoke the tool expecting only file synchronization, while it actually opens a service endpoint that exposes session metadata and export APIs.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
Backup/restore and raw snapshot operations are materially more sensitive than simple sync because they can copy or overwrite full agent databases in place. Hiding these capabilities from the manifest weakens informed consent and could lead an orchestrating agent or user to run destructive operations under a misleadingly narrow trust model.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
Auto-installing packages via pip is outside the narrow purpose of session synchronization and creates unnecessary supply-chain and environment-modification risk. In an agent-executed setting, this can unexpectedly change the host runtime, pull code from package indexes, and make the skill capable of actions users did not authorize.

Context-Inappropriate Capability

Medium
Confidence
91% confidence
Finding
The doctor command creates global command shims and per-agent skill bridge links across many application directories, extending persistence and reach beyond session sync. This broad filesystem modification is risky because it can affect other tools' behavior, survive beyond the current run, and is not justified by the stated core function.

Static analysis

No suspicious patterns detected.