T09 · Insecure Skill Coding Practices
- Location
hunt.js:12- Finding
Unsanitized Remote Job Data Rendered as Markdown Output
- Content
View full analysis
Vulnerability Details
File Location:
hunt.js, lines 12-18 and 47-51
Vulnerability Type: Untrusted remote-content injection
Risk Level: MediumVulnerable Code
js title: j.position, company: j.company, salary: j.salary_min ? `$${j.salary_min}-${j.salary_max}` : 'Not specified', url: j.url, tags: j.tags || [], date: j.datejs function formatOutput(jobs) { if (jobs.length === 0) return 'No matching jobs found.'; return jobs.slice(0, 10).map((job, i) => `${i+1}. **${job.title}** @ ${job.company}\n 💰 ${job.salary}\n 🔗 ${job.url}` ).join('\n\n'); }Technical Analysis
The skill obtains job records from
https://remoteok.com/apiand accepts the remoteposition,company, salary, and URL fields without validation or sanitization.formatOutput()then interpolates these fields directly into Markdown-like output.Because the API response is outside the skill's trust boundary, a malicious listing or compromised upstream feed can supply Markdown metacharacters, deceptive links, instruction-like text, or terminal control characters. The resulting content may alter how the output is displayed or be interpreted as instructions by a downstream AI agent.
This does not directly execute operating-system commands in the audited implementation. Exploitation depends on attacker influence over the remote feed and on how the generated output is rendered or consumed.
Attack Path
- An attacker publishes a crafted job listing on the supported service or compromises the upstream API.
- The listing places malicious content in a rendered field such as
position,company, orurl. fetchJobs()downloads the listing from the RemoteOK API.- The source parser copies the attacker-controlled fields into local job objects without validation.
formatOutput()inserts those values verbatim into Markdown-like output.- A Markdown renderer, terminal, ...[truncated 740 chars]
- Remediation
View remediation
Remediation Suggestions
- Treat every field received from the job API as untrusted data.
- Strip ANSI escape sequences and other nonessential control characters.
- Escape Markdown metacharacters in job titles, company names, and salary values before rendering.
- Parse URLs with
new URL()and permit only approved schemes, preferablyhttps:. - Consider restricting links to expected domains or clearly label external destinations.
- Apply reasonable length limits and type checks to every remote field.
- Keep remote records structurally separated from agent instructions and explicitly identify them as untrusted data.
- If output is consumed by another agent, use a structured format such as validated JSON rather than instruction-like free text.
- Add tests containing crafted Markdown links, embedded instructions, control characters, malformed URLs, and oversized fields.
