Back to skill

Security audit

TeamWork

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its teamwork purpose, but it needs Review because it can persist provider API keys in plaintext and broadly share task context across configured models.

Install only if you are comfortable with local persistent provider configuration. Prefer environment-variable references instead of pasting real API keys, review .trae/config/providers.json permissions, avoid sharing confidential tasks with multiple external providers, and restrict template names to known bundled templates.

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/config-manager.js:7
Finding
Provider API Keys Can Be Persisted in Plaintext Configuration Files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/config-manager.js:7-13`, `scripts/init.js:35-37`, and `SKILL.md:32-38` **Vulnerability Type**: Plaintext sensitive credential storage **Risk Level**: High ### Vulnerable Code The configuration manager accepts a literal API key and retains it in the provider configuration: ```javascript function addProvider(config, providerInfo) { const provider = { name: providerInfo.name, api_key: providerInfo.api_key || `\${${providerInfo.name.toUpperCase()}_API_KEY}`, base_url: providerInfo.base_url || '', models: [] }; ``` The generic JSON writer serializes the complete configuration without redaction, encryption, or restrictive permissions: ```javascript function writeJSON(filePath, data) { fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf8'); } ``` The Skill documentation explicitly allows collection of either a literal API key or an environment-variable name: ```markdown For each provider, collect: - Provider name - API key (or environment variable name) - Base URL (if custom endpoint) ``` ### Technical Analysis The secure default is an environment-variable or secret-manager reference, but `addProvider` accepts arbitrary `providerInfo.api_key` values. If a caller supplies a real credential, that value is placed directly in `config.providers[].api_key`. The documented workflow subsequently persists provider configuration in `.trae/config/providers.json` through `writeJSON`. Node.js creates the file using the process umask because no explicit mode is supplied. The implementation provides no encryption, credential validation, redaction, permission verification, or prohibition against literal secrets. Consequently, long-lived provider credentials can remain in a predictable local file. The file may also be copied into backups, support bundles, or source-control commits. ### Attack Path 1. A user follows the documented initialization workflow. 2. The user supplies a l ...[truncated 1398 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not accept or persist literal provider credentials. Store only an environment-variable name or secret-manager reference: ```javascript const envName = providerInfo.api_key_env || `${providerInfo.name.toUpperCase()}_API_KEY`; const provider = { name: providerInfo.name, api_key_env: envName, base_url: providerInfo.base_url || '', models: [] }; ``` 2. Resolve credentials only at request time: ```javascript const apiKey = process.env[provider.api_key_env]; if (!apiKey) { throw new Error(`Missing credential environment variable: ${provider.api_key_env}`); } ``` 3. Reject values that appear to be literal API keys rather than approved reference names. 4. Create sensitive configuration files with owner-only permissions: ```javascript fs.writeFileSync( filePath, JSON.stringify(data, null, 2), { encoding: 'utf8', mode: 0o600 } ); ``` 5. Verify and correct permissions on existing configuration files. Warn the user if a file is group-readable or world-readable. 6. Redact fields named `api_key`, `token`, `secret`, or similar from logging, display, diagnostics, backups, and error messages. 7. Document credential rotation procedures and advise users to revoke any key previously stored in plaintext. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
utils/template-renderer.js:6
Finding
Template Path Traversal Allows Arbitrary Local File Reads<![CDATA[ ## Vulnerability Details **File Location**: `utils/template-renderer.js:6-13` **Vulnerability Type**: Path traversal and arbitrary local file disclosure **Risk Level**: Medium ### Vulnerable Code ```javascript function loadTemplate(templateName) { const templatePath = path.join(TEMPLATES_DIR, templateName); if (!fs.existsSync(templatePath)) { throw new Error(`Template not found: ${templateName}`); } return fs.readFileSync(templatePath, 'utf8'); } ``` ### Technical Analysis `loadTemplate` is exported and accepts an unrestricted `templateName`. The value is joined to the intended template directory, but the resolved path is never checked for directory containment. A name containing parent-directory components, such as `../../some/file`, can escape `TEMPLATES_DIR`. The `existsSync` call confirms only that the resulting target exists; it does not establish that the target is an authorized template. Absolute paths and symlinks may produce equivalent boundary violations depending on the supplied path and filesystem layout. `renderTemplateFromFile` calls `loadTemplate`, so the disclosed file content may be returned directly or processed as a template. If the caller can influence the template name and observe the result, this becomes an arbitrary text-file read within the Node.js process's filesystem permissions. ### Attack Path 1. An application exposes `loadTemplate` or `renderTemplateFromFile` through a route, command, agent action, or other interface that accepts a caller-controlled template name. 2. The attacker supplies a traversal value such as: ```text ../../.trae/config/providers.json ``` 3. `path.join(TEMPLATES_DIR, templateName)` resolves a path outside the bundled `templates` directory. 4. `fs.existsSync` succeeds if the target file exists. 5. `fs.readFileSync` reads the target using the privileges of the Node.js process. 6. The function returns the file content to the caller or embeds it in rendered output. 7. Th ...[truncated 768 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Prefer a strict allowlist because the project contains only four supported templates: ```javascript const ALLOWED_TEMPLATES = new Set([ 'task-report.md', 'meeting-minutes.md', 'failure-report.md', 'evaluation-form.md' ]); function loadTemplate(templateName) { if (!ALLOWED_TEMPLATES.has(templateName)) { throw new Error('Invalid template name'); } return fs.readFileSync(path.join(TEMPLATES_DIR, templateName), 'utf8'); } ``` 2. If dynamic template names are required, canonicalize and enforce containment: ```javascript function loadTemplate(templateName) { if (path.isAbsolute(templateName)) { throw new Error('Absolute template paths are not allowed'); } const base = path.resolve(TEMPLATES_DIR); const templatePath = path.resolve(base, templateName); const relative = path.relative(base, templatePath); if ( relative === '' || relative.startsWith(`..${path.sep}`) || relative === '..' || path.isAbsolute(relative) ) { throw new Error('Template path escapes the template directory'); } return fs.readFileSync(templatePath, 'utf8'); } ``` 3. Reject path separators and parent-directory components when only flat filenames are expected. 4. Consider resolving the real path and checking it again against the real template directory to prevent symlink-based escapes. 5. Return generic errors to untrusted callers so filesystem paths and existence information are not exposed. 6. Add tests covering `../`, nested traversal, absolute paths, encoded traversal at interface boundaries, mixed separators, and escaping symlinks. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The code does not create, orchestrate, or manage AI agent teams or collaborative workflows. Instead, it manages configuration data for model providers, models, pricing, quotas, and budgets. While this could support a broader teamwork system, the supplied code chunk’s actual primary purpose is configuration administration, not multi-agent task execution or team coordination. Therefore the declared description materially misrepresents the behavior of this code.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The code is an initialization module, not a runtime team-management system. It creates directories and reads/writes local JSON config files for providers, roles, and model scoring metadata. While the default role definitions relate conceptually to agent teams, the chunk does not dynamically create teams, assign agents, coordinate collaboration, or execute complex projects. Its primary purpose is setup and validation of configuration state, which is materially narrower and different from the declared description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The supplied code does not perform dynamic team creation or management. Instead, it maintains a score database for models, updates evaluation metrics across dimensions, computes overall scores, tracks historical role fit, and retrieves top-ranked models for roles or capabilities. While role-fit and capability ranking could support a broader team-selection system, this chunk itself is focused on scoring and ranking models, not orchestrating multi-agent teams or executing complex collaborative workflows. Therefore the declared description materially overstates and misrepresents the actual behavior of this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents this skill as a multi-agent team orchestration component. However, the supplied code chunk only contains error classes plus helper functions to format/log errors and mark some errors as recoverable. There is no logic for creating agents, assigning roles, coordinating workflows, or executing complex projects. This is a materially different primary purpose, so the description does not accurately represent the code.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description promises a specialized capability for dynamic multi-agent team creation and management. However, the actual code chunk contains only general-purpose helper functions. None of the functions implement agent orchestration, team lifecycle management, specialized role handling, or coordinated workflows. While helper utilities could support a larger system, this code by itself does not match the declared primary purpose and instead serves as a generic utility library, making the description materially inaccurate for this chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description describes a high-level orchestration skill for dynamically creating and managing AI agent teams. However, the supplied code chunk does not implement any agent-management or workflow-coordination behavior. It only aggregates and re-exports utilities from other local modules. This is a materially different primary purpose from the declared functionality, so it should be flagged as a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description says the skill manages AI agent teams and coordinates complex multi-agent workflows. The supplied code does none of that. Instead, it defines a Logger class with log levels, console output, and optional file-based logging via fs.appendFileSync. This is a materially different primary purpose. Additionally, the code accesses filesystem resources for log writing, which is not suggested by the declared permissions or purpose. This is a clear description-behavior mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared purpose suggests orchestration of AI agents, role assignment, and coordinated workflow management. However, the supplied code chunk only provides a basic template renderer that reads template files, substitutes variables and simple control blocks, and writes rendered content to an output path. This is a materially different primary purpose. The filesystem access for reading templates and writing output is also not reflected in the declared permissions, though the stronger issue is that the code is unrelated to multi-agent collaboration functionality.

Ae1

High
Category
analysis-evasion
Content
const configManager = require('./scripts/config-manager.js');
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
const configManager = require('./scripts/config-manager.js');
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
const TeamCoordinator = require('./scripts/team-coordinator.js');
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
const TeamCoordinator = require('./scripts/team-coordinator.js');
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
const Herald = require('./scripts/herald.js');
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
const Herald = require('./scripts/herald.js');
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
const { createLogger, LOG_LEVELS } = require('./utils/logger.js');
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The README instructs users to add AI providers and API keys and describes persistent configuration files, but it provides no guidance on secure credential storage, redaction, or filesystem permissions. In a multi-agent skill that coordinates multiple providers, poor secret-handling practices increase the chance that API keys are stored in plaintext, exposed in logs, or made accessible to other components or users on the host.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The README states the skill is automatically invoked for broad conditions like 'multi-agent collaboration' or 'complex projects,' which creates an overly permissive trigger surface. In an agent framework, ambiguous auto-invocation can cause the skill to activate in contexts the user did not clearly intend, leading to unnecessary access to configuration, provider selection, or downstream execution logic.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill explicitly instructs users to provide provider API keys and then persist provider configuration, but it gives no safeguards around secret collection, storage, masking, or use of environment variables. In a multi-provider orchestration skill, this creates a meaningful risk of credential exposure through files, prompts, logs, backups, or later configuration display.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill says it will display the complete provider configuration from `.trae/config/providers.json`, which may include API keys or secret references. Exposing full configuration materially increases the chance of accidental credential disclosure to users, other models, logs, screenshots, or downstream tooling.

External Transmission

Medium
Category
Data Exfiltration
Content
{
      "name": "openai",
      "api_key": "${OPENAI_API_KEY}",
      "base_url": "https://api.openai.com/v1",
      "models": [
        {
          "name": "gpt-4",
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
{
      "name": "openai",
      "api_key": "${OPENAI_API_KEY}",
      "base_url": "https://api.openai.com/v1",
      "models": [
        {
          "name": "gpt-4",
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
{
      "name": "openai",
      "api_key": "${OPENAI_API_KEY}",
      "base_url": "https://api.openai.com/v1",
      "models": [
        {
          "name": "gpt-4",
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Ssd 3

Medium
Confidence
94% confidence
Finding
The workflow instructs the host model to present all task content, requirements, constraints, and background information to every participating model. In a multi-agent setting, this violates data minimization and can unnecessarily spread secrets, proprietary code, personal data, or internal business context across more providers/models than required.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The template explicitly states that no user consultation is required and that automated recovery will proceed, but it does not warn about possible side effects such as data loss, configuration drift, unintended actions, or service disruption. In a multi-agent teamwork skill that can coordinate complex workflows, this normalizes autonomous remediation without requiring a safety check or impact disclosure, increasing the chance of unsafe recovery actions being taken or socially justified by the generated report.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
This skill documentation includes Chinese terms such as '订阅制' alongside English labels, and similar mixed-language labels appear elsewhere in the file. Because the skill does not state that it is region-specific or offer a language preference choice, this can violate a language/locale policy requiring user opt-in for non-default language presentation.

Static analysis

No suspicious patterns detected.