Back to skill

Security audit

Togetherai Tts

Security checks for vulnerabilities and agentic risk

Overview

This TTS skill appears to do what it claims, but it sends text to TogetherAI and has avoidable risks around API-key logging and unrestricted output-file overwrites.

Review before installing. Use only non-sensitive text, use a narrowly scoped TogetherAI key with spending limits, avoid running it in privileged directories, and provide output paths only in a dedicated folder. The publisher should sanitize error logging, restrict output paths, prevent accidental overwrites, and pin dependencies with a lockfile.

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
index.js:20
Finding

Potential API Credential Disclosure Through Unsanitized Axios Error Logging

Content
View full analysis

Vulnerability Details

File Location: index.js, lines 20-30
Vulnerability Type: Sensitive credential exposure through verbose error logging
Risk Level: High

Vulnerable Code

js
      headers: {
        'Authorization': `Bearer ${apiKey}`,
      },
    }
  );

  const audioData = response.data.audio;
  fs.writeFileSync(outputFile, Buffer.from(audioData, 'base64'));

  console.log(`TTS generated and saved to ${outputFile}`);
} catch (error) {
  console.error('Error generating TTS:', error);

Technical Analysis

The application includes the TogetherAI API key in an Axios request's Authorization header and logs the complete error object if the request fails. Axios error objects can retain request configuration and header information. Depending on the Axios and Node.js serialization behavior, the logged object may therefore include the bearer token.

The risk applies to terminal output, process logs, CI/CD logs, agent execution transcripts, and centralized logging systems. Logging only a sanitized error message would be sufficient for routine diagnostics.

Attack Path

  1. An attacker or unreliable network condition causes the TogetherAI request to fail, such as through an invalid request, rejected credentials, connection failure, or non-success response.
  2. Axios constructs an error object that can contain the original request configuration.
  3. The request configuration contains Authorization: Bearer <TOGETHERAI_API_KEY>.
  4. The catch block passes the complete object to console.error.
  5. Anyone with access to the resulting terminal, execution transcript, or collected logs may recover the API credential.
  6. The exposed credential may then be used directly against the TogetherAI API.

Impact Assessment

Successful exploitation can disclose the configured TogetherAI API key. An attacker could make unauthorized API requests with the permissions and usage quota asso ...[truncated 343 chars]

Remediation
View remediation

Remediation Suggestions

  • Never log the complete Axios error object when authenticated requests are involved.

  • Log only explicitly selected, non-sensitive fields, such as the error message and HTTP status:

    js
    } catch (error) {
      const status = error.response?.status;
      console.error('Error generating TTS:', {
        message: error.message,
        status,
      });
    }
    
  • Add a centralized redaction function that removes authorization, cookie, API-key, and token fields before structured objects are logged.

  • Ensure production logging and monitoring systems apply an additional credential-redaction layer.

  • Rotate the TogetherAI API key if existing logs may contain prior request errors.

  • Use a narrowly scoped API credential and configure usage limits where the provider supports them.

T09 · Insecure Skill Coding Practices

Error
Location
index.js:26
Finding

Unrestricted Caller-Controlled File Overwrite

Content
View full analysis

Vulnerability Details

File Location: index.js, lines 26-43
Vulnerability Type: Arbitrary file write and overwrite through an unvalidated output path
Risk Level: High

Vulnerable Code

js
  const audioData = response.data.audio;
  fs.writeFileSync(outputFile, Buffer.from(audioData, 'base64'));

  console.log(`TTS generated and saved to ${outputFile}`);
} catch (error) {
  console.error('Error generating TTS:', error);
}
}

if (process.argv.length < 4) {
  console.error('Usage: node index.js <text> <output_file>');
  process.exit(1);
}

const text = process.argv[2];
const outputFile = process.argv[3];

generateTTS(text, outputFile);

Technical Analysis

The destination path is taken directly from process.argv[3] and passed to fs.writeFileSync without path validation, directory restrictions, file-type checks, symlink checks, or exclusive-creation semantics. writeFileSync overwrites an existing target by default.

A caller can provide an absolute path or a path containing traversal components such as ../. If the process has permission to write the resolved target, the API response bytes will replace that file. A symlink located at an apparently acceptable destination could also redirect the write to another writable target.

The generated content is obtained from the configured remote TTS service rather than being fully controlled as arbitrary local plaintext. Nevertheless, it is attacker-influenced binary data and can corrupt any writable target.

Attack Path

  1. An attacker gains control over, or can influence, the output_file command-line argument used by an agent, wrapper, service, or automation workflow.
  2. The attacker supplies an absolute path, traversal path, or symlink path that resolves to a sensitive file writable by the Node.js process.
  3. The application sends the supplied text to TogetherAI.
  4. After a successful response, the applicat ...[truncated 862 chars]
Remediation
View remediation

Remediation Suggestions

  • Define a dedicated output directory and prohibit writes outside it.
  • Resolve both the allowed directory and requested destination to canonical absolute paths, then verify that the destination remains inside the allowed directory.
  • Reject absolute paths, traversal components, unexpected extensions, and paths that resolve through symbolic links.
  • Generate the destination filename internally when caller-selected filenames are unnecessary.
  • Use exclusive creation, such as the wx flag, to prevent silent overwrites unless overwrite behavior has been explicitly authorized.
  • Run the skill under a minimally privileged account with access only to its required output directory.
  • Validate the returned payload and enforce a maximum response size before writing it.

Example restricted-write approach:

js
const path = require('path');

const outputDir = path.resolve(process.cwd(), 'output');
const safeName = path.basename(outputFile);

if (!safeName.toLowerCase().endsWith('.mp3')) {
  throw new Error('Only MP3 output files are allowed');
}

const destination = path.resolve(outputDir, safeName);
if (!destination.startsWith(outputDir + path.sep)) {
  throw new Error('Invalid output path');
}

fs.writeFileSync(destination, Buffer.from(audioData, 'base64'), {
  flag: 'wx',
  mode: 0o600,
});
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (5)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script sends arbitrary command-line text to a third-party TTS service without any notice, confirmation, or guardrails. This creates a real data exposure risk because users may supply sensitive content assuming it is processed locally, while the skill silently transmits it off-host to an external provider.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

This code makes an outbound request to an external API endpoint and includes user-supplied text in the request body. External transmission is not inherently malicious, but in this skill context it is security-relevant because there is no transparency, restriction, or validation around what data may leave the environment.

Content

Scanner excerpt · index.js (reported line 14)May include surrounding context.

js
async function generateTTS(text, outputFile) {
  try {
    const response = await axios.post(
      'https://api.together.ai/v1/audio/speech',
      {
        text,
        model,

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency dotenv is also specified with a caret range (^16.3.1), allowing version drift across environments and over time. While not inherently exploitable by itself, unpinned dependencies increase supply-chain risk and make builds less reproducible, which is a recognized security weakness.

Content

Scanner excerpt · package.json (reported line 1)May include surrounding context.

json
{"name":"togetherai_tts","version":"1.0.1","description":"Text-to-speech using TogetherAI API with MiniMax speech-2.6-turbo model","main":"index.js","scripts":{},"keywords":["tts","speech","togetherai","minimax"],"author":"Marc","license":"MIT","dependencies":{"axios":"^1.6.0","dotenv":"^16.3.1"}}

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency dotenv is also specified with a caret range (^16.3.1), allowing version drift across environments and over time. While not inherently exploitable by itself, unpinned dependencies increase supply-chain risk and make builds less reproducible, which is a recognized security weakness.

Content

Scanner excerpt · package.json (reported line 1)May include surrounding context.

json
{"name":"togetherai_tts","version":"1.0.1","description":"Text-to-speech using TogetherAI API with MiniMax speech-2.6-turbo model","main":"index.js","scripts":{},"keywords":["tts","speech","togetherai","minimax"],"author":"Marc","license":"MIT","dependencies":{"axios":"^1.6.0","dotenv":"^16.3.1"}}

Unverifiable Dependency: axios has 16 known advisory(ies) (CVE-2026-44494 (axios Vulnerable to Full Man-in-the-Middle via Prototype Pollution Gadget in `co); CVE-2026-44495 (axios Vulnerable to Credential Theft and Response Hijacking via Prototype Pollut); CVE-2025-62718 (Axios has a NO_PROXY Hostname Normalization Bypass that Leads to SSRF) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The manifest references axios without an exact pinned version, and axios has numerous published advisories affecting some releases. Because the allowed version range is broad, it is not possible to verify from this file alone whether the installed version is safe, creating uncertainty that can mask known vulnerable dependency resolution.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
index.js:6