Back to skill

Security audit

AI Website Check

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly a disclosed read-only website checker, but its redirect handling can make your machine request unexpected internal or third-party URLs, so it needs review before install.

Install only if you are comfortable with a website scanner making outbound GET requests from your machine. Until redirect and private-address validation are added, avoid scanning untrusted URLs or attacker-controlled sites from environments that can reach sensitive internal services.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
src/core.mjs:13
Finding

Same-Origin Redirect Validation Bypass Enables Server-Side Request Forgery

Content
View full analysis

Vulnerability Details

File Location: src/core.mjs:8-20, src/core.mjs:71-73, and src/core.mjs:79-84
Vulnerability Type: Server-Side Request Forgery through unchecked redirects
Risk Level: Medium

Complete Code Snippets

javascript
export async function fetchEvidence(url, { timeoutMs = 10_000, signal } = {}) {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), timeoutMs);
  const abort = () => controller.abort();
  signal?.addEventListener('abort', abort, { once: true });
  try {
    const response = await fetch(url, { redirect: 'follow', signal: controller.signal, headers: { accept: 'text/html,application/xhtml+xml,text/plain;q=0.9,*/*;q=0.1', 'user-agent': 'AIWebsiteCheck/0.1 (+read-only assessment)' } });
    const contentType = response.headers.get('content-type') || '';
    const body = await response.text();
    return { url: response.url, requestedUrl: url, status: response.status, ok: response.ok, contentType, body: body.slice(0, MAX_BODY_BYTES), truncated: body.length > MAX_BODY_BYTES };
  } catch (error) {
    return { url, requestedUrl: url, status: null, ok: false, contentType: '', body: '', error: error.name === 'AbortError' ? 'timeout' : error.message };
  } finally { clearTimeout(timer); signal?.removeEventListener('abort', abort); }
}
javascript
const page = await fetchEvidence(target.href, options);
const root = new URL(page.url || target.href).origin;
const [robots, sitemap, llms] = await Promise.all(['robots.txt', 'sitemap.xml', 'llms.txt'].map((path) => fetchEvidence(new URL(`/${path}`, root).href, options)));
javascript
export async function runJourney(baseUrl, definition, options = {}) {
  if (!definition || !Array.isArray(definition.steps) || !definition.steps.length) throw new Error('Journey JSON must contain a non-empty steps array.');
  const base = new URL(baseUrl);
  const step
...[truncated 3208 chars]
Remediation
View remediation

Remediation Suggestions

  1. Set redirect: 'manual' and implement an explicit redirect loop with a strict maximum redirect count.
  2. Resolve each Location value relative to the current URL and validate every redirect before issuing the next request.
  3. For journey mode, require every redirect destination to retain the origin authorized by the original baseUrl, rather than validating only the initial step.
  4. For scan mode, decide whether redirects are allowed. If allowed, clearly define whether discovery requests remain bound to the original origin or require explicit authorization for the final origin.
  5. Resolve destination hostnames and reject loopback, link-local, private, multicast, unspecified, and other restricted IP ranges when those destinations are outside the intended assessment scope.
  6. Revalidate after DNS resolution and on every redirect to reduce DNS rebinding and redirect-chain bypass risks. Apply equivalent checks to IPv4, IPv6, and IPv4-mapped IPv6 addresses.
  7. Add tests covering public-to-private redirects, cross-origin journey redirects, multi-hop redirect chains, IPv6 loopback, and redirects that change origin before discovery requests are generated.
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
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (2)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/cli.mjs scan https://example.com --format markdown --out report.md

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
node src/cli.mjs scan https://example.com --format markdown --out report.md