Back to skill

Security audit

Alibabacloud Esa Pages Deploy

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it asks for broad Alibaba Cloud authority and has unsafe handling around deployment tokens and static-directory packaging.

Review this skill before installing. Use a narrowly scoped Alibaba Cloud RAM role instead of FullAccess where possible, avoid running static-directory deployment on untrusted build output or directories containing symlinks, and do not paste tokenized access URLs into public logs, tickets, or chats. Treat production deployment and KV writes as real cloud changes.

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 (4)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/deploy-folder.mjs:229
Finding

Short-Lived Bearer Token Exposed in Console Output

Content
View full analysis
{ console.log("\n✅ Deployment successful!"); console.log(`Access URL: ${url}`); console.log("\n💡 Note: If you access the link too quickly, DNS resolution may not have taken effect yet. Please wait a moment and try again."); }) ``` ### Technical Analysis The deployment access token is a bearer credential. The scripts append it to the `esa_er_token` query parameter and print the complete URL to standard output. Query-string credentials are liable to be retained in CI/CD logs, Agent transcripts, terminal logs, shell-session recordings, screenshots, browser history, HTTP proxy logs, and referrer metadata. Anyone who obtains the complete URL can use the token without separately authenticating to the Alibaba Cloud account. The token has a documented default lifetime of one hour, which limits but does not eliminate the exposure window. Uploading deployment artifacts to the Alibaba Cloud-provided OSS URL is necessary for the declared functionality; printing the resulting bearer token is not. ### Attack Path 1. A user runs one of the deployment scripts. 2. The script calls `GetRoutineAccessToken` and receives a valid bearer token. 3. The token is appended to the deployed routine URL as a query parameter. 4. The complete tokenized URL is written ...[truncated 680 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/deploy-folder.mjs:103
Finding

Static Directory Packager Follows Symbolic Links Outside the Deployment Root

Content
View full analysis
{ for (const file of fs.readdirSync(dir)) { const fullPath = path.join(dir, file); const zipFilePath = zipPath ? `${zipPath}/${file}` : file; if (fs.statSync(fullPath).isDirectory()) { addFiles(fullPath, zipFilePath); } else { zip.file(`assets/${zipFilePath}`, fs.readFileSync(fullPath)); fileCount++; } } }; addFiles(folderPath); ``` ### Technical Analysis `fs.statSync()` and `fs.readFileSync()` follow symbolic links. The recursive packager does not use `fs.lstatSync()` to identify links and does not compare each resolved path against the canonical deployment root. Consequently, a symbolic link placed inside the selected static directory can point to a file or directory elsewhere on the local filesystem. The script will read the target and include its contents in the ZIP archive under `assets/`. That archive is then uploaded to Alibaba Cloud OSS and deployed. This can occur accidentally in ordinary build output or intentionally when a repository, dependency, or generated artifact is attacker-controlled. Directory symlinks can also introduce recursion cycles, causing resource exhaustion or deployment failure. ### Attack Path 1. An attacker modifies a repository, build process, dependency, or build artifact. 2. The static output directory contains a symbolic link to a sensitive external file or directory. 3. A user invokes `deploy-folder.mjs` against that output directory. 4. `fs.statSync()` follows the link and treats its target as an ordinary file or directory. 5. `fs.readFileSync()` reads the external content, or recursion traverses the external directory. ...[truncated 661 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
references/kv-api.md:51
Finding

KV Reference Provides Destructive Helpers Without Required Confirmation

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Note
Location
SKILL.md:25
Finding

Skill Requires Broad AliyunESAFullAccess Instead of Task-Specific Permissions

Content
View full analysis
**Important**: > > 1. Grant **AliyunESAFullAccess** policy to your RAM user/role before using this skill. > 2. Enable ESA Functions & Pages first at [ESA Console](https://esa.console.aliyun.com/edge/pages/list), or use `OpenErService` API to enable programmatically. ``` ### Technical Analysis The Skill directs users to grant the managed `AliyunESAFullAccess` policy. The reviewed scripts use a more limited set of ESA capabilities relating to routine deployment, routine inspection, access-token generation, Edge KV operations, and optional Edge Routine service activation. A full-service policy can authorize unrelated ESA operations beyond those required for an individual deployment or management task. This violates least-privilege principles and increases the consequences of compromised credentials, malicious dependencies, unsafe local execution, or user error. The scripts obtain credentials from Alibaba Cloud's default credential chain. Therefore, the broad permissions apply to whichever RAM identity is resolved at runtime. ### Attack Path 1. A user follows the prerequisite and grants `AliyunESAFullAccess` to a RAM user or role. 2. The Skill executes under that identity through the default credential chain. 3. The runtime, host, dependency chain, or credentials are compromised. 4. The attacker uses the identity for ESA operations unrelated to the requested deployment or KV task. 5. Additional ESA resources can be inspected or modified within the broad policy's scope. ### Impact Assessment The exact privileges depend on the current definition of the Alibaba Cloud managed policy, but the potential scope extends beyond the routine or KV resource involved in the current task. A compromise may affect unrelated ESA s ...[truncated 316 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (38)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

  1. Upload code/assets to OSS → Via staging upload or assets API
  2. Commit & Publish → Deploy to production environment
  3. GetRoutine(name) → Get access URL (defaultRelatedRecord)
  4. GetRoutineAccessToken(name) → Get access token and append to URL (token valid for 1 hour)
text

> **STRICT Error Handling for CreateRoutine**: After calling `CreateRoutine`, you **MUST** inspect both the HTTP status code and the response body error code. Only two outcomes allow the flow to continue: (1) successful creation (HTTP 200), or (2) HTTP 400 with error code `RoutineNameAlreadyExists` (treat as success, skip to step 2). For **all other errors** (other 400 codes, 5xx, network failures), you **MUST immediately abort** the entire deployment flow and print the complete error information. It is **strictly forbidden** to proceed with upload or publish steps without confirmed routine creation success.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/deploy-folder.mjs (reported line 208)May include surrounding context.

js
2. Upload code/assets to OSS        → Via staging upload or assets API
3. Commit & Publish                 → Deploy to production environment
4. GetRoutine(name)                 → Get access URL (defaultRelatedRecord)
5. GetRoutineAccessToken(name)      → Get access token and append to URL (token valid for 1 hour)
```

> **STRICT Error Handling for CreateRoutine**: After calling `CreateRoutine`, you **MUST** inspect both the HTTP status code and the response body error code. Only two outcomes allow the flow to continue: (1) successful creation (HTTP 200), or (2) HTTP 400 with error code `RoutineNameAlreadyExists` (treat as success, skip to step 2). For **all other errors** (other 400 codes, 5xx, network failures), you **MUST immediately abort** the entire deployment flow and print the complete error information. It is **strictly forbidden** to proceed with upload or publish steps without confirmed routine creation success.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/deploy-folder.mjs (reported line 210)May include surrounding context.

js
2. Upload code/assets to OSS        → Via staging upload or assets API
3. Commit & Publish                 → Deploy to production environment
4. GetRoutine(name)                 → Get access URL (defaultRelatedRecord)
5. GetRoutineAccessToken(name)      → Get access token and append to URL (token valid for 1 hour)
```

> **STRICT Error Handling for CreateRoutine**: After calling `CreateRoutine`, you **MUST** inspect both the HTTP status code and the response body error code. Only two outcomes allow the flow to continue: (1) successful creation (HTTP 200), or (2) HTTP 400 with error code `RoutineNameAlreadyExists` (treat as success, skip to step 2). For **all other errors** (other 400 codes, 5xx, network failures), you **MUST immediately abort** the entire deployment flow and print the complete error information. It is **strictly forbidden** to proceed with upload or publish steps without confirmed routine creation success.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/deploy-html.mjs (reported line 134)May include surrounding context.

js
2. Upload code/assets to OSS        → Via staging upload or assets API
3. Commit & Publish                 → Deploy to production environment
4. GetRoutine(name)                 → Get access URL (defaultRelatedRecord)
5. GetRoutineAccessToken(name)      → Get access token and append to URL (token valid for 1 hour)
```

> **STRICT Error Handling for CreateRoutine**: After calling `CreateRoutine`, you **MUST** inspect both the HTTP status code and the response body error code. Only two outcomes allow the flow to continue: (1) successful creation (HTTP 200), or (2) HTTP 400 with error code `RoutineNameAlreadyExists` (treat as success, skip to step 2). For **all other errors** (other 400 codes, 5xx, network failures), you **MUST immediately abort** the entire deployment flow and print the complete error information. It is **strictly forbidden** to proceed with upload or publish steps without confirmed routine creation success.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · scripts/deploy-html.mjs (reported line 136)May include surrounding context.

js
2. Upload code/assets to OSS        → Via staging upload or assets API
3. Commit & Publish                 → Deploy to production environment
4. GetRoutine(name)                 → Get access URL (defaultRelatedRecord)
5. GetRoutineAccessToken(name)      → Get access token and append to URL (token valid for 1 hour)
```

> **STRICT Error Handling for CreateRoutine**: After calling `CreateRoutine`, you **MUST** inspect both the HTTP status code and the response body error code. Only two outcomes allow the flow to continue: (1) successful creation (HTTP 200), or (2) HTTP 400 with error code `RoutineNameAlreadyExists` (treat as success, skip to step 2). For **all other errors** (other 400 codes, 5xx, network failures), you **MUST immediately abort** the entire deployment flow and print the complete error information. It is **strictly forbidden** to proceed with upload or publish steps without confirmed routine creation success.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
> **Mandatory Pre-deployment Validation**: Before calling `deploy-folder.mjs` or executing the Static Directory flow, you **MUST** verify the target directory e

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
> **Mandatory Pre-deployment Validation**: Before calling `deploy-folder.mjs` or executing the Static Directory flow, you **MUST** verify the target directory e

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
> **Mandatory Pre-deployment Validation**: Before calling `deploy-folder.mjs` or executing the Static Directory flow, you **MUST** verify the target directory e

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

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

md
- **Function Management**: `CreateRoutine`, `GetRoutine`, `ListUserRoutines` (preferred API for listing routines, use instead of GetRoutineUserInfo)
- **Code Version**: `GetRoutineStagingCodeUploadInfo`, `CommitRoutineStagingCode`, `PublishRoutineCodeVersion`
- **Assets Deployment**: `CreateRoutineWithAssetsCodeVersion`, `GetRoutineCodeVersionInfo`, `CreateRoutineCodeDeployment`
- **Access Token**: `GetRoutineAccessToken` (generates token for URL access, default TTL is 1 hour)
- **Routes**: `CreateRoutineRoute`, `ListRoutineRoutes`

### Edge KV

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `deploy-html.mjs` | `node scripts/deploy-html.mjs <name> <html-file>` | Deploy HTML page |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `deploy-html.mjs` | `node scripts/deploy-html.mjs <name> <html-file>` | Deploy HTML page |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `deploy-function.mjs` | `node scripts/deploy-function.mjs <name> <code-file>` | Deploy custom function |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `deploy-function.mjs` | `node scripts/deploy-function.mjs <name> <code-file>` | Deploy custom function |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `manage.mjs` | `node scripts/manage.mjs list\|get` | Manage routines (uses ListUserRoutines API) |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `manage.mjs` | `node scripts/manage.mjs list\|get` | Manage routines (uses ListUserRoutines API) |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `manage.mjs` | `node scripts/manage.mjs list\|get` | Manage routines (uses ListUserRoutines API) |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `kv.mjs` | `node scripts/kv.mjs <command> [options]` | Manage Edge KV namespaces and key-value pairs |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `kv.mjs` | `node scripts/kv.mjs <command> [options]` | Manage Edge KV namespaces and key-value pairs |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `kv.mjs` | `node scripts/kv.mjs <command> [options]` | Manage Edge KV namespaces and key-value pairs |

Credential Access

High
Category
Privilege Escalation
Confidence
76% confidence
Finding

The skill tells the agent to append the access token directly in the URL query string and to obtain a fresh token before sharing the URL. Query-string tokens are prone to leakage through logs, browser history, referrers, chat transcripts, and monitoring systems, so distributing access this way increases the chance of unintended disclosure of a live bearer token.

Content

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

md
- **Same name**: Reuses existing function, deploys new version. If CreateRoutine returns error code 'RoutineNameAlreadyExists', this is expected — continue with the deployment flow.
- **Environments**: production only (default)
- **Access URL**: `defaultRelatedRecord` from `GetRoutine` + `?esa_er_token=<token>` from `GetRoutineAccessToken`. If access returns **401**, the token is missing or expired — call `GetRoutineAccessToken` again to refresh.
- **Token validity**: Access token is valid for 1 hour (default TTL). Always obtain a fresh token via `GetRoutineAccessToken` before sharing the URL.
- **Size limits**: Functions < 5MB, Assets single file < 25MB, KV value < 2MB (25MB high capacity)
- **Destructive operations**: Delete APIs (`DeleteRoutine`, `DeleteKv`, `DeleteKvNamespace`) require explicit user confirmation before execution. Always show resource details and ask for confirmation first.

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/pages-api.md (reported line 421)May include surrounding context.

}

text

## Access Token

Generate an access token to append to the deployment URL for authentication (default TTL: 1 hour).

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/pages-api.md (reported line 423)May include surrounding context.

Access Token

Generate an access token to append to the deployment URL for authentication (default TTL: 1 hour).

javascript
// Get access URL with token

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

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

Content

Scanner excerpt · references/pages-api.md (reported line 437)May include surrounding context.

Access Token

Generate an access token to append to the deployment URL for authentication (default TTL: 1 hour).

javascript
// Get access URL with token

Credential Access

High
Category
Privilege Escalation
Confidence
92% confidence
Finding

The script programmatically requests a routine access token and appends it to the returned URL, which is then printed to stdout. Query-string tokens are easily exposed through terminal logs, shell history capture, CI job logs, copy/paste, browser history, and intermediary systems, allowing anyone who obtains the URL to access the deployed routine until the token expires.

Content

Scanner excerpt · scripts/deploy-function.mjs (reported line 121)May include surrounding context.

js
? `https://${routine.body.defaultRelatedRecord}`
    : null;

  // Get access token and append to URL
  if (url) {
    console.log("Getting access token...");
    const tokenParams = new OpenApi.Params({

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

This code invokes the GetRoutineAccessToken API and then uses the resulting credential-bearing token to build a shareable URL. Even though the token is short-lived, generating and exposing credentials in this way increases the risk of inadvertent disclosure, especially because deployment scripts are often run in automated environments where stdout is centrally retained.

Content

Scanner excerpt · scripts/deploy-function.mjs (reported line 123)May include surrounding context.

js
// Get access token and append to URL
  if (url) {
    console.log("Getting access token...");
    const tokenParams = new OpenApi.Params({
      action: "GetRoutineAccessToken",
      version: "2024-09-10",

Static analysis

No suspicious patterns detected.