Back to skill

Security audit

ACME SSL automation for Alibaba Cloud ESA DNS

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent certificate-renewal purpose, but its root cron installer creates high-impact local and credential exposure risks that users should review before installing.

Install only on a controlled Linux host after reviewing the installer. Use a least-privilege Alibaba Cloud RAM or short-lived STS credential limited to the specific ESA zones, avoid primary account keys, and do not run the root cron installer from a user-writable checkout. Prefer manual runs or harden the cron install by copying the Python script and i18n files into a root-owned directory, removing credential command-line flags, and limiting reload behavior to a fixed Nginx reload command.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (2)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/install_cron.sh:115
Finding

Root Cron Job Executes Mutable Code from the Original Project Directory

Content
View full analysis
&2 exit 1 fi # ... { echo '#!/usr/bin/env bash' echo 'set -euo pipefail' echo 'export PATH="/root/.hermes/node/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"' printf 'source %s\n' "$(shell_quote "$ENV_FILE")" printf 'exec 9>%s\n' "$(shell_quote "/tmp/esa-acme-${WRAPPER_NAME}.lock")" echo 'flock -n 9 || exit 0' echo 'cd /root' printf 'python3 %s \\\n' "$(shell_quote "$SKILL_SCRIPT")" ``` ### Technical Analysis The installer must run as root and creates a root cron entry, but the generated root-owned wrapper continues to execute `esa_acme_issue.py` directly from the original project directory. The installer checks only that the file exists; it does not verify that the file and all parent directories are owned by root and are not writable by less-privileged users. Consequently, the security of the persistent root cron task depends on the ownership and permissions of the directory from which the installer was launched. If that directory is writable by a non-root account, that account can replace or modify the Python script after installation. The next scheduled invocation will execute the modified code as root. This persistence mechanism is explicitly documented and is legitimate for automatic certificate renewal. The vulnerability is not the presence of cron itself, but the failure to establish a trusted, immutable execution path across the privilege boundary. ### Attack Path 1. An administrator checks out or extracts the Skill into a directory owned ...[truncated 915 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/install_cron.sh:159
Finding

Alibaba Cloud Credentials Are Exposed Through Process Command-Line Arguments

Content
View full analysis
%s\n' "$(shell_quote "/tmp/esa-acme-${WRAPPER_NAME}.lock")" echo 'flock -n 9 || exit 0' echo 'cd /root' printf 'python3 %s \\\n' "$(shell_quote "$SKILL_SCRIPT")" for ((i=0; i<${#domain_args[@]}; i+=2)); do printf ' -d %s \\\n' "$(shell_quote "${domain_args[i+1]}")" done printf ' --ak "$ALIYUN_AK" \\\n' printf ' --sk "$ALIYUN_SK" \\\n' if [[ -n "$STS_TOKEN" ]]; then printf ' --sts-token "$ALIYUN_SECURITY_TOKEN" \\\n' fi ``` ### Technical Analysis The installer protects the credential environment file with mode `0600`, but the generated wrapper expands the AccessKey ID, AccessKey secret, and optional STS token into command-line arguments. After shell expansion, the effective process command line contains the literal credential values. Depending on operating-system process visibility, `/proc` mount configuration, audit rules, process accounting, monitoring agents, diagnostic tooling, and administrative access, these arguments may be recorded or exposed outside the protected environment file. This exposure is unnecessary because `esa_acme_issue.py` already supports reading all three values from environment variables: - `ALIYUN_AK` - `ALIYUN_SK` - `ALIYUN_SECURITY_TOKEN` Passing them again as arguments increases the credential exposure surface without providing required functionality. ### Attack Path 1. The root cron wrapper sources the protected credential environment file. 2. The wrapper launches Python with the expanded credent ...[truncated 1027 chars]
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
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (34)

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

The default env file path under /root/.config indicates the script stores cloud credentials in a predictable on-disk location for repeated use. In the context of an automation skill that provisions DNS validation and cert renewal, these credentials may permit DNS/API manipulation beyond certificate issuance, so compromise of the host or file can lead to significant account impact.

Content

Scanner excerpt · install_cron.sh (reported line 108)May include surrounding context.

sh
fi

if [[ -z "$ENV_FILE" ]]; then
  ENV_FILE="/root/.config/esa-acme-${WRAPPER_NAME}.env"
fi
if [[ -z "$WRAPPER" ]]; then
  WRAPPER="/usr/local/sbin/esa-acme-${WRAPPER_NAME}-renew"

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Defaulting the credential file to /root/.config/esa-acme-.env indicates deliberate on-disk storage of cloud API secrets for recurring use. In a certificate automation skill tied to DNS control, compromise of these credentials could let an attacker alter DNS records, interfere with validation, or potentially obtain fraudulent certificates for managed domains.

Content

Scanner excerpt · scripts/install_cron.sh (reported line 108)May include surrounding context.

sh
fi

if [[ -z "$ENV_FILE" ]]; then
  ENV_FILE="/root/.config/esa-acme-${WRAPPER_NAME}.env"
fi
if [[ -z "$WRAPPER" ]]; then
  WRAPPER="/usr/local/sbin/esa-acme-${WRAPPER_NAME}-renew"

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · README.md (reported line 9)May include surrounding context.

md
## What this skill solves

AI models often resolve to the wrong place: they write records to traditional AliDNS, while the correct target should be ESA DNS. These two DNS systems are independent.

In other words, when a domain is hosted on ESA (`*.atrustdns.com`), DNS-01 validation records must be written to ESA DNS, not traditional AliDNS.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 95)May include surrounding context.

示例:

bash
sudo bash scripts/install_cron.sh \
  --wrapper-name dogeow \
  --domains "dogeow.com,*.dogeow.com" \
  --ak 你的AK \

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 112)May include surrounding context.

示例:

bash
sudo bash scripts/install_cron.sh \
  --wrapper-name dogeow \
  --domains "dogeow.com,*.dogeow.com" \
  --ak 你的AK \

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README_zh.md (reported line 89)May include surrounding context.

示例:

bash
sudo bash scripts/install_cron.sh \
  --wrapper-name dogeow \
  --domains "dogeow.com,*.dogeow.com" \
  --ak 你的AK \

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README_zh.md (reported line 106)May include surrounding context.

示例:

bash
sudo bash scripts/install_cron.sh \
  --wrapper-name dogeow \
  --domains "dogeow.com,*.dogeow.com" \
  --ak 你的AK \

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises capabilities that include environment access, file reads, network access, and shell execution, but it does not declare any explicit tool scope or permissions boundary. This increases the risk of over-privileged execution because a caller or platform may invoke the skill without clear restrictions, while the documented workflow handles cloud credentials, DNS changes, cron installation, and optional Nginx reloads.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The top-level description includes broad trigger phrases like Let's Encrypt, wildcard certificate, and Nginx certificate configuration, which can match many unrelated user requests. Over-broad activation can cause unintended invocation of a skill that performs sensitive actions involving DNS, credentials, shell commands, and system configuration changes.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The 'When to Trigger' section contains activation conditions that are still broad enough to capture common certificate troubleshooting or Nginx setup scenarios. Because this skill can write DNS records and optionally install certificates or reload Nginx, accidental triggering raises the chance of unnecessary or unsafe state-changing operations.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
89% confidence
Finding

The skill supports persistent automation by writing DNS records, installing certificates to Nginx, and recommending a cron-based renewal flow that stores cloud credentials in a root-owned env file. This creates ongoing state and secret persistence on the host, which can increase exposure if the machine is later compromised or if the renewal wrapper is misconfigured.

Content

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

md
- User says "issue certificate with acme.sh", "Let's Encrypt", "DNS-01"
- Error: `No TXT record found at _acme-challenge...`
- Need to issue `example.com + *.example.com` together
- Need to auto-write ESA DNS records and install to Nginx

---

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
84% confidence
Finding

The skill instructs users to run an installation script with sudo, which enables root-level changes such as writing credential files, installing wrapper scripts, creating cron entries, and potentially reloading Nginx. Even if intended for legitimate automation, encouraging privileged execution expands blast radius if the script is flawed, tampered with, or invoked with unsafe arguments.

Content

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

Example:

bash
sudo bash scripts/install_cron.sh \
  --wrapper-name dogeow \
  --domains "dogeow.com,*.dogeow.com" \
  --ak YOUR_AK \

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code passes a user-provided --reload-cmd directly to acme.sh's --reloadcmd option, causing arbitrary command execution when certificate installation occurs. Even though this script does not invoke a shell itself, acme.sh commonly executes reload hooks as shell commands, so this becomes a command-execution primitive beyond the stated scope of certificate issuance.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill claims to automate certificate issuance, but it also allows arbitrary A/AAAA DNS record creation and modification through --ensure-a-record. That expands the operational scope from ACME validation into general DNS administration, which can be abused to redirect traffic, hijack subdomains, or alter service routing under the guise of certificate management.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script persists Alibaba Cloud access keys and optional STS tokens to a root-owned env file for later cron execution. Although permissions are restricted with umask 077 and chmod 600, this still creates long-lived credential material on disk without an explicit warning, lifecycle controls, or guidance to prefer short-lived credentials; compromise of root, backups, or accidental disclosure of the file would expose cloud credentials.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · esa_acme_issue.py (reported line 34)May include surrounding context.

python
def run(cmd, timeout=DEFAULT_CMD_TIMEOUT):
    try:
        p = subprocess.run(cmd, text=True, capture_output=True, timeout=timeout)
        return p.returncode, (p.stdout or "") + (p.stderr or "")
    except FileNotFoundError:
        return 127, f"[ERR] command not found: {cmd[0]}"

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/esa_acme_issue.py (reported line 34)May include surrounding context.

python
def run(cmd, timeout=DEFAULT_CMD_TIMEOUT):
    try:
        p = subprocess.run(cmd, text=True, capture_output=True, timeout=timeout)
        return p.returncode, (p.stdout or "") + (p.stderr or "")
    except FileNotFoundError:
        return 127, f"[ERR] command not found: {cmd[0]}"

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This skill performs DNS A/AAAA record creation and modification in addition to ACME TXT challenge handling, which expands its authority beyond certificate issuance. Because DNS changes can redirect traffic or disrupt services, a user invoking a certificate workflow could unintentionally or indirectly alter production routing.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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 · esa_acme_issue.py (reported line 350)May include surrounding context.

python
if current and current != ip and not confirm_overwrite:
            print(f"[CONFIRM] Existing {rrtype} record detected: {host} -> {current}")
            print(f"[CONFIRM] Requested new value: {ip}")
            print("[ERR] overwrite blocked. Re-run with --confirm-overwrite after user confirmation.")
            sys.exit(6)
        esa_req(client, "UpdateRecord", "POST", SiteId=site_id, RecordId=target.get("RecordId"), Type="A/AAAA", RecordName=host, Ttl=1, Data=payload, Proxied="false")
        print(f"[INFO] {rrtype} record update request accepted: {host} -> {ip}")

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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/esa_acme_issue.py (reported line 350)May include surrounding context.

python
if current and current != ip and not confirm_overwrite:
            print(f"[CONFIRM] Existing {rrtype} record detected: {host} -> {current}")
            print(f"[CONFIRM] Requested new value: {ip}")
            print("[ERR] overwrite blocked. Re-run with --confirm-overwrite after user confirmation.")
            sys.exit(6)
        esa_req(client, "UpdateRecord", "POST", SiteId=site_id, RecordId=target.get("RecordId"), Type="A/AAAA", RecordName=host, Ttl=1, Data=payload, Proxied="false")
        print(f"[INFO] {rrtype} record update request accepted: {host} -> {ip}")

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The script accepts a caller-supplied --reload-cmd and forwards it to acme.sh's --reloadcmd option, which results in execution of arbitrary local commands during certificate installation. In the context of an agent skill, this is dangerous because untrusted or loosely validated user input can become code execution on the host with the skill's privileges.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · install_cron.sh (reported line 41)May include surrounding context.

sh
require_root() {
  if [[ ${EUID:-$(id -u)} -ne 0 ]]; then
    echo "[ERR] run as root" >&2
    exit 1
  fi
}

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · scripts/install_cron.sh (reported line 41)May include surrounding context.

sh
require_root() {
  if [[ ${EUID:-$(id -u)} -ne 0 ]]; then
    echo "[ERR] run as root" >&2
    exit 1
  fi
}

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script persists Alibaba access keys and an optional STS token to a root-owned env file for later unattended cron use. Although permissions are restricted with umask 077 and chmod 600, long-lived credential storage increases exposure through backups, filesystem compromise, operator mistakes, or token reuse, and the script does not prominently warn the user about this persistence risk.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · install_cron.sh (reported line 136)May include surrounding context.

sh
if [[ -n "$REGION" ]]; then
  printf 'ALIYUN_ESA_REGION=%s\n' "$(shell_quote "$REGION")" >> "$ENV_FILE"
fi
chmod 600 "$ENV_FILE"

IFS=',' read -r -a domain_items <<< "$DOMAINS"
if [[ ${#domain_items[@]} -eq 0 ]]; then

Static analysis

No suspicious patterns detected.