Back to skill

Security audit

Gateway Restore

Security checks for vulnerabilities and agentic risk

Overview

This skill performs a legitimate gateway restore function, but it can make live configuration changes and restart services from broad natural-language triggers without clear confirmation or operator control.

Review this skill before installing on any active gateway host. Use it only where the operator expects live Slack or Discord gateway configuration changes and service restarts, and prefer adding explicit confirmation, a non-detached execution path with status, a secure temporary log path, and corrected rollback handling before production use.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/gateway-restore.sh:67
Finding

Errexit Prevents the Intended Configuration Rollback

Content
View full analysis

Vulnerability Details

File Location: scripts/gateway-restore.sh, lines 8 and 67-79
Vulnerability Type: Improper error handling and rollback failure
Risk Level: High

Vulnerable Code:

bash
set -euo pipefail
bash
bash "$RESTART_SCRIPT" "restore to known-good config"
EXIT=$?

if [ $EXIT -eq 0 ]; then
    log "✅ $GATEWAY gateway restored and healthy"
elif [ $EXIT -eq 1 ]; then
    log "⚠️  Restart failed — rolled back to previous config"
    cp "$CURRENT_BACKUP" "$CONFIG"
else
    err "CRITICAL: Restart + rollback failed — check $GATEWAY gateway manually"
fi

exit $EXIT

Technical Analysis

The script enables Bash's errexit behavior with set -e. The restart command is then executed as a standalone command before its exit status is captured.

If "$RESTART_SCRIPT" returns any nonzero exit status, Bash terminates gateway-restore.sh immediately. Consequently, EXIT=$? and the subsequent conditional rollback logic are not executed. In particular, the command intended to restore the pre-operation configuration:

bash
cp "$CURRENT_BACKUP" "$CONFIG"

is unreachable under the ordinary restart-failure condition.

This behavior contradicts the Skill's documented guarantee that a failed restart automatically restores the previous configuration. The else branch also does not perform a rollback despite reporting that both restart and rollback failed; no rollback has actually been attempted by that branch.

Attack Path

  1. A restore operation copies the current configuration to a timestamped backup.
  2. The known-good configuration is copied over the live configuration.
  3. The fixed restart script encounters an operational error or is caused to return a nonzero status.
  4. Because set -e is active, gateway-restore.sh exits at the failed bash "$RESTART_SCRIPT" command.
  5. The exit status is never captured and the rollback branch is never entered.

...[truncated 943 chars]

Remediation
View remediation

Remediation Suggestions

Run the restart command in a conditional context where set -e does not terminate the script before its status is handled:

bash
if bash "$RESTART_SCRIPT" "restore to known-good config"; then
    log "✅ $GATEWAY gateway restored and healthy"
    exit 0
else
    restart_exit=$?
    err "Restart failed with status $restart_exit; restoring previous config"

    if cp -- "$CURRENT_BACKUP" "$CONFIG"; then
        log "Previous $GATEWAY configuration restored"
    else
        err "CRITICAL: Failed to restore previous configuration"
        exit 2
    fi

    exit "$restart_exit"
fi

Additional hardening should include:

  • Attempt rollback for every nonzero restart status rather than only exit code 1.
  • Report restart failure and rollback failure as separate events.
  • Validate that the restored configuration matches the backup before reporting rollback success.
  • Define and document consistent exit codes for successful restart, successful rollback after restart failure, and failed rollback.
  • Add automated tests in which the restart script returns 1, 2, and other nonzero statuses.
  • Consider using an ERR trap only if it can guarantee safe, idempotent rollback without obscuring the primary failure.

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:50
Finding

Predictable Shared Temporary Log Allows Symlink-Based File Truncation

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 50-51
Vulnerability Type: Unsafe predictable temporary-file handling
Risk Level: Medium

Vulnerable Code:

bash
setsid bash /home/swabby/repos/swabby-brain/skills/gateway-restore/scripts/gateway-restore.sh [slack|discord] [--tag-current] > /tmp/restore-output.log 2>&1 &
sleep 2 && cat /tmp/restore-output.log

Technical Analysis

The documented natural-language invocation redirects output to a fixed filename in the shared /tmp directory. Shell redirection opens the destination with truncation before starting the restore process.

The workflow neither creates the log atomically nor verifies that the path is a regular file owned by the invoking user. On systems where another local user can create /tmp/restore-output.log, that user can place a symbolic link at this predictable path. When the restore workflow is invoked, the shell follows the symbolic link and truncates its target with the privileges of the Skill operator.

The fixed path also introduces a race between concurrent invocations. One process can truncate or replace another process's output, and the delayed cat command can read output produced by a different invocation or a replacement file.

Attack Path

  1. A local attacker predicts the documented path /tmp/restore-output.log.
  2. Before the operator invokes the Skill, the attacker creates that path as a symbolic link to a file writable by the operator.
  3. The operator triggers a natural-language gateway restore.
  4. The shell processes > /tmp/restore-output.log using the operator's permissions.
  5. The symbolic link is followed and the target file is opened with truncation.
  6. Restore-script output is written to the unintended target.
  7. Depending on the selected target, the operator may suffer data loss, corrupted user configuration, or disruption of another user-level process.

An alternativ ...[truncated 790 chars]

Remediation
View remediation

Remediation Suggestions

Create a unique temporary file atomically with mktemp, apply restrictive permissions, and remove it after use:

bash
log_file="$(mktemp "${TMPDIR:-/tmp}/gateway-restore.XXXXXXXX.log")" || exit 1
chmod 600 "$log_file"
trap 'rm -f -- "$log_file"' EXIT HUP INT TERM

setsid bash /home/swabby/repos/swabby-brain/skills/gateway-restore/scripts/gateway-restore.sh \
    slack >"$log_file" 2>&1 &

restore_pid=$!
sleep 2
cat -- "$log_file"

Further hardening should include:

  • Prefer a private runtime directory owned by the invoking user, such as a securely created subdirectory under ${XDG_RUNTIME_DIR}.
  • Never reuse a globally predictable log filename.
  • Quote every generated path and use -- before filename operands where supported.
  • Keep the temporary file descriptor open if output integrity must be protected from path replacement.
  • Track the detached process identifier so output and status are associated with the correct invocation.
  • Remove temporary logs when they are no longer needed, or move persistent logs into an operator-owned directory with mode 0700.
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The natural-language trigger is broad enough that generic requests like 'restore' or 'rollback' can cause a real configuration rollback without a tightly scoped confirmation step. Because this skill performs destructive operational changes and defaults ambiguous requests to the Slack gateway, an attacker or confused user could trigger unintended restoration actions through normal conversation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill directs the agent to run a detached script that changes live gateway configuration and restarts services, but it does not require a clear user-facing warning or confirmation about the destructive nature of the action. This increases the chance of accidental production-impacting changes, especially when invoked from natural language where user intent may be ambiguous.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
90% confidence
Finding

Using 'setsid' with background execution detaches the restore operation from the interactive session, allowing a privileged configuration change and service restart to continue after the agent interaction ends. This reduces visibility, auditability, and operator control, and can be abused to launch persistent operational actions that the user cannot easily stop or verify in-band.

Content

Scanner excerpt · SKILL.md (reported line 51)May include surrounding context.

If the user asks to restore via natural language (not a slash command), THEN run the script:

bash
setsid bash /home/swabby/repos/swabby-brain/skills/gateway-restore/scripts/gateway-restore.sh [slack|discord] [--tag-current] > /tmp/restore-output.log 2>&1 &
sleep 2 && cat /tmp/restore-output.log

Static analysis

No suspicious patterns detected.