Back to skill

Security audit

Asana

Security checks for vulnerabilities and agentic risk

Overview

This Asana skill is mostly purpose-aligned, but it has real credential-handling and live-data mutation risks that users should review before installing.

Install only if you are comfortable giving the skill access to your Asana account and letting it modify live tasks. Prefer environment variables or a secret manager over saved plaintext files, avoid passing secrets on the command line, restrict permissions on ~/.openclaw/asana, and use a low-privilege Asana token or test workspace when possible.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/configure.mjs:39
Finding

Sensitive credential files are created without restrictive permissions

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:34
Finding

Documented command-line authentication flow exposes secrets through process arguments

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/asana_api.mjs:342
Finding

Task search forwards authentication and control flags into the request URL

Content
View full analysis
(or set default via set-default-workspace)'); const query = { ...flags }; delete query._; if (query.assignee === 'me') query['assignee.any'] = await resolveMeGid(accessToken); if (query.project) query['projects.any'] = String(query.project); delete query.assignee; delete query.project; const optFields = query.opt_fields || 'gid,name,completed,assignee.name,due_on,permalink_url'; delete query.opt_fields; const r = await asanaGet(`/workspaces/${workspace}/tasks/search`, accessToken, { ...query, opt_fields: optFields, limit: query.limit || 100, }); printJson(r); return; } ``` The query is then added to the URL by `scripts/asana_api.mjs:163-167`: ```js async function asanaGet(pathname, token, query) { const url = new URL(API_BASE + pathname); if (query) { for (const [k, v] of Object.entries(query)) url.searchParams.set(k, String(v)); } ``` ### Technical Analysis The `search-tasks` implementation copies every parsed command-line flag into the outgoing query object and removes only a few known fields. Authentication and local control flags are not excluded. For example, invoking the command with `--token`, `--client-id`, or `--client-secret` causes those values to be serialized into the request URL. This is separate from the legitimate bearer token in the `Authorization` header. Although the URL origin is hard-coded to the official Asana HTTPS endpoint, secrets in URLs receive weaker handling than secrets in authorization headers. Full URLs may be retained by HTTP infrastructure, reverse proxies, tracing systems, diagnostics, server access logs, or monito ...[truncated 1453 chars]
Remediation
View remediation
allowedSearchFlags.has(key)), ); ``` 2. Explicitly reject or remove authentication and local control fields before URL construction: ```js delete query.token; delete query['client-id']; delete query['client-secret']; delete query.client_id; delete query.client_secret; delete query.workspace; ``` 3. Validate each accepted query parameter's type, length, and expected format. 4. Keep bearer credentials exclusively in the `Authorization` header. 5. Add regression tests confirming that PATs, client secrets, authorization codes, and unrelated flags never appear in generated URLs. 6. Rotate any credential known to have been used with the vulnerable `search-tasks --token` pattern if request URLs may have been logged. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (14)

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 · README.md (reported line 7)May include surrounding context.

md
## Recommended auth

Use a Personal Access Token (PAT).

Supported auth order:
1. `ASANA_PAT` env var

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/oauth_oob.mjs authorize --client-id "$ASANA_CLIENT_ID"

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node scripts/oauth_oob.mjs authorize --client-id "$ASANA_CLIENT_ID"

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 · README.md (reported line 32)May include surrounding context.

md
}

function credentialsPath() {
  return path.join(asanaDir(), 'credentials.json');
}

function loadJsonIfExists(p, fallback = {}) {

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/configure.mjs (reported line 27)May include surrounding context.

js
}

function credentialsPath() {
  return path.join(asanaDir(), 'credentials.json');
}

function loadJsonIfExists(p, fallback = {}) {

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The markdown documents that configuration, credentials, and token files are stored under the user's home directory, but it does not warn that these files contain sensitive authentication material. For a skill handling PATs and OAuth secrets, omitting a user-facing warning about protecting or securing those files is a meaningful safety disclosure gap.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill exposes capabilities that can access environment variables and make network calls, but it does not declare any explicit tool scope such as permissions or allowed-tools. That weakens policy enforcement and user awareness, increasing the chance the skill can access secrets or perform remote actions beyond what operators expected.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
79% confidence
Finding

The skill is designed around persistent local storage of authentication state, including PATs and OAuth tokens, which creates session persistence beyond a single invocation. While common for API integrations, persistent auth material increases exposure if the host is compromised or if multiple users/processes can access the same home directory.

Content

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

md
---
name: asana
description: "Manage Asana via the Asana REST API. Use when you need to list workspaces, projects, tasks, search tasks, comment, update, complete, or create tasks."
metadata:
  openclaw:
    homepage: "https://developers.asana.com/docs"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill instructs users to store PAT/OAuth credentials in local files under ~/.openclaw/asana without an explicit warning that these are sensitive secrets. Storing API tokens locally without handling guidance raises the risk of credential leakage through weak file permissions, backups, shared machines, or accidental disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The command list includes state-changing operations such as update-task, complete-task, comment, and create-task, but it does not clearly warn that these commands will modify live Asana data. In an agent setting, that omission can lead to unintended writes to production workspaces or tasks if a user assumes the commands are read-only or merely demonstrative.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The flagged commands (update-task, complete-task, comment, and create-task) immediately perform authenticated state-changing requests against the Asana API with no confirmation prompt, dry-run mode, or explicit safeguard. In an agent/tooling context, this increases the risk of unintended remote writes from prompt injection, user misunderstanding, or argument mix-ups, especially because the script is designed to act on live project-management data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script saves the full OAuth token response to ~/.openclaw/asana/token.json and logs only the file path. While the operation is commented and printed, there is no user-facing warning that sensitive access credentials will be persisted locally, which is a safety-relevant file write involving secrets.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script reads ASANA_CLIENT_SECRET from the environment to perform the token exchange, but provides no warning or explanatory note that a secret credential will be consumed from environment variables. The existing usage text shows how to set it, but does not disclose the sensitivity or handling implications of that secret.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script sends the authorization code, client ID, and client secret to Asana's token endpoint. Although this is expected for OAuth, the file does not provide a user-facing warning that sensitive data will be transmitted over the network as part of the token exchange.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access, suspicious.exposed_secret_literal

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/asana_api.mjs:70

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
scripts/oauth_oob.mjs:84

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
scripts/asana_api.mjs:117