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## 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
## 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
Content
node src/cli.mjs scan https://example.com --format markdown --out report.md
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
node src/cli.mjs scan https://example.com --format markdown --out report.md
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Static analysis

No suspicious patterns detected.