T08 · Insecure Dependencies
- Location
scripts/daily-brief.mjs:10- Finding
Execution of an Unpinned External Script Dependency
- Content
View full analysis
Vulnerability Details
File Location:
scripts/daily-brief.mjs:10-29andscripts/search-tavily.mjs:11-30
Vulnerability Type: Unverified external executable dependency
Risk Level: MediumVulnerable Code
From
scripts/daily-brief.mjs:js // Tavily script absolute path const TAVILY_SCRIPT = '/home/admin/.openclaw/workspace/skills/tavily-search/scripts/search.mjs'; // Search query templates const queries = { companies: "OpenAI OR Google AI OR Microsoft AI OR Meta AI OR Anthropic OR DeepMind news yesterday", leaders: "Sam Altman OR Satya Nadella OR Sundar Pichai OR Mark Zuckerberg OR Dario Amodei AI statement yesterday", products: "LLM OR AI Agent OR AI Skills OR RAG new release launch product announcement yesterday", papers: "arXiv cs.CL cs.LG cs.AI LLM Agent RAG knowledge base paper yesterday" }; // Execute Tavily search function searchTavily(query, count = 10, topic = 'news') { try { const cmd = `node "${TAVILY_SCRIPT}" "${query}" -n ${count} --topic ${topic}`; const result = execSync(cmd, { encoding: 'utf8', maxBuffer: 10 * 1024 * 1024 }); return result; } catch (error) { console.error(`Tavily search failed for query: ${query}`); console.error(error.message); return null; } }The same execution pattern appears in
scripts/search-tavily.mjs:js // Tavily script absolute path const TAVILY_SCRIPT = '/home/admin/.openclaw/workspace/skills/tavily-search/scripts/search.mjs'; // Execute Tavily search function searchTavily(query, count = 10, topic = 'news') { try { const cmd = `node "${TAVILY_SCRIPT}" "${query}" -n ${count} --topic ${topic}`; const result = execSync(cmd, { encoding: 'utf8', maxBuffer: 10 * 1024 * 1024 }); return result; // Return raw markdown output } catch (error) { console.error(`Tavily search failed for query: ${query}`); console.error(error.message); return null; ...[truncated 2277 chars]- Remediation
View remediation
Remediation Suggestions
- Replace the external script invocation with direct Tavily API calls from audited project code.
- If a reusable dependency is required, package it through a lockfile-based dependency manager and pin an exact version.
- Verify the dependency's cryptographic hash or signature before execution when bundling is not possible.
- Confirm that the external file and all parent directories are owned by a trusted administrative account and are not writable by less-privileged users.
- Remove the machine-specific absolute path and use an explicitly configured, validated dependency location.
- Replace
execSync()withexecFileSync()orspawnSync()and pass each argument separately, avoiding shell parsing:
js import { execFileSync } from 'node:child_process'; const result = execFileSync( process.execPath, [validatedScriptPath, query, '-n', String(count), '--topic', topic], { encoding: 'utf8', maxBuffer: 10 * 1024 * 1024, shell: false } );- Validate
countas a bounded integer and restricttopicto an explicit allowlist even if these values later become externally configurable. - Run the search component with minimal filesystem permissions and expose only the API credentials required for its operation.
