T09 · Insecure Skill Coding Practices
- 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: HighVulnerable 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.fetchwrapper 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_TOKENis 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
- An application copies the documented global
env.fetchwrapper. - The application configures
env.remoteHostfrom deployment configuration, user-controlled input, or a compromised configuration source. - The host is changed to an attacker-controlled HTTPS server.
- Transformers.js requests model configuration, token ...[truncated 844 chars]
- Remediation
View remediation
Remediation Suggestions
- Parse the target URL before adding authentication.
- Require HTTPS and maintain an explicit allowlist of approved authentication destinations.
- Do not send Hugging Face credentials to custom CDNs or model servers.
- Use separate, narrowly scoped credentials for private custom hosts.
- Do not add an
Authorizationheader when the token is absent. - Use read-only, least-privileged tokens for model downloads.
- 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.
