Back to skill

Security audit

Transformers.js

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent Transformers.js documentation, but it needs review because an authentication example can forward a Hugging Face token to any configured model host.

Install only if you are comfortable treating this as example documentation, not hardened production guidance. Before copying the auth example, restrict tokens to trusted Hugging Face hosts, use read-only scoped tokens, avoid sending credentials to custom CDNs or proxies, pin package and model revisions for production, and replace `innerHTML` examples with safer DOM APIs when displaying model metadata.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
references/CONFIGURATION.md:262
Finding

Unrestricted Bearer Token Forwarding to Configurable Remote Hosts

Content
View full analysis

Vulnerability Details

File Location: references/CONFIGURATION.md:262-271
Additional Location: SKILL.md:393-400
Vulnerability Type: Credential disclosure through an unconstrained global fetch wrapper
Risk Level: High

Vulnerable Code

javascript
import { env } from '@huggingface/transformers';

const HF_TOKEN = process.env.HF_TOKEN;

env.fetch = (url, options) =>
  fetch(url, {
    ...options,
    headers: {
      ...options?.headers,
      Authorization: `Bearer ${HF_TOKEN}`,
    },
  });

The same unsafe pattern is repeated in SKILL.md:

javascript
env.fetch = (url, options) =>
  fetch(url, {
    ...options,
    headers: {
      ...options?.headers,
      Authorization: `Bearer ${HF_TOKEN}`,
    },
  });

Technical Analysis

The global env.fetch wrapper adds the Hugging Face bearer token to every URL passed through Transformers.js. It does not validate:

  • The URL scheme
  • The destination hostname
  • Whether the destination is an approved Hugging Face service
  • Whether authentication is required for the requested resource
  • Whether HF_TOKEN is defined

This is particularly dangerous because the same documentation permits applications to configure an arbitrary env.remoteHost, including custom model servers and CDNs. If that host is untrusted, misconfigured, or attacker-controlled, requests to it will include the Hugging Face token.

Authentication is only necessary for private resources hosted by approved services. Sending the token to every model or asset endpoint exceeds least privilege.

Attack Path

  1. An application copies the documented global env.fetch wrapper.
  2. The application configures env.remoteHost from deployment configuration, user-controlled input, or a compromised configuration source.
  3. The host is changed to an attacker-controlled HTTPS server.
  4. Transformers.js requests model configuration, token ...[truncated 844 chars]
Remediation
View remediation

Remediation Suggestions

  1. Parse the target URL before adding authentication.
  2. Require HTTPS and maintain an explicit allowlist of approved authentication destinations.
  3. Do not send Hugging Face credentials to custom CDNs or model servers.
  4. Use separate, narrowly scoped credentials for private custom hosts.
  5. Do not add an Authorization header when the token is absent.
  6. Use read-only, least-privileged tokens for model downloads.
  7. Ensure redirects cannot result in credentials being forwarded to an unapproved destination.

A safer pattern is:

javascript
import { env } from '@huggingface/transformers';

const HF_TOKEN = process.env.HF_TOKEN;
const AUTHORIZED_HOSTS = new Set([
  'huggingface.co',
]);

env.fetch = async (input, options = {}) => {
  const url = new URL(
    typeof input === 'string' ? input : input.url
  );

  if (url.protocol !== 'https:') {
    throw new Error('Model downloads require HTTPS');
  }

  const headers = new Headers(options.headers);

  if (HF_TOKEN && AUTHORIZED_HOSTS.has(url.hostname)) {
    headers.set('Authorization', `Bearer ${HF_TOKEN}`);
  } else {
    headers.delete('Authorization');
  }

  return fetch(input, {
    ...options,
    headers,
    redirect: 'error',
  });
};

Approved Hugging Face asset hosts should be added only after verifying the exact endpoints used by the selected library version.

T09 · Insecure Skill Coding Practices

Warning
Location
references/EXAMPLES.md:127
Finding

DOM Injection Through Unescaped Remote Model File Metadata

Content
View full analysis

Vulnerability Details

File Location: references/EXAMPLES.md:127-136
Additional Location: references/PIPELINE_OPTIONS.md:118-126
Vulnerability Type: DOM-based cross-site scripting through unsafe innerHTML usage
Risk Level: Medium

Vulnerable Code

javascript
if (!fileProgressBars[info.file]) {
  const fileDiv = document.createElement('div');
  fileDiv.className = 'file-progress';
  fileDiv.innerHTML = `
    <div class="file-name">${info.file}</div>
    <div class="progress-bar">
      <div class="progress-fill"></div>
    </div>
  `;
  progressContainer.appendChild(fileDiv);
  fileProgressBars[info.file] = fileDiv.querySelector('.progress-fill');
}

A substantially identical pattern appears in references/PIPELINE_OPTIONS.md:

javascript
if (!fileProgressBars[info.file]) {
  const fileDiv = document.createElement('div');
  fileDiv.innerHTML = `
    <div class="file-name">${info.file}</div>
    <div class="progress-bar">
      <div class="progress-fill" style="width: 0%"></div>
    </div>
  `;
  progressContainer.appendChild(fileDiv);
  fileProgressBars[info.file] = fileDiv.querySelector('.progress-fill');
}

Technical Analysis

The examples interpolate info.file directly into an HTML template and assign it to innerHTML. File metadata associated with a remote model source must not be assumed to be trusted, especially when the documentation supports custom model hosts and arbitrary model repositories.

If an attacker can influence the file name or equivalent progress metadata, HTML markup is parsed in the application's origin. A crafted value containing an element with an event handler can result in DOM-based cross-site scripting. The feasibility of particular payloads can be affected by the application's Content Security Policy, but the unsafe sink remains exploitable in applications without an effective restrictive policy.

Attack Pa

...[truncated 1222 chars]

Remediation
View remediation

Remediation Suggestions

Do not insert remote metadata through innerHTML. Construct the DOM using element APIs and assign untrusted values through textContent:

javascript
if (!fileProgressBars[info.file]) {
  const fileDiv = document.createElement('div');
  fileDiv.className = 'file-progress';

  const fileName = document.createElement('div');
  fileName.className = 'file-name';
  fileName.textContent = String(info.file ?? '');

  const progressBar = document.createElement('div');
  progressBar.className = 'progress-bar';

  const progressFill = document.createElement('div');
  progressFill.className = 'progress-fill';

  progressBar.appendChild(progressFill);
  fileDiv.append(fileName, progressBar);
  progressContainer.appendChild(fileDiv);

  fileProgressBars[info.file] = progressFill;
}

Additionally:

  • Treat all model repository metadata as untrusted.
  • Apply a restrictive Content Security Policy without unsafe-inline.
  • Validate metadata types and impose reasonable length limits.
  • Avoid using untrusted strings directly as ordinary-object keys; use a Map or a null-prototype object where appropriate.

T03 · Remote Payload Retrieval and Execution

Warning
Location
SKILL.md:34
Finding

Mutable Third-Party JavaScript Loaded and Executed Directly from a CDN

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:34-37
Additional Locations: references/EXAMPLES.md:33, references/EXAMPLES.md:107, references/TEXT_GENERATION.md:77
Vulnerability Type: Mutable remote dependency retrieval and execution
Risk Level: Medium

Vulnerable Code

javascript
&lt;script type="module">
  import { pipeline } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers';
&lt;/script>

Other examples pin only the major version:

javascript
import { pipeline } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@4';

Technical Analysis

The browser examples execute JavaScript obtained at runtime from jsDelivr. The main example does not specify a package version, while other examples specify only the mutable major-version range @4.

The effective code can therefore change after the Skill has been reviewed. Applications copying these examples trust both the package publication channel and CDN delivery path each time the page loads. Native module imports in the demonstrated form do not provide a Subresource Integrity attribute.

This is not evidence that the named package or CDN is currently malicious. It is a supply-chain and remote-payload risk caused by executing mutable third-party content without an immutable version or locally audited build.

Attack Path

  1. An application copies the remote module import from the documentation.
  2. The package version remains unpinned or is pinned only to major version 4.
  3. A future package release is compromised, a publisher account is taken over, or CDN content is maliciously altered.
  4. The browser resolves the import URL during page loading.
  5. The changed JavaScript executes automatically as a module in the application's page context.
  6. The malicious dependency performs actions available to page JavaScript, including accessing page data and making network requests.

Impact Assessment

...[truncated 577 chars]

Remediation
View remediation

Remediation Suggestions

  1. Install the dependency locally and commit a lockfile:
bash
npm install --save-exact @huggingface/transformers@4.x.y

Replace 4.x.y with a specific reviewed release.

  1. Bundle the dependency into the application's audited static assets rather than importing it from a mutable CDN URL.
  2. Enforce lockfile integrity in CI and review dependency updates before deployment.
  3. Generate and retain a software bill of materials for production builds.
  4. Apply a restrictive Content Security Policy that limits script-src and connect-src.
  5. If remote delivery is unavoidable, use an immutable versioned asset with cryptographic integrity verification through an import mechanism or build system that supports it.
  6. Pin model revisions to immutable commit identifiers in production, since remote model assets are also part of the inference supply chain.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (9)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
spose()` when finished to prevent memory leaks. See examples in [Code Examples](./references/EXAMPLES.md) for cleanup patterns across different environments.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
spose()` when finished to prevent memory leaks. See examples in [Code Examples](./references/EXAMPLES.md) for cleanup patterns across different environments.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
spose()` when finished to prevent memory leaks. See examples in [Code Examples](./references/EXAMPLES.md) for cleanup patterns across different environments.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
**→ [Pipeline Options - Progress Callback](./references/PIPELINE_OPTIONS.md#progress-callback)**

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
**→ [Pipeline Options - Progress Callback](./references/PIPELINE_OPTIONS.md#progress-callback)**

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill explicitly encourages remote model downloads from Hugging Face Hub and even shows how to attach Authorization headers via a custom fetch, but it does not warn that prompts, file paths, URLs, or other user-supplied inputs may be sent to external infrastructure during model fetches or related remote asset resolution. In a security-sensitive agent context, this omission can lead to unintentional data egress, use of untrusted third-party model artifacts, and leakage of credentials or sensitive content to external services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file documents use of env.fetch to attach a bearer token from process.env.HF_TOKEN to outbound requests. While the section describes the mechanism, it does not warn users that credentials will be sent over the network or advise caution when targeting custom hosts or proxies.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill manifest describes support for a wide range of NLP, vision, audio, and multimodal tasks, but this example file explicitly states that all examples use only the feature-extraction task with a single MiniLM model. This is not a security bug, but it is a genuine description-to-behavior mismatch between the broad stated capability and what this documented file actually demonstrates.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This markdown file contains browser, Node.js, React, and Express examples that load models from remote sources and accept arbitrary user text for embedding, but the description does not warn that using these examples can involve network activity and transmission of user-provided input to an API endpoint. For markdown files, SQP-2 applies when the skill description omits warnings about behaviors that could affect user data, privacy, or system integrity.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.