Back to skill

Security audit

Auto.dev – Automotive Data

Security checks for vulnerabilities and agentic risk

Overview

This automotive API skill is coherent, but users should review it because some generated server examples can expose paid API usage without enough access controls and its install commands run unpinned global packages.

Install only if you are comfortable giving the Auto.dev SDK/MCP tooling access to configure your agent environment. Pin and verify package versions before running npm/npx commands. If you use the app or webhook templates, add authentication, authorization, rate limits, quotas, spend caps, strict input validation, and fail-closed secret checks before deploying them publicly.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
integration-recipes.md:205
Finding
Webhook Authentication Fails Open When WEBHOOK_SECRET Is Unset<![CDATA[ ## Vulnerability Details **File Location**: `integration-recipes.md:205-210` **Vulnerability Type**: Fail-open authentication caused by comparison of potentially undefined values **Risk Level**: High ### Vulnerable Code ```typescript router.post('/enrich-vin', async (req, res) => { // Authenticate the caller — this route spends API credits. if (req.get('x-webhook-secret') !== process.env.WEBHOOK_SECRET) { return res.status(401).json({ error: 'unauthorized' }); } ``` ### Technical Analysis The authentication check assumes that `WEBHOOK_SECRET` is configured. If the environment variable is absent and the caller also omits the `x-webhook-secret` header, both expressions evaluate to `undefined`. The resulting comparison is: ```typescript undefined !== undefined // false ``` Because the condition is false, the request is treated as authenticated. The route subsequently invokes VIN decode, specifications, and recall endpoints using the server's Auto.dev credentials. Some of these endpoints may be billable. This is a fail-open authentication design. Authentication controls must reject requests when either the configured credential or the supplied credential is missing. The example also lacks rate limiting, replay protection, and caller-specific quotas, increasing the impact of the authentication bypass. ### Attack Path 1. A developer deploys the documented webhook recipe but neglects to configure `WEBHOOK_SECRET`. 2. An attacker sends a request to `POST /enrich-vin`. 3. The attacker omits the `x-webhook-secret` header and supplies a syntactically valid VIN. 4. Both the request header and environment variable resolve to `undefined`. 5. The authentication condition evaluates to false, allowing the request. 6. The server calls Auto.dev endpoints using its own API credentials. 7. The attacker repeats the request to consume API credits or generate billable API traffic. ### Impact Assessment An unauthenticated remote attacker may: - Invoke s ...[truncated 385 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Fail closed when the server secret is unavailable, and reject requests with missing credentials: ```typescript import { timingSafeEqual } from 'node:crypto'; const webhookSecret = process.env.WEBHOOK_SECRET; if (!webhookSecret) { throw new Error('WEBHOOK_SECRET must be configured'); } function validWebhookSecret(supplied: string | undefined): boolean { if (!supplied) return false; const suppliedBuffer = Buffer.from(supplied); const expectedBuffer = Buffer.from(webhookSecret); return suppliedBuffer.length === expectedBuffer.length && timingSafeEqual(suppliedBuffer, expectedBuffer); } router.post('/enrich-vin', async (req, res) => { if (!validWebhookSecret(req.get('x-webhook-secret'))) { return res.status(401).json({ error: 'unauthorized' }); } // Continue only after successful authentication. }); ``` Additional hardening should include: 1. Validate mandatory secrets during application startup. 2. Apply IP-, account-, and route-level rate limits. 3. Add per-caller API quotas and spending limits. 4. Limit request body size. 5. Use signed webhook requests with a timestamp and nonce to prevent replay. 6. Log rejected and accepted calls without logging secrets. 7. Rotate webhook credentials periodically. 8. Return generic authentication errors without revealing configuration state. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
code-patterns.md:427
Finding
Generated Server-Side API Proxies Lack Authentication and Abuse Controls<![CDATA[ ## Vulnerability Details **File Locations**: - `code-patterns.md:427-448` — Next.js listings proxy - `code-patterns.md:550-588` — Express search, VIN, and payment proxies - `code-patterns.md:606-650` — Flask search, VIN, and payment proxies - `integration-recipes.md:317-353` — Zapier listings proxy - `app-scaffolding.md:74` and `app-scaffolding.md:283-284` — instructions to expose server-side proxies without corresponding access-control requirements **Vulnerability Type**: Unauthenticated server-funded API proxy and missing resource-consumption controls **Risk Level**: High ### Vulnerable Code The Next.js example forwards every supplied query parameter using the server's API credential, without authenticating the caller: ```typescript // app/api/listings/route.ts import { NextRequest, NextResponse } from 'next/server'; import { autodevFetch, AutodevError } from '@/lib/autodev'; import type { ListingsResponse } from '@/types/autodev'; export async function GET(request: NextRequest) { const { searchParams } = request.nextUrl; const params: Record<string, string> = {}; for (const [key, value] of searchParams.entries()) { params[key] = value; } try { const data = await autodevFetch<ListingsResponse>('/listings', params); return NextResponse.json(data); } catch (error) { if (error instanceof AutodevError) { return NextResponse.json( { error: error.message, code: error.code }, { status: error.status } ); } return NextResponse.json({ error: 'Internal server error' }, { status: 500 }); } } ``` The Express example similarly exposes multiple operations, including the payments endpoint: ```typescript // routes/vehicles.ts import { Router } from 'express'; import { autodevFetch } from '../lib/autodev'; import type { ListingsResponse, VinDecode, PaymentsResponse } from '../types/autodev'; const router = Router(); router.get('/search', async (req, res) => { try { const { make, model, m ...[truncated 5331 chars]
Remediation
<![CDATA[ ## Remediation Suggestions All generated API proxy templates should include secure-by-default controls: 1. Require authenticated application users before making upstream requests. 2. Enforce authorization policies for paid or privacy-sensitive endpoints. 3. Apply per-user, per-IP, and global rate limits. 4. Add daily and monthly spending ceilings. 5. Define endpoint-specific quotas, especially for payment, build, plate, and enrichment operations. 6. Validate all inputs using strict schemas: - VIN: exactly 17 valid VIN characters. - State: approved two-letter abbreviation. - ZIP code: expected format and length. - Price and payment values: bounded numeric ranges. - Pagination: capped page and limit values. - Query keys: explicit allowlist. 7. Cache safe, repeatable results where appropriate. 8. Add timeouts and concurrency limits for upstream calls. 9. Avoid returning unnecessary upstream metadata or internal error details. 10. Add monitoring and alerts for abnormal call volume or billing changes. 11. Use CSRF defenses when authentication relies on cookies. 12. Document that server-side credential storage alone is not an authorization control. A hardened route should authenticate first, validate an allowlisted schema, enforce quotas, and only then call Auto.dev: ```typescript export async function GET(request: NextRequest) { const user = await requireAuthenticatedUser(request); await enforceRateLimit(`listings:${user.id}`); const parsed = ListingsQuerySchema.safeParse( Object.fromEntries(request.nextUrl.searchParams) ); if (!parsed.success) { return NextResponse.json({ error: 'Invalid query' }, { status: 400 }); } await enforceUsageQuota(user.id, 'listings'); const data = await autodevFetch<ListingsResponse>( '/listings', parsed.data ); return NextResponse.json(data); } ``` ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:37
Finding
Unpinned Installation Commands Execute Third-Party Code and Modify Agent Configuration<![CDATA[ ## Vulnerability Details **File Locations**: - `SKILL.md:37-45` - `SKILL.md:85-86` - `README.md:28-40` - `README.md:53-66` - `README.md:195-211` **Vulnerability Type**: Unpinned third-party dependency execution and broad installation scope **Risk Level**: Medium ### Vulnerable Installation Instructions ```markdown To install: `npx @auto.dev/sdk mcp install` (installs globally and configures Claude Code, Claude Desktop, Cursor, Windsurf, VS Code Copilot, Cline, Zed). To install: `npm install -g @auto.dev/sdk` or use `npx @auto.dev/sdk <command>` without installing. To install: `npm install @auto.dev/sdk` ``` The README repeats globally scoped and unpinned installation commands: ```bash npm install -g @auto.dev/sdk ``` ```bash auto mcp install ``` ```bash npx skills add drivly/auto-dev-skill ``` It also recommends unpinned update operations: ```bash npx skills update npm update -g @auto.dev/sdk ``` ### Technical Analysis The project does not include the source code, lockfile, integrity hashes, or lifecycle scripts for `@auto.dev/sdk`, the `skills` installer, or the `clawhub` installer. Their behavior therefore cannot be verified from the audited artifact. Commands such as `npx` may download and immediately execute the currently resolved package version. Since no exact version or integrity digest is specified, the executed code can differ from what was expected when the Skill was reviewed. Global package installation and `auto mcp install` also have a broader security scope than a local library installation. The documentation states that MCP installation modifies configurations for several AI tools. A compromised or unexpectedly changed package could therefore execute with the user's permissions and alter multiple Agent configurations. No evidence was found that the currently referenced packages are malicious. This finding concerns the unbounded supply-chain trust and execution model, not a confirmed malicious package payload. ### Attack P ...[truncated 1279 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin exact package versions in every installation command: ```bash npm install --save-exact @auto.dev/sdk@<reviewed-version> npx --yes @auto.dev/sdk@<reviewed-version> mcp install ``` 2. Publish and verify package integrity hashes or signed provenance. 3. Include a lockfile for reproducible project installations. 4. Recommend local installation instead of global installation where feasible. 5. Instruct users to inspect package metadata and lifecycle scripts before installation: ```bash npm view @auto.dev/sdk version dist.integrity scripts ``` 6. Use `npm install --ignore-scripts` where lifecycle scripts are not required. 7. Document every file and Agent configuration modified by `auto mcp install`. 8. Require explicit confirmation before changing configuration for each detected Agent. 9. Back up existing configuration before modification and provide a rollback procedure. 10. Separate update checks from update execution; do not automatically install unreviewed versions. 11. Audit `@auto.dev/sdk`, the `skills` installer, and their transitive dependencies independently. 12. Prefer packages with signed releases, registry provenance, and publicly reviewable source corresponding to the published artifact. ]]>
Vulnerability Patterns
  • 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
  • Rogue AgentSelf-Modification, Session Persistence
Findings (50)

Credential Access

High
Category
Privilege Escalation
Content
autodev.ts              — API client (from code-patterns.md)
  types/
    autodev.ts              — TypeScript types (from code-patterns.md)
  .env.local                — AUTODEV_API_KEY
```

### Key Pages
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
autodev.ts              — API client (from code-patterns.md)
  types/
    autodev.ts              — TypeScript types (from code-patterns.md)
  .env.local                — AUTODEV_API_KEY
```

### Key Pages
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
### Environment Variable (All Frameworks)

```bash
# .env or .env.local
AUTODEV_API_KEY=sk_ad_your_key_here
```
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Vague Triggers

Medium
Confidence
96% confidence
Finding
The manifest description says to use the skill for 'any automotive data task' and lists many broad domains, which creates an activation scope that can overlap with ordinary automotive questions rather than a narrowly bounded invocation condition. It does not provide explicit trigger phrases, exclusions, or negative examples to constrain when the skill should or should not activate.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
The skill instructs users to execute `npx @auto.dev/sdk` without pinning a specific version, which creates a supply-chain risk: future package updates or a compromised release could execute unexpected code at install/runtime. Because this command is presented as the installation path for MCP tooling, it could affect any environment where the skill is followed as written.

Rp1

Medium
Category
MCP Rug Pull
Confidence
90% confidence
Finding
This line again recommends installing `@auto.dev/sdk` via an unpinned `npx` invocation, allowing whatever version is latest at execution time to run code in the user's environment. Unpinned execution is a recognized supply-chain weakness, especially for globally installed developer tooling.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding
The CLI quick reference tells users they can use `npx @auto.dev/sdk` without installing, but without a version pin this executes a mutable remote package. If the package is updated maliciously or unexpectedly, users invoking the documented command may run attacker-controlled code.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- **Chain APIs** when the query spans multiple endpoints — MCP tools and CLI commands can be called in parallel
- **Sensitive inputs**: `creditScore`, `zip`, and the price / trade-in / down-payment fields on `/apr`, `/payments`, and `/taxes` are transmitted to the Auto.dev API. Ask the user for these values rather than inferring them, send only what the endpoint requires, and don't persist or echo them beyond the answer.
- **Plate lookups** (`/plate/{state}/{plate}`) resolve a license plate to a specific vehicle and can identify its owner. Confirm the user has a legitimate purpose, and never run them in bulk against plates the user did not supply.
- **When writing exports to disk**, confirm the destination path first and don't overwrite an existing file without asking.

## Deep Reference
Confidence
75% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The activation condition says to use these templates whenever a developer asks to build a complete application with Auto.dev, which is a broad natural-language condition rather than a tightly scoped invocation rule. It does not provide exclusion conditions or clarify when the scaffolding should not be used, increasing the chance of unintended invocation for generic app-building requests.

Vague Triggers

Medium
Confidence
94% confidence
Finding
Phrases like "Build me a used car search app" and especially "Create a vehicle marketplace" are broad product requests that could arise in ordinary development conversations. The file treats them as activation examples without clarifying boundaries or whether other adjacent requests should trigger the skill.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The file explicitly says to match broad user-described 'business needs' to prebuilt workflows, which creates an overly permissive activation surface for the skill. In an agent setting, this can cause the automotive skill to trigger on generic business-analysis requests and unnecessarily access or influence automotive data workflows when the user did not clearly intend to use this capability.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrase 'I'm considering buying this car, run a full check' is generic enough that many ordinary purchase-assistance requests could activate a high-capability due-diligence workflow. Because that workflow chains VIN decoding, recall checks, photos, payment calculations, and total-cost analysis, accidental or overbroad invocation increases the chance of unnecessary data access and incorrect tool routing.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The examples send VINs, license plate data, ZIP codes, prices, and credit score inputs to external APIs without any warning that these can be sensitive or regulated data elements. In a code-patterns skill, developers may copy these examples directly into production flows, causing privacy, consent, or compliance issues if user data is transmitted without disclosure or minimization.

Intent-Code Divergence

Medium
Confidence
96% confidence
Finding
Line L005 states that 'All integrations use a polling pattern,' which directly conflicts with later recipes that implement webhook receivers and webhook endpoints for external systems and Zapier/Make (L174-L250, L307-L367). This is an active contradiction in the file's guidance, not merely an omitted detail.

Session Persistence

Medium
Category
Rogue Agent
Content
### Cron Setup

```bash
# crontab -e
# Run every 6 hours
0 */6 * * * node /path/to/jobs/inventory-monitor.js
```
Confidence
85% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Vague Triggers

Medium
Confidence
90% confidence
Finding
The instruction says, "When a user starts a broad search, treat it as the beginning of an interactive session," but it does not define what counts as a broad search or when the mode should not activate. This ambiguity can cause unintended invocation during ordinary search-like conversation because there are no explicit constraints or negative examples.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The enrichment trigger phrases are broad enough that ordinary conversational language like 'are these safe?' or 'tell me more about this one' can automatically invoke additional API calls with cost and data-access implications. In this skill context, that creates a real prompt-driven overreach risk: an attacker or accidental phrasing could cause excessive enrichment, unnecessary spending, or expanded processing of vehicle/VIN-linked data without sufficiently explicit user consent.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
code-patterns.md:89

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
integration-recipes.md:257

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
README.md:89