Back to skill

Security audit

InfoQuest Web Search

Security checks for vulnerabilities and agentic risk

Overview

This is a straightforward BytePlus InfoQuest search and extraction skill that sends user queries or URLs to BytePlus as expected and shows no hidden persistence or local data access.

Install only if you are comfortable with BytePlus receiving the searches, URLs, and page content you ask this skill to process. Avoid using it with secrets, private internal URLs, proprietary documents, or regulated personal data unless that use is approved, and prefer Node.js 18 or newer to avoid the optional unpinned node-fetch install path.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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)

T01 · Skill Instruction Hijacking

Warning
Location
extract.mjs:104
Finding
Untrusted Web Content Is Exposed to the Agent Without Safety Boundaries## Vulnerability Details **File Location**: `extract.mjs:104-123, 137-142`; `search.mjs:120-171, 286-305` **Vulnerability Type**: Untrusted-content prompt injection **Risk Level**: Medium ### Vulnerable Code `extract.mjs:104-123`: ```js const text = await response.text(); if (!text || !text.trim()) { return 'Error: no result found'; } // Try to parse as JSON and extract reader_result try { const jsonData = JSON.parse(text); if (jsonData.reader_result) { return jsonData.reader_result; } else if (jsonData.content) { return 'Error: fetch API return wrong format'; } } catch { // Not JSON, return as-is } return text; ``` `extract.mjs:137-142`: ```js if (content.startsWith('Error:')) { console.error(`Error: ${content}`); process.exit(1); } console.log(formatContent(content, url)); ``` `search.mjs:120-137`: ```js // Process organic results if (results.organic) { for (const result of results.organic) { const cleanResult = { type: 'page' }; if (result.title) cleanResult.title = result.title; if (result.desc) cleanResult.desc = result.desc; if (result.url) cleanResult.url = result.url; const url = cleanResult.url; if (url && !seenUrls.has(url)) { seenUrls.add(url); cleanResults.push(cleanResult); } } } ``` `search.mjs:286-305`: ```js if (isImageSearch) { results = await performImageSearch(query, site, days > 0 ? days : -1, imageSize); console.log(JSON.stringify({ query: query, total_results: results.length, results: results, usage_hint: "Use the 'image_url' values as reference images in image generation. Download them first if needed." }, null, 2)); } else { results = await performWebSearch(query, site, days > 0 ? days : -1); console.log(JSON.stringify({ query, search_type: searchType, count: results.length, results }, ...[truncated 2127 chars]
Remediation
## Remediation Suggestions 1. Wrap all search and extraction output in a structured envelope that explicitly labels it as untrusted external data. 2. Add a warning for the consuming agent stating that commands, policies, credentials requests, or tool-use instructions found in returned content must not be followed. 3. Prefer a strict JSON schema with separate fields for metadata and content rather than emitting free-form page bodies. 4. Remove active HTML elements and non-content material, including scripts, styles, hidden text, and embedded metadata not required for extraction. 5. Apply prompt-injection detection or flagging before returning content. Detection should supplement rather than replace isolation because filters can be bypassed. 6. Ensure the calling agent treats Skill output as data with lower precedence than system, developer, and user instructions. 7. Require confirmation before any subsequent privileged action is based solely on instructions found in retrieved content.

T08 · Insecure Dependencies

Note
Location
SKILL.md:94
Finding
Unpinned Runtime Dependency Installation Creates Supply-Chain Risk## Vulnerability Details **File Location**: `SKILL.md:94-100`; `search.mjs:16-25`; `extract.mjs:14-23` **Vulnerability Type**: Unpinned third-party runtime dependency **Risk Level**: Low ### Vulnerable Code `SKILL.md:94-100`: ```bash # Node.js 18+ includes fetch natively # For older versions, install node-fetch npm install node-fetch ``` `search.mjs:16-25`: ```js fetchImplementation = async (...args) => { try { const { default: fetch } = await import('node-fetch'); return fetch(...args); } catch (error) { throw new Error( 'Fetch API not available. Node.js 18+ includes fetch natively. ' + 'For older versions, install node-fetch: npm install node-fetch' ); } }; ``` `extract.mjs:14-23`: ```js fetchImplementation = async (...args) => { try { const { default: fetch } = await import('node-fetch'); return fetch(...args); } catch (error) { throw new Error( 'Fetch API not available. Node.js 18+ includes fetch natively. ' + 'For older versions, install node-fetch: npm install node-fetch' ); } }; ``` ### Technical Analysis Users of Node.js versions below 18 are instructed to install `node-fetch` without a fixed version, lockfile, or integrity constraint. Both scripts then dynamically import and execute whichever version is resolved in the local environment. `node-fetch` is not a suspiciously named dependency, and the reviewed project contains no evidence that it intentionally resolves a malicious package. The weakness is that future installation results are not reproducible or constrained. A compromised package release, registry account, dependency chain, or local package-resolution environment could therefore introduce code not covered by this audit. ### Attack Path 1. A user runs the Skill on a Node.js release without global `fetch`. 2. The user follows the documentation and executes `npm install node-fetc ...[truncated 825 chars]
Remediation
## Remediation Suggestions 1. Require a supported Node.js version with built-in `fetch`, then remove the dynamic `node-fetch` fallback and installation instruction. 2. If legacy Node.js support is necessary, add an explicit `package.json` dependency with a reviewed, exact version. 3. Commit a generated lockfile containing package integrity metadata and use `npm ci` for reproducible installations. 4. Enable automated dependency vulnerability and integrity monitoring. 5. Review transitive dependencies before upgrades and avoid automatically accepting unreviewed major versions. 6. Run the Skill with a restricted environment containing only the required `INFOQUEST_API_KEY` and with minimal filesystem and network permissions.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Lp3

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding
The skill advertises and requires an environment secret and makes network-backed requests, but it does not declare an explicit tool scope such as permissions or allowed-tools. That creates a transparency and governance gap: consumers and enforcement layers may not clearly understand that the skill can access secrets and transmit data externally, increasing the chance of unintended secret use or data egress.

Missing User Warnings

Medium
Confidence
98% confidence
Finding
The skill description says it performs web search and content extraction via BytePlus InfoQuest, but it does not clearly warn users that their search queries, submitted URLs, and extracted page content are sent to an external third-party API. This can lead users to provide sensitive prompts, internal URLs, or proprietary content without informed consent, resulting in privacy, confidentiality, or compliance issues.

External Transmission

Medium
Category
Data Exfiltration
Content
const data = prepareCrawlRequestData(url, returnFormat);

  try {
    const response = await fetch('https://reader.infoquest.bytepluses.com', {
      method: 'POST',
      headers,
      body: JSON.stringify(data)
Confidence
60% 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
}

  try {
    const response = await fetch('https://search.infoquest.bytepluses.com', {
      method: 'POST',
      headers,
      body: JSON.stringify(params)
Confidence
60% 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
}

  try {
    const response = await fetch('https://search.infoquest.bytepluses.com', {
      method: 'POST',
      headers,
      body: JSON.stringify(params)
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
This code sends the user's query, and potentially a site filter, in a POST request to a remote BytePlus InfoQuest endpoint. Although the CLI usage explains functionality, it does not clearly warn that user-provided input will be sent off-device to a third-party service.

Static analysis

No suspicious patterns detected.