Back to skill

Security audit

XPR Creative

Security checks for vulnerabilities and agentic risk

Overview

The skill provides the advertised creative delivery tools, but it can publicly publish user content and has network-handling weaknesses that need review before installation.

Install only if you are comfortable with deliverables being sent to external services and potentially becoming public. Before using it, require explicit approval for IPFS uploads and public GitHub repositories, avoid sensitive or proprietary files, use narrowly scoped service tokens, and isolate outbound URL fetching from internal networks.

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

Error
Location
src/index.ts:95
Finding

Unrestricted Server-Side URL Fetching Enables SSRF and Data Disclosure

Content
View full analysis
{ if (!/^https?:\/\//.test(url)) return null; try { const resp = await fetch(url, { signal: AbortSignal.timeout(30000), redirect: 'follow' }); if (!resp.ok) return null; const contentType = resp.headers.get('content-type') || 'application/octet-stream'; const contentLength = parseInt(resp.headers.get('content-length') || '0'); if (contentLength > MAX_DOWNLOAD_SIZE) { console.warn(`[download] Too large: ${contentLength}`); return null; } const arrayBuffer = await resp.arrayBuffer(); if (arrayBuffer.byteLength > MAX_DOWNLOAD_SIZE) return null; return { buffer: Buffer.from(arrayBuffer), mimeType: contentType.split(';')[0].trim() }; } catch (e) { console.error(`[download] Failed: ${url}`, e); return null; } } ``` The URL is reached through the media-delivery handler: ```ts if (source_url) { const downloaded = await downloadFromUrl(source_url); if (downloaded) { buffer = downloaded.buffer; mimeType = downloaded.mimeType || ct; } } ``` PDF image embedding exposes an equivalent request surface: ```ts const allImages = extractImages(content); const imageCache = new Map(); if (allImages.length > 0) { await Promise.allSettled( allImages.slice(0, 10).map(async (img) => { const data = await downloadImage(img.url); if (data) imageCache.set(img.url, data); }) ); } ``` ### Technical Analysis The Skill accepts URLs controlled through `source_url` or embedded Markdown image references and fetches them from the server-side runtime. Validation only checks whether a URL begins with `http://` or `https://`. The implementation doe ...[truncated 2485 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
src/index.ts:535
Finding

Replicate Bearer Token Can Be Forwarded to an Unvalidated Polling Origin

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/index.ts:332
Finding

Code Deliverables Are Unconditionally Published to Public GitHub Repositories

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The stated description presents the skill as general creative tooling, but the documented behavior includes public repo creation, IPFS uploads, remote content fetching, PDF generation with embedded external resources, and third-party AI service calls. This mismatch can mislead operators and users about the real data exposure and execution risks, making unsafe invocation more likely.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explicitly instructs creation of a public GitHub repository without any warning that the repository will be world-readable. This creates a direct risk of publishing confidential code, credentials, internal documents, or copyrighted material if the agent follows the instruction with user-provided content.

Content

No source excerpt is available for this finding.

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
95% confidence
Finding

The anti-refusal instruction pressures the agent to always comply with media-generation requests and discourages safe fallback behavior. Such language can override caution in cases involving policy limits, missing prerequisites, unsafe content, or inappropriate tool use, making risky actions more likely.

Content

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

md
**Code repositories:**
- `create_github_repo` with all source files — creates a public GitHub repo

NEVER say you can't create images or videos — you have the tools!
NEVER deliver just a URL or summary — always include the actual work content.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The store_deliverable flow automatically uploads deliverable content to IPFS when credentials are present, without any explicit user warning that the content may become publicly retrievable and effectively immutable. In this skill context, deliverables may contain sensitive business, personal, or proprietary material, making unintended disclosure particularly risky.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The repository creation tool returns a public GitHub URL after creating a repository with private: false, publishing user-provided files without a strong warning or approval step. In agent workflows, users may not realize generated files, prompts, or embedded credentials are being pushed to a public code-hosting service.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/index.ts (reported line 482)May include surrounding context.

ts
job_id: number; name: string; description?: string; files: Record<string, string>;
    }) => {
      if (!process.env.GITHUB_TOKEN || !process.env.GITHUB_OWNER) {
        return { error: 'GitHub not configured. Set GITHUB_TOKEN and GITHUB_OWNER in .env' };
      }
      const repoUrl = await createGithubRepo(job_id, name, description || `Deliverable for job #${job_id}`, files);
      if (!repoUrl) return { error: 'Failed to create GitHub repository' };

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/index.ts (reported line 515)May include surrounding context.

ts
},
    handler: async ({ prompt, job_id, aspect_ratio }: { prompt: string; job_id?: number; aspect_ratio?: string }) => {
      const token = process.env.REPLICATE_API_TOKEN;
      if (!token) return { error: 'REPLICATE_API_TOKEN not set. Add it to .env to enable AI image generation.' };

      try {
        const createResp = await fetch('https://api.replicate.com/v1/models/google/imagen-3/predictions', {

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · src/index.ts (reported line 599)May include surrounding context.

ts
},
    handler: async ({ prompt, job_id, aspect_ratio }: { prompt: string; job_id?: number; aspect_ratio?: string }) => {
      const token = process.env.REPLICATE_API_TOKEN;
      if (!token) return { error: 'REPLICATE_API_TOKEN not set. Add it to .env to enable AI image generation.' };

      try {
        const createResp = await fetch('https://api.replicate.com/v1/models/google/imagen-3/predictions', {

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises capabilities that involve network access and external side effects, but it does not declare any explicit tool scope or permission boundaries. This increases the chance that an agent can invoke powerful actions without clear least-privilege constraints or user-visible authorization expectations.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill uses broad activation language that does not define when these capabilities should or should not be used. In practice, vague triggers can cause over-invocation of tools that fetch remote content, generate artifacts, or publish outputs, increasing the risk of unintended data disclosure or unsafe side effects.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill description says it provides creative deliverable tools, but the implementation also publishes content to public IPFS and creates public GitHub repositories. That mismatch can mislead operators and users about the true data-exfiltration and publication surface, reducing informed consent and weakening review controls.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/index.ts (reported line 51)May include surrounding context.

ts
const jwt = process.env.PINATA_JWT;
  if (!jwt) return null;
  try {
    const resp = await fetch('https://api.pinata.cloud/pinning/pinJSONToIPFS', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${jwt}` },
      body: JSON.stringify({

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/index.ts (reported line 51)May include surrounding context.

ts
const jwt = process.env.PINATA_JWT;
  if (!jwt) return null;
  try {
    const resp = await fetch('https://api.pinata.cloud/pinning/pinJSONToIPFS', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${jwt}` },
      body: JSON.stringify({

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/index.ts (reported line 72)May include surrounding context.

ts
const jwt = process.env.PINATA_JWT;
  if (!jwt) return null;
  try {
    const resp = await fetch('https://api.pinata.cloud/pinning/pinJSONToIPFS', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${jwt}` },
      body: JSON.stringify({

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/index.ts (reported line 72)May include surrounding context.

ts
const formData = new FormData();
    formData.append('file', new Blob([new Uint8Array(buffer)], { type: mimeType }), filename);
    formData.append('pinataMetadata', JSON.stringify({ name: filename }));
    const resp = await fetch('https://api.pinata.cloud/pinning/pinFileToIPFS', {
      method: 'POST',
      headers: { Authorization: `Bearer ${jwt}` },
      body: formData,

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This code can create public GitHub repositories from user-supplied files using configured credentials, which is a publication capability beyond ordinary 'creative tools'. In an agent setting, this can expose sensitive code, reports, or embedded secrets to the public internet if invoked on unreviewed content.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/index.ts (reported line 333)May include surrounding context.

ts
'Content-Type': 'application/json', 'X-GitHub-Api-Version': '2022-11-28',
  };
  try {
    const createResp = await fetch('https://api.github.com/user/repos', {
      method: 'POST', headers,
      body: JSON.stringify({ name: repoName, description, private: false, auto_init: true }),
    });

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/index.ts (reported line 333)May include surrounding context.

ts
'Content-Type': 'application/json', 'X-GitHub-Api-Version': '2022-11-28',
  };
  try {
    const createResp = await fetch('https://api.github.com/user/repos', {
      method: 'POST', headers,
      body: JSON.stringify({ name: repoName, description, private: false, auto_init: true }),
    });

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/index.ts (reported line 340)May include surrounding context.

ts
'Content-Type': 'application/json', 'X-GitHub-Api-Version': '2022-11-28',
  };
  try {
    const createResp = await fetch('https://api.github.com/user/repos', {
      method: 'POST', headers,
      body: JSON.stringify({ name: repoName, description, private: false, auto_init: true }),
    });

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/index.ts (reported line 342)May include surrounding context.

ts
'Content-Type': 'application/json', 'X-GitHub-Api-Version': '2022-11-28',
  };
  try {
    const createResp = await fetch('https://api.github.com/user/repos', {
      method: 'POST', headers,
      body: JSON.stringify({ name: repoName, description, private: false, auto_init: true }),
    });

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/index.ts (reported line 347)May include surrounding context.

ts
'Content-Type': 'application/json', 'X-GitHub-Api-Version': '2022-11-28',
  };
  try {
    const createResp = await fetch('https://api.github.com/user/repos', {
      method: 'POST', headers,
      body: JSON.stringify({ name: repoName, description, private: false, auto_init: true }),
    });

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/index.ts (reported line 353)May include surrounding context.

ts
'Content-Type': 'application/json', 'X-GitHub-Api-Version': '2022-11-28',
  };
  try {
    const createResp = await fetch('https://api.github.com/user/repos', {
      method: 'POST', headers,
      body: JSON.stringify({ name: repoName, description, private: false, auto_init: true }),
    });

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/index.ts (reported line 358)May include surrounding context.

ts
'Content-Type': 'application/json', 'X-GitHub-Api-Version': '2022-11-28',
  };
  try {
    const createResp = await fetch('https://api.github.com/user/repos', {
      method: 'POST', headers,
      body: JSON.stringify({ name: repoName, description, private: false, auto_init: true }),
    });

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/index.ts (reported line 363)May include surrounding context.

ts
'Content-Type': 'application/json', 'X-GitHub-Api-Version': '2022-11-28',
  };
  try {
    const createResp = await fetch('https://api.github.com/user/repos', {
      method: 'POST', headers,
      body: JSON.stringify({ name: repoName, description, private: false, auto_init: true }),
    });

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · src/index.ts (reported line 518)May include surrounding context.

ts
if (!token) return { error: 'REPLICATE_API_TOKEN not set. Add it to .env to enable AI image generation.' };

      try {
        const createResp = await fetch('https://api.replicate.com/v1/models/google/imagen-3/predictions', {
          method: 'POST',
          headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json', Prefer: 'wait' },
          body: JSON.stringify({ input: { prompt, aspect_ratio: aspect_ratio || '1:1', output_format: 'png' } }),

Static analysis

Detected: suspicious.env_credential_access

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/index.ts:38