Back to skill

Security audit

Git Sync Daemon

Security checks for vulnerabilities and agentic risk

Overview

This skill is an auto-sync daemon, but its Linux service installer can create a persistent root-running service from a user-writable script path.

Review carefully before installing on Linux. Avoid the sudo systemd installer unless it is changed to run under a dedicated unprivileged user, validate the unit name, and copy scripts to a protected root-owned location. The macOS launchd path and manual run-once mode are more consistent with the stated purpose, but any auto-commit/push daemon should only be used on repositories you intentionally trust for unattended synchronization.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/git_sync_ctl.sh:249
Finding
Persistent systemd service runs a user-modifiable script as root<![CDATA[ ## Vulnerability Details **File Location**: `scripts/git_sync_ctl.sh`, lines 249-285 **Vulnerability Type**: `T05: Unauthorized Access and Privilege Escalation` **Risk Level**: High ### Vulnerable Code ```bash if [[ "$(id -u)" -ne 0 ]]; then echo "install-systemd requires root" >&2 exit 1 fi local unit_path unit_path="/etc/systemd/system/${SYSTEMD_UNIT}" cat > "$unit_path" <<EOF [Unit] Description=Git Sync Daemon After=network-online.target Wants=network-online.target [Service] Type=simple User=$(id -un) Environment=GIT_SYNC_INTERVAL=${INTERVAL} Environment=GIT_SYNC_REPO_FILE=${REPO_FILE} Environment=GIT_SYNC_LOG_FILE=${LOG_FILE} Environment=GIT_SYNC_GIT_TIMEOUT=${TIMEOUT_SECS} ExecStart=/bin/bash ${DAEMON_SCRIPT} Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now "$SYSTEMD_UNIT" ``` ### Technical Analysis The installation command requires execution as root. Consequently, `User=$(id -un)` resolves to `User=root` in the generated systemd unit. The service therefore performs all daemon operations with unrestricted root privileges. The `ExecStart` directive references `git_sync_daemon.sh` directly in the original project directory rather than copying it to a protected, root-owned installation directory. If an unprivileged user can modify that directory or script after installation, systemd will execute attacker-controlled shell code as root on the next service start, restart, or system reboot. The service uses `Restart=always` and is enabled for `multi-user.target`, making the privileged execution persistent. The daemon also invokes Git operations in registered repositories. Git hooks and related helpers reached during those operations inherit the service's root identity, expanding the trust boundary from the daemon script to repository-controlled executable content. Root privileges are not necessary for ordinary Git synchronization. This implementation there ...[truncated 1972 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Run the daemon as a dedicated unprivileged account** - Require an explicit service-user parameter. - Set `User` and `Group` to that account rather than deriving them from the root installer. - Reject `root` as the runtime identity unless the operator explicitly acknowledges a documented exceptional requirement. 2. **Install executable files into a protected location** - Copy the daemon to a root-owned location such as `/usr/local/libexec/git-sync-daemon/`. - Set ownership to `root:root`. - Remove group and world write permissions. - Ensure every parent directory in the executable path is not writable by the service user or other unprivileged users. 3. **Restrict filesystem access** - Grant the service account access only to the configured repositories, state directory, credential material, and log destination. - Do not expose root's home directory, SSH keys, or global Git configuration to the daemon. - Apply suitable systemd controls such as: ```ini NoNewPrivileges=true ProtectSystem=strict ProtectHome=true PrivateTmp=true PrivateDevices=true RestrictSUIDSGID=true LockPersonality=true ReadWritePaths=/explicit/state/path /explicit/repository/path ``` 4. **Constrain repository-controlled execution** - Treat registered repositories as trusted executable content because Git hooks may run during synchronization. - Consider disabling hooks for unattended synchronization with a controlled `core.hooksPath`, where compatible with intended behavior. - Never synchronize repositories controlled by less-trusted users from a more-privileged service account. 5. **Use a safer installation workflow** - Have the privileged installation phase only create protected files and register the unit. - Run repository operations under the same unprivileged identity that owns the repositories and corresponding credentials. - Validate ownership and permissions of the daemon, its parent directories, re ...[truncated 342 chars]
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (23)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
fi

  systemctl disable --now "$SYSTEMD_UNIT" >/dev/null 2>&1 || true
  rm -f "/etc/systemd/system/${SYSTEMD_UNIT}"
  systemctl daemon-reload
  echo "systemd removed: $SYSTEMD_UNIT"
}
Confidence
95% confidence
Finding
The unit filename comes from the environment variable GIT_SYNC_SYSTEMD_UNIT and is interpolated directly into an absolute path for rm -f. Because the script runs as root for systemd uninstall, an attacker or mistaken caller can supply path traversal such as '../../../etc/shadow' and cause deletion of arbitrary root-owned files outside /etc/systemd/system.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
bash scripts/git_sync_ctl.sh init
bash scripts/git_sync_ctl.sh add-repo /path/to/repo
bash scripts/git_sync_ctl.sh run-once
sudo bash scripts/git_sync_ctl.sh install-systemd
bash scripts/git_sync_ctl.sh status
```
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
Service lifecycle:
- macOS install: `bash scripts/git_sync_ctl.sh install-launchd`
- macOS uninstall: `bash scripts/git_sync_ctl.sh uninstall-launchd`
- Linux install: `sudo bash scripts/git_sync_ctl.sh install-systemd`
- Linux uninstall: `sudo bash scripts/git_sync_ctl.sh uninstall-systemd`

## Production hardening checklist
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
Service lifecycle:
- macOS install: `bash scripts/git_sync_ctl.sh install-launchd`
- macOS uninstall: `bash scripts/git_sync_ctl.sh uninstall-launchd`
- Linux install: `sudo bash scripts/git_sync_ctl.sh install-systemd`
- Linux uninstall: `sudo bash scripts/git_sync_ctl.sh uninstall-systemd`

## Production hardening checklist
Confidence
70% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
INTERVAL="${GIT_SYNC_INTERVAL:-60}"
TIMEOUT_SECS="${GIT_SYNC_GIT_TIMEOUT:-45}"
LABEL="${GIT_SYNC_LAUNCHD_LABEL:-com.samwei12.git-sync-daemon}"
PLIST_PATH="${GIT_SYNC_LAUNCHD_PLIST:-$HOME/Library/LaunchAgents/${LABEL}.plist}"
SYSTEMD_UNIT="${GIT_SYNC_SYSTEMD_UNIT:-git-sync-daemon.service}"

trim() {
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.

Session Persistence

Medium
Category
Rogue Agent
Content
INTERVAL="${GIT_SYNC_INTERVAL:-60}"
TIMEOUT_SECS="${GIT_SYNC_GIT_TIMEOUT:-45}"
LABEL="${GIT_SYNC_LAUNCHD_LABEL:-com.samwei12.git-sync-daemon}"
PLIST_PATH="${GIT_SYNC_LAUNCHD_PLIST:-$HOME/Library/LaunchAgents/${LABEL}.plist}"
SYSTEMD_UNIT="${GIT_SYNC_SYSTEMD_UNIT:-git-sync-daemon.service}"

trim() {
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.

Session Persistence

Medium
Category
Rogue Agent
Content
INTERVAL="${GIT_SYNC_INTERVAL:-60}"
TIMEOUT_SECS="${GIT_SYNC_GIT_TIMEOUT:-45}"
LABEL="${GIT_SYNC_LAUNCHD_LABEL:-com.samwei12.git-sync-daemon}"
PLIST_PATH="${GIT_SYNC_LAUNCHD_PLIST:-$HOME/Library/LaunchAgents/${LABEL}.plist}"
SYSTEMD_UNIT="${GIT_SYNC_SYSTEMD_UNIT:-git-sync-daemon.service}"

trim() {
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.

Session Persistence

Medium
Category
Rogue Agent
Content
INTERVAL="${GIT_SYNC_INTERVAL:-60}"
TIMEOUT_SECS="${GIT_SYNC_GIT_TIMEOUT:-45}"
LABEL="${GIT_SYNC_LAUNCHD_LABEL:-com.samwei12.git-sync-daemon}"
PLIST_PATH="${GIT_SYNC_LAUNCHD_PLIST:-$HOME/Library/LaunchAgents/${LABEL}.plist}"
SYSTEMD_UNIT="${GIT_SYNC_SYSTEMD_UNIT:-git-sync-daemon.service}"

trim() {
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.

Session Persistence

Medium
Category
Rogue Agent
Content
INTERVAL="${GIT_SYNC_INTERVAL:-60}"
TIMEOUT_SECS="${GIT_SYNC_GIT_TIMEOUT:-45}"
LABEL="${GIT_SYNC_LAUNCHD_LABEL:-com.samwei12.git-sync-daemon}"
PLIST_PATH="${GIT_SYNC_LAUNCHD_PLIST:-$HOME/Library/LaunchAgents/${LABEL}.plist}"
SYSTEMD_UNIT="${GIT_SYNC_SYSTEMD_UNIT:-git-sync-daemon.service}"

trim() {
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.

Session Persistence

Medium
Category
Rogue Agent
Content
INTERVAL="${GIT_SYNC_INTERVAL:-60}"
TIMEOUT_SECS="${GIT_SYNC_GIT_TIMEOUT:-45}"
LABEL="${GIT_SYNC_LAUNCHD_LABEL:-com.samwei12.git-sync-daemon}"
PLIST_PATH="${GIT_SYNC_LAUNCHD_PLIST:-$HOME/Library/LaunchAgents/${LABEL}.plist}"
SYSTEMD_UNIT="${GIT_SYNC_SYSTEMD_UNIT:-git-sync-daemon.service}"

trim() {
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.

Session Persistence

Medium
Category
Rogue Agent
Content
INTERVAL="${GIT_SYNC_INTERVAL:-60}"
TIMEOUT_SECS="${GIT_SYNC_GIT_TIMEOUT:-45}"
LABEL="${GIT_SYNC_LAUNCHD_LABEL:-com.samwei12.git-sync-daemon}"
PLIST_PATH="${GIT_SYNC_LAUNCHD_PLIST:-$HOME/Library/LaunchAgents/${LABEL}.plist}"
SYSTEMD_UNIT="${GIT_SYNC_SYSTEMD_UNIT:-git-sync-daemon.service}"

trim() {
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.

Session Persistence

Medium
Category
Rogue Agent
Content
INTERVAL="${GIT_SYNC_INTERVAL:-60}"
TIMEOUT_SECS="${GIT_SYNC_GIT_TIMEOUT:-45}"
LABEL="${GIT_SYNC_LAUNCHD_LABEL:-com.samwei12.git-sync-daemon}"
PLIST_PATH="${GIT_SYNC_LAUNCHD_PLIST:-$HOME/Library/LaunchAgents/${LABEL}.plist}"
SYSTEMD_UNIT="${GIT_SYNC_SYSTEMD_UNIT:-git-sync-daemon.service}"

trim() {
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.

Session Persistence

Medium
Category
Rogue Agent
Content
INTERVAL="${GIT_SYNC_INTERVAL:-60}"
TIMEOUT_SECS="${GIT_SYNC_GIT_TIMEOUT:-45}"
LABEL="${GIT_SYNC_LAUNCHD_LABEL:-com.samwei12.git-sync-daemon}"
PLIST_PATH="${GIT_SYNC_LAUNCHD_PLIST:-$HOME/Library/LaunchAgents/${LABEL}.plist}"
SYSTEMD_UNIT="${GIT_SYNC_SYSTEMD_UNIT:-git-sync-daemon.service}"

trim() {
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.

Session Persistence

Medium
Category
Rogue Agent
Content
INTERVAL="${GIT_SYNC_INTERVAL:-60}"
TIMEOUT_SECS="${GIT_SYNC_GIT_TIMEOUT:-45}"
LABEL="${GIT_SYNC_LAUNCHD_LABEL:-com.samwei12.git-sync-daemon}"
PLIST_PATH="${GIT_SYNC_LAUNCHD_PLIST:-$HOME/Library/LaunchAgents/${LABEL}.plist}"
SYSTEMD_UNIT="${GIT_SYNC_SYSTEMD_UNIT:-git-sync-daemon.service}"

trim() {
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.

Session Persistence

Medium
Category
Rogue Agent
Content
INTERVAL="${GIT_SYNC_INTERVAL:-60}"
TIMEOUT_SECS="${GIT_SYNC_GIT_TIMEOUT:-45}"
LABEL="${GIT_SYNC_LAUNCHD_LABEL:-com.samwei12.git-sync-daemon}"
PLIST_PATH="${GIT_SYNC_LAUNCHD_PLIST:-$HOME/Library/LaunchAgents/${LABEL}.plist}"
SYSTEMD_UNIT="${GIT_SYNC_SYSTEMD_UNIT:-git-sync-daemon.service}"

trim() {
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.

Session Persistence

Medium
Category
Rogue Agent
Content
INTERVAL="${GIT_SYNC_INTERVAL:-60}"
TIMEOUT_SECS="${GIT_SYNC_GIT_TIMEOUT:-45}"
LABEL="${GIT_SYNC_LAUNCHD_LABEL:-com.samwei12.git-sync-daemon}"
PLIST_PATH="${GIT_SYNC_LAUNCHD_PLIST:-$HOME/Library/LaunchAgents/${LABEL}.plist}"
SYSTEMD_UNIT="${GIT_SYNC_SYSTEMD_UNIT:-git-sync-daemon.service}"

trim() {
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.

Session Persistence

Medium
Category
Rogue Agent
Content
list-repos
  run-once
  status
  install-launchd
  uninstall-launchd
  install-systemd
  uninstall-systemd
Confidence
80% 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.

Session Persistence

Medium
Category
Rogue Agent
Content
run-once
  status
  install-launchd
  uninstall-launchd
  install-systemd
  uninstall-systemd
EOF
Confidence
80% 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.

Session Persistence

Medium
Category
Rogue Agent
Content
run-once
  status
  install-launchd
  uninstall-launchd
  install-systemd
  uninstall-systemd
EOF
Confidence
80% 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.

Session Persistence

Medium
Category
Rogue Agent
Content
status
  install-launchd
  uninstall-launchd
  install-systemd
  uninstall-systemd
EOF
}
Confidence
80% 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.

Session Persistence

Medium
Category
Rogue Agent
Content
uid="$(id -u)"
  launchctl bootout "gui/${uid}" "$PLIST_PATH" >/dev/null 2>&1 || true
  launchctl bootstrap "gui/${uid}" "$PLIST_PATH"
  launchctl enable "gui/${uid}/${LABEL}" >/dev/null 2>&1 || true
  launchctl kickstart -k "gui/${uid}/${LABEL}"
  echo "launchd installed: $LABEL"
}
Confidence
80% 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.

Session Persistence

Medium
Category
Rogue Agent
Content
EOF

  systemctl daemon-reload
  systemctl enable --now "$SYSTEMD_UNIT"
  echo "systemd installed: $SYSTEMD_UNIT"
}
Confidence
80% 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.

Session Persistence

Medium
Category
Rogue Agent
Content
systemctl daemon-reload
  systemctl enable --now "$SYSTEMD_UNIT"
  echo "systemd installed: $SYSTEMD_UNIT"
}

cmd_uninstall_systemd() {
Confidence
80% 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.

Static analysis

No suspicious patterns detected.