T09 · Insecure Skill Coding Practices
- Location
SKILL.md:24- Finding
API Credential Exposed Through URL Query Parameters
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is a coherent CarsXE API integration, but it exposes sensitive owner and resident lookup workflows with weak consent, scoping, and data-minimization guidance.
Review this skill carefully before installing, especially if your CarsXE key has Enterprise ownership access. Use a separate least-privilege key for ordinary vehicle lookups, require explicit user approval before VIN, plate, OCR image, bulk VIN, lien/theft, or ownership queries, avoid ownership ZIP/person/address searches unless you have a legitimate authorized purpose, and treat expanded request URLs and returned owner data as sensitive.
SKILL.md:24API Credential Exposed Through URL Query Parameters
references/ownership.md:1Ownership Lookups Default to Excessive Personal-Data Disclosure
The skill advertises ownership and registered-owner lookups without any warning, consent requirement, or eligibility restriction, despite these endpoints processing highly sensitive personal data. This creates a real privacy and misuse risk because an agent may facilitate deanonymization or surveillance-style queries with no built-in notice or gating.
The README states that agents automatically call the CarsXE API on every request, which means VINs, license plates, ownership queries, OCR images, and other potentially sensitive vehicle-related data may be sent to a third party without any explicit privacy notice or consent guidance. In the context of this skill, that omission is important because several supported endpoints involve personal or regulated data, increasing the risk of unintentional disclosure.
The trigger text is extremely broad (e.g., 'any automotive data query' and 'always use this skill'), which can cause the agent to invoke an external data-sharing skill for loosely related requests without clear necessity or user awareness. In this context, over-invocation is risky because the skill can send sensitive identifiers such as VINs, plates, ownership data, and images to a third-party API.
This skill is fundamentally designed around transmitting user data to api.carsxe.com, an external service. External transmission is not inherently malicious here, but it is security-relevant because the transmitted data can include VINs, license plates, ownership-related identifiers, and image URLs, and the skill lacks corresponding consent/privacy controls.
automotive data query. Always use this skill when working with CarsXE APIs — do not guess API
behavior without it.
version: 1.2.0
homepage: https://api.carsxe.com/docs
---
# CarsXE Skill
The skill does not warn that user-supplied VINs, license plates, addresses, OBD codes, and especially image URLs will be transmitted to an external service. Users may reasonably expect local interpretation, but the skill silently directs the agent to send these identifiers off-platform, increasing privacy and data-handling risk.
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
## Quick API Map
| User intent | Endpoint | Method | Key Parameters |
| ------------------------------ | --------------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------- |
| Decode a VIN / get specs | `GET /specs` | GET | `vin`, optional: `deepdata`, `disableIntVINDecoding` |
| Decode a license plate | `GET /v2/platedecoder` | GET | `plate`, `country` (required), `state`, `district` (optional) |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| Decode a VIN / get specs | `GET /specs` | GET | `vin`, optional: `deepdata`, `disableIntVINDecoding` |
| Decode a license plate | `GET /v2/platedecoder` | GET | `plate`, `country` (required), `state`, `district` (optional) |
| Market value | `GET /v2/marketvalue` | GET | `vin`, optional: `state`, `mileage`, `condition` |
| Vehicle history report | `GET /history` | GET | `vin` |
| Vehicle images | `GET /images` | GET | `make`, `model`, optional: `year`, `trim`, `color`, `angle`, `photoType`, `size`, `license`, `transparent` |
| Safety recalls (VIN) | `GET /v1/recalls` | GET | `vin` |
| Safety recalls (YMM) | `GET /v1/recalls-ymm` | GET | `year`, `make`, `model` |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| Decode a VIN / get specs | `GET /specs` | GET | `vin`, optional: `deepdata`, `disableIntVINDecoding` |
| Decode a license plate | `GET /v2/platedecoder` | GET | `plate`, `country` (required), `state`, `district` (optional) |
| Market value | `GET /v2/marketvalue` | GET | `vin`, optional: `state`, `mileage`, `condition` |
| Vehicle history report | `GET /history` | GET | `vin` |
| Vehicle images | `GET /images` | GET | `make`, `model`, optional: `year`, `trim`, `color`, `angle`, `photoType`, `size`, `license`, `transparent` |
| Safety recalls (VIN) | `GET /v1/recalls` | GET | `vin` |
| Safety recalls (YMM) | `GET /v1/recalls-ymm` | GET | `year`, `make`, `model` |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| Decode a VIN / get specs | `GET /specs` | GET | `vin`, optional: `deepdata`, `disableIntVINDecoding` |
| Decode a license plate | `GET /v2/platedecoder` | GET | `plate`, `country` (required), `state`, `district` (optional) |
| Market value | `GET /v2/marketvalue` | GET | `vin`, optional: `state`, `mileage`, `condition` |
| Vehicle history report | `GET /history` | GET | `vin` |
| Vehicle images | `GET /images` | GET | `make`, `model`, optional: `year`, `trim`, `color`, `angle`, `photoType`, `size`, `license`, `transparent` |
| Safety recalls (VIN) | `GET /v1/recalls` | GET | `vin` |
| Safety recalls (YMM) | `GET /v1/recalls-ymm` | GET | `year`, `make`, `model` |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| Decode a VIN / get specs | `GET /specs` | GET | `vin`, optional: `deepdata`, `disableIntVINDecoding` |
| Decode a license plate | `GET /v2/platedecoder` | GET | `plate`, `country` (required), `state`, `district` (optional) |
| Market value | `GET /v2/marketvalue` | GET | `vin`, optional: `state`, `mileage`, `condition` |
| Vehicle history report | `GET /history` | GET | `vin` |
| Vehicle images | `GET /images` | GET | `make`, `model`, optional: `year`, `trim`, `color`, `angle`, `photoType`, `size`, `license`, `transparent` |
| Safety recalls (VIN) | `GET /v1/recalls` | GET | `vin` |
| Safety recalls (YMM) | `GET /v1/recalls-ymm` | GET | `year`, `make`, `model` |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| Decode a VIN / get specs | `GET /specs` | GET | `vin`, optional: `deepdata`, `disableIntVINDecoding` |
| Decode a license plate | `GET /v2/platedecoder` | GET | `plate`, `country` (required), `state`, `district` (optional) |
| Market value | `GET /v2/marketvalue` | GET | `vin`, optional: `state`, `mileage`, `condition` |
| Vehicle history report | `GET /history` | GET | `vin` |
| Vehicle images | `GET /images` | GET | `make`, `model`, optional: `year`, `trim`, `color`, `angle`, `photoType`, `size`, `license`, `transparent` |
| Safety recalls (VIN) | `GET /v1/recalls` | GET | `vin` |
| Safety recalls (YMM) | `GET /v1/recalls-ymm` | GET | `year`, `make`, `model` |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| Vehicle history report | `GET /history` | GET | `vin` |
| Vehicle images | `GET /images` | GET | `make`, `model`, optional: `year`, `trim`, `color`, `angle`, `photoType`, `size`, `license`, `transparent` |
| Safety recalls (VIN) | `GET /v1/recalls` | GET | `vin` |
| Safety recalls (YMM) | `GET /v1/recalls-ymm` | GET | `year`, `make`, `model` |
| Safety recalls (batch) | `POST /v1/recalls-batch/submit` | POST | JSON body: `vins` and/or `csv` / `csvUrl`; optional `webhookUrl` |
| Safety recalls (batch) | `GET /v1/recalls-batch/status\|results\|download` | GET | `batchId` |
| Lien & theft check | `GET /v1/lien-theft` | GET | `vin` |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| Safety recalls (VIN) | `GET /v1/recalls` | GET | `vin` |
| Safety recalls (YMM) | `GET /v1/recalls-ymm` | GET | `year`, `make`, `model` |
| Safety recalls (batch) | `POST /v1/recalls-batch/submit` | POST | JSON body: `vins` and/or `csv` / `csvUrl`; optional `webhookUrl` |
| Safety recalls (batch) | `GET /v1/recalls-batch/status\|results\|download` | GET | `batchId` |
| Lien & theft check | `GET /v1/lien-theft` | GET | `vin` |
| International VIN | `GET /v1/international-vin-decoder` | GET | `vin` |
| Year/Make/Model lookup | `GET /v1/ymm` | GET | `year`, `make`, `model`, optional: `trim` |
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.
| Year/Make/Model lookup | `GET /v1/ymm` | GET | `year`, `make`, `model`, optional: `trim` |
| YMM options (dropdowns) | `GET /v1/ymm-options` | GET | optional: `dimension`, `year`, `make`, `model`, `trim` |
| Ownership (Enterprise) | `GET /v1/ownership/vin\|person\|address\|zip` | GET | VIN / name+address+zip / address+zip / zip; optional `include` |
| OBD code diagnosis | `GET /obdcodesdecoder` | GET | `code` |
| VIN OCR from image | `POST /v1/vinocr` | POST | JSON body: `{"image": "<URL>"}` |
| Plate OCR from image | `POST /platerecognition` | POST | JSON body: `{"image": "<URL>"}` |
| Validate API key | `GET /v1/auth/validate` | GET | `key` |
The example requests demonstrate direct transmission of VINs and other vehicle data to an external API. In context this is expected behavior, but it remains a true security concern because the skill normalizes off-platform sharing without warning users about privacy implications.
## Examples (replace $CARSXE_KEY with actual env var value)
**"What are the specs for VIN WBAFR7C57CC811956?"**
→ `GET https://api.carsxe.com/specs?key=$CARSXE_KEY&vin=WBAFR7C57CC811956&source=openclaw`
**"Decode California plate 7XER187"**
→ `GET https://api.carsxe.com/v2/platedecoder?key=$CARSXE_KEY&plate=7XER187&country=US&state=CA&source=openclaw`
This example sends a license plate and jurisdictional data to an external API, which can reveal information about a specific vehicle and owner linkage possibilities. The risk is amplified by the skill's lack of consent and sensitivity warnings around plate lookups.
→ `GET https://api.carsxe.com/specs?key=$CARSXE_KEY&vin=WBAFR7C57CC811956&source=openclaw`
**"Decode California plate 7XER187"**
→ `GET https://api.carsxe.com/v2/platedecoder?key=$CARSXE_KEY&plate=7XER187&country=US&state=CA&source=openclaw`
**"What's my car worth? VIN WBAFR7C57CC811956, 45k miles, clean condition, California"**
→ `GET https://api.carsxe.com/v2/marketvalue?key=$CARSXE_KEY&vin=WBAFR7C57CC811956&state=CA&mileage=45000&condition=clean&source=openclaw`
The market-value example transmits a VIN plus location and condition details externally. While normal for the feature, it still exposes potentially sensitive vehicle-specific information without any documented notice or minimization.
→ `GET https://api.carsxe.com/v2/platedecoder?key=$CARSXE_KEY&plate=7XER187&country=US&state=CA&source=openclaw`
**"What's my car worth? VIN WBAFR7C57CC811956, 45k miles, clean condition, California"**
→ `GET https://api.carsxe.com/v2/marketvalue?key=$CARSXE_KEY&vin=WBAFR7C57CC811956&state=CA&mileage=45000&condition=clean&source=openclaw`
**"Does this car have any recalls? 1C4JJXR64PW696340"**
→ `GET https://api.carsxe.com/v1/recalls?key=$CARSXE_KEY&vin=1C4JJXR64PW696340&source=openclaw`
The recall lookup example sends a specific VIN to a third party. Although this may be a legitimate use case, the skill does not provide user-facing warning that a persistent vehicle identifier is being disclosed externally.
→ `GET https://api.carsxe.com/v2/marketvalue?key=$CARSXE_KEY&vin=WBAFR7C57CC811956&state=CA&mileage=45000&condition=clean&source=openclaw`
**"Does this car have any recalls? 1C4JJXR64PW696340"**
→ `GET https://api.carsxe.com/v1/recalls?key=$CARSXE_KEY&vin=1C4JJXR64PW696340&source=openclaw`
**"Any recalls on a 2023 Toyota Camry?"**
→ `GET https://api.carsxe.com/v1/recalls-ymm?key=$CARSXE_KEY&year=2023&make=Toyota&model=Camry&source=openclaw`
This example sends only year/make/model, which is less sensitive than VINs or plates, but it still involves external transmission. In context this is lower-risk than the identifier-based endpoints because it does not uniquely identify a specific vehicle or person.
→ `GET https://api.carsxe.com/v1/recalls?key=$CARSXE_KEY&vin=1C4JJXR64PW696340&source=openclaw`
**"Any recalls on a 2023 Toyota Camry?"**
→ `GET https://api.carsxe.com/v1/recalls-ymm?key=$CARSXE_KEY&year=2023&make=Toyota&model=Camry&source=openclaw`
**"Check recalls for this list of VINs"**
→ Submit: `POST https://api.carsxe.com/v1/recalls-batch/submit?key=$CARSXE_KEY&source=openclaw` with `Content-Type: application/json` and body `{"vins":["1HGBH41JXMN109186","5YJSA1E26HF000001"]}`
The batch recalls example supports uploading lists of VINs and optional CSV/CSV URL data to an external API, creating a significant bulk-data exposure risk. This is more dangerous than single-record lookups because a mistake or abuse can disclose fleet-scale sensitive identifiers at once, and the optional webhook/CSV mechanisms expand the data flow surface.
→ `GET https://api.carsxe.com/v1/recalls-ymm?key=$CARSXE_KEY&year=2023&make=Toyota&model=Camry&source=openclaw`
**"Check recalls for this list of VINs"**
→ Submit: `POST https://api.carsxe.com/v1/recalls-batch/submit?key=$CARSXE_KEY&source=openclaw` with `Content-Type: application/json` and body `{"vins":["1HGBH41JXMN109186","5YJSA1E26HF000001"]}`
→ Status: `GET https://api.carsxe.com/v1/recalls-batch/status?key=$CARSXE_KEY&batchId=brb_mnablbn7_wvbaqv&source=openclaw`
→ Results: `GET https://api.carsxe.com/v1/recalls-batch/results?key=$CARSXE_KEY&batchId=brb_mnablbn7_wvbaqv&source=openclaw`
→ Download CSV: `GET https://api.carsxe.com/v1/recalls-batch/download?key=$CARSXE_KEY&batchId=brb_mnablbn7_wvbaqv&source=openclaw`
The batch status polling example continues interacting with externally hosted batch jobs tied to previously uploaded VIN sets. The security issue is not the polling itself, but the normalization of large-scale third-party processing without protective guidance.
**"Check recalls for this list of VINs"**
→ Submit: `POST https://api.carsxe.com/v1/recalls-batch/submit?key=$CARSXE_KEY&source=openclaw` with `Content-Type: application/json` and body `{"vins":["1HGBH41JXMN109186","5YJSA1E26HF000001"]}`
→ Status: `GET https://api.carsxe.com/v1/recalls-batch/status?key=$CARSXE_KEY&batchId=brb_mnablbn7_wvbaqv&source=openclaw`
→ Results: `GET https://api.carsxe.com/v1/recalls-batch/results?key=$CARSXE_KEY&batchId=brb_mnablbn7_wvbaqv&source=openclaw`
→ Download CSV: `GET https://api.carsxe.com/v1/recalls-batch/download?key=$CARSXE_KEY&batchId=brb_mnablbn7_wvbaqv&source=openclaw`
Retrieving batch results from an external service can expose large collections of VIN-linked recall data, magnifying the impact of unauthorized or accidental bulk processing. Because the skill offers no warning or restrictions, an agent could surface or store mass results without user awareness.
**"Check recalls for this list of VINs"**
→ Submit: `POST https://api.carsxe.com/v1/recalls-batch/submit?key=$CARSXE_KEY&source=openclaw` with `Content-Type: application/json` and body `{"vins":["1HGBH41JXMN109186","5YJSA1E26HF000001"]}`
→ Status: `GET https://api.carsxe.com/v1/recalls-batch/status?key=$CARSXE_KEY&batchId=brb_mnablbn7_wvbaqv&source=openclaw`
→ Results: `GET https://api.carsxe.com/v1/recalls-batch/results?key=$CARSXE_KEY&batchId=brb_mnablbn7_wvbaqv&source=openclaw`
→ Download CSV: `GET https://api.carsxe.com/v1/recalls-batch/download?key=$CARSXE_KEY&batchId=brb_mnablbn7_wvbaqv&source=openclaw`
**"What Toyota models were sold in 2023?"**
The batch download endpoint enables exporting bulk recall data, increasing exfiltration and secondary-sharing risk. In this context, downloadable files can be redistributed or retained more easily than single interactive responses, making the transmission more dangerous.
→ Submit: `POST https://api.carsxe.com/v1/recalls-batch/submit?key=$CARSXE_KEY&source=openclaw` with `Content-Type: application/json` and body `{"vins":["1HGBH41JXMN109186","5YJSA1E26HF000001"]}`
→ Status: `GET https://api.carsxe.com/v1/recalls-batch/status?key=$CARSXE_KEY&batchId=brb_mnablbn7_wvbaqv&source=openclaw`
→ Results: `GET https://api.carsxe.com/v1/recalls-batch/results?key=$CARSXE_KEY&batchId=brb_mnablbn7_wvbaqv&source=openclaw`
→ Download CSV: `GET https://api.carsxe.com/v1/recalls-batch/download?key=$CARSXE_KEY&batchId=brb_mnablbn7_wvbaqv&source=openclaw`
**"What Toyota models were sold in 2023?"**
→ `GET https://api.carsxe.com/v1/ymm-options?key=$CARSXE_KEY&year=2023&make=Toyota&source=openclaw`
The ownership lookup example sends a VIN to an endpoint intended to return registered-owner information, a highly sensitive personal-data operation. This is especially dangerous because the skill markets the capability directly without any consent, legality, or authorization safeguards.
→ `GET https://api.carsxe.com/v1/ymm-options?key=$CARSXE_KEY&year=2023&make=Toyota&source=openclaw`
**"Who is the registered owner of VIN 1FT8X3BT0BEA61538?"**
→ `GET https://api.carsxe.com/v1/ownership/vin?key=$CARSXE_KEY&vin=1FT8X3BT0BEA61538&source=openclaw`
**"Check liens and theft for WBAFR7C57CC811956"**
→ `GET https://api.carsxe.com/v1/lien-theft?key=$CARSXE_KEY&vin=WBAFR7C57CC811956&source=openclaw`
The lien/theft example transmits a specific VIN to an external service. This is a legitimate feature, but it still shares a persistent identifier externally without any warning or guidance about handling potentially sensitive status results.
→ `GET https://api.carsxe.com/v1/ownership/vin?key=$CARSXE_KEY&vin=1FT8X3BT0BEA61538&source=openclaw`
**"Check liens and theft for WBAFR7C57CC811956"**
→ `GET https://api.carsxe.com/v1/lien-theft?key=$CARSXE_KEY&vin=WBAFR7C57CC811956&source=openclaw`
**"Decode this international VIN: WF0MXXGBWM8R43240"**
→ `GET https://api.carsxe.com/v1/international-vin-decoder?key=$CARSXE_KEY&vin=WF0MXXGBWM8R43240&source=openclaw`
No suspicious patterns detected.