Back to skill

Security audit

kiaaccess-curl

Security checks for vulnerabilities and agentic risk

Overview

This skill is coherent, but it gives ready-to-run commands that can control a real Kia and stores reusable vehicle-account credentials with some under-scoped handling.

Install only if you are comfortable with an agent helping issue direct Kia Owners API calls that can reveal vehicle location and change vehicle state. Treat KIA_PASSWORD, sid, rmtoken, and the generated /tmp files as sensitive secrets; avoid shared machines, verify the target vehicle before any command, and prefer a safer scoped tool or manual confirmation for lock, unlock, climate, and charging changes.

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

Error
Location
references/requests.md:59
Finding
Predictable and Insecure Temporary Files Expose Authentication Tokens and Vehicle Data## Vulnerability Details **File Location**: `references/requests.md:59-60, 79-82, 99-100, 123, 132-134, 146, 154, 162` **Vulnerability Type**: Insecure temporary-file handling and plaintext sensitive-data exposure **Risk Level**: High ### Vulnerable Code ```bash curl -sS -X "$method" "${KIA_BASE}/${path}" "${KIA_HDRS[@]}" \ ${body:+--data "$body"} -D /tmp/kia_hdrs --compressed ``` ```bash kia_curl POST prof/authUser "$(jq -nc \ --arg u "$KIA_USERNAME" --arg p "$KIA_PASSWORD" \ '{deviceKey:"",deviceType:2,userCredential:{userId:$u,password:$p},tncFlag:1}')" \ | tee /tmp/kia_auth.json | jq '.status, .payload.nextAction' OTPKEY=$(jq -r '.payload.otpKey' /tmp/kia_auth.json) XID=$(grep -i '^xid:' /tmp/kia_hdrs | tr -d '\r' | cut -d' ' -f2) ``` ```bash SID=$(grep -i '^sid:' /tmp/kia_hdrs | tr -d '\r' | cut -d' ' -f2) RMTOKEN=$(grep -i '^rmtoken:' /tmp/kia_hdrs | tr -d '\r' | cut -d' ' -f2) ``` ```bash SID=$(grep -i '^sid:' /tmp/kia_hdrs | tr -d '\r' | cut -d' ' -f2) ``` ```bash kia_curl GET ownr/gvl '' -- "sid: $SID" | tee /tmp/kia_gvl.json \ | jq '.payload.vehicleSummary[] | {nickName, modelYear, modelName, mileage, vehicleKey}' VIN=$(jq -r '.payload.vehicleSummary[0].vehicleKey' /tmp/kia_gvl.json) ``` ```bash kia_curl POST cmm/gvi "$GVI" -- "sid: $SID" "vinkey: $VIN" > /tmp/kia_gvi.json ``` ```bash jq '.payload.vehicleInfoList[0].lastVehicleInfo.vehicleStatusRpt.vehicleStatus | {doorLock, ign3, engine, climate: {airCtrl: .climate.airCtrl, temp: .climate.airTemp.value}, battery: .evStatus.batteryStatus, range: .evStatus.drvDistance[0].rangeByFuel.totalAvailableRange.value, synced: .syncDate.utc}' /tmp/kia_gvi.json ``` ```bash jq '.payload.vehicleInfoList[0].lastVehicleInfo.location | {lat: .coord.lat, lon: .coord.lon, synced: .syncDate.utc}' /tmp/kia_gvi.json ``` ### Technical Analysis The documented commands use fixed ...[truncated 2625 chars]
Remediation
## Remediation Suggestions - Set a restrictive process mask before creating any sensitive files: ```bash umask 077 ``` - Create a unique private temporary directory instead of using fixed paths: ```bash KIA_TMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/kiaaccess.XXXXXXXX") || exit 1 chmod 700 "$KIA_TMPDIR" trap 'rm -rf -- "$KIA_TMPDIR"' EXIT HUP INT TERM ``` - Replace every fixed temporary path with a file inside that directory, for example: ```bash KIA_HEADER_FILE="$KIA_TMPDIR/headers" KIA_AUTH_FILE="$KIA_TMPDIR/auth.json" KIA_GVL_FILE="$KIA_TMPDIR/gvl.json" KIA_GVI_FILE="$KIA_TMPDIR/gvi.json" ``` - Pass the private header path to the wrapper rather than hardcoding `/tmp/kia_hdrs`. - Avoid storing token-bearing response headers when possible. Capture required headers in memory or extract them immediately from a securely created file and delete that file as soon as parsing is complete. - Explicitly verify that sensitive files are regular files owned by the current user and are not symbolic links before reuse. - Retain the existing `chmod 600` protection for the durable session file and apply equivalent restrictive permissions to all temporary files containing credentials or location data. - Clear sensitive shell variables such as `SID`, `RMTOKEN`, and `OTPKEY` when the operation completes.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (11)

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill enables high-impact remote actions against a real vehicle, including lock, unlock, climate start, and charging commands, but the description presents these as routine shell actions without an explicit warning that they can change the physical/security state of the car. In this context, missing a prominent warning increases the chance of accidental or insufficiently confirmed execution of sensitive commands.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The documentation explains how to export username/password and persist an rmtoken that can silently re-authenticate the account, but it does not provide a strong privacy/security warning about the sensitivity and reuse risk of those credentials. Because the token bypasses repeated MFA, leakage from shell history, environment inspection, backups, or logs could allow unauthorized vehicle access.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
> credential and try once.

Store the `rmtoken` at `$KIA_SESSION` (default `~/.kiaaccess-mcp/curl-session.json`)
with `chmod 600`. It is a credential: it re-authenticates the account without a
password prompt.

> Do **not** write it to `~/.kiaaccess-mcp/session.json`. That path belongs to the
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Session Persistence

Medium
Category
Rogue Agent
Content
with `chmod 600`. It is a credential: it re-authenticates the account without a
password prompt.

> Do **not** write it to `~/.kiaaccess-mcp/session.json`. That path belongs to the
> `kiaaccess-mcp` server, whose store is keyed by `accountId` with a different
> schema — overwriting it corrupts the server's session and forces it back
> through MFA.
Confidence
89% confidence
Finding
The skill explicitly instructs persistent storage of a long-lived refresh token that can re-authenticate without MFA, which creates a reusable session secret on disk. Even though the text advises `chmod 600` and warns about schema separation, local compromise, backup leakage, or accidental exposure of that file could enable unauthorized account and vehicle access.

External Transmission

Medium
Category
Data Exfiltration
Content
device id stable.

```bash
KIA_BASE='https://api.owners.kia.com/apigw/v1'
: "${KIA_DEVICE:?export KIA_DEVICE=\$(uuidgen) first}"

# Session file for THIS skill. Deliberately NOT ~/.kiaaccess-mcp/session.json —
Confidence
50% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
done
}

# curl wrapper: kia_curl <method> <path> [body] [-- extra-header ...]
kia_curl() {
  local method="$1" path="$2" body="${3:-}"
  shift 2; [ $# -gt 0 ] && shift          # drop the body arg when present
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
SID=$(grep -i '^sid:'     /tmp/kia_hdrs | tr -d '\r' | cut -d' ' -f2)
RMTOKEN=$(grep -i '^rmtoken:' /tmp/kia_hdrs | tr -d '\r' | cut -d' ' -f2)

mkdir -p "$(dirname "$KIA_SESSION")" && chmod 700 "$(dirname "$KIA_SESSION")"
jq -nc --arg r "$RMTOKEN" --arg d "$KIA_DEVICE" '{rmtoken:$r,deviceId:$d}' \
  > "$KIA_SESSION"
chmod 600 "$KIA_SESSION"
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Content
mkdir -p "$(dirname "$KIA_SESSION")" && chmod 700 "$(dirname "$KIA_SESSION")"
jq -nc --arg r "$RMTOKEN" --arg d "$KIA_DEVICE" '{rmtoken:$r,deviceId:$d}' \
  > "$KIA_SESSION"
chmod 600 "$KIA_SESSION"
```

`$KIA_SESSION` — **not** `session.json`. That neighbouring file is the MCP
Confidence
80% confidence
Finding
Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The skill documents direct retrieval of precise vehicle location data without any privacy warning or guidance about consent and sensitive handling. Location is highly sensitive telemetry, and in this context the skill makes exfiltration trivial for anyone with shell access and stored session material.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This section provides ready-to-run remote vehicle control commands such as lock, unlock, climate start/stop, and EV charging changes without requiring an explicit confirmation step or prominently warning about real-world effects. In a shell-oriented skill, users may paste commands directly, so omission of friction and safety messaging materially increases the chance of accidental unauthorized or unintended actuation of a physical asset.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
The header helper hard-codes `accept-language: en-US,en;q=0.9`, which imposes a specific locale preference. There is no accompanying explanation, opt-in, or indication that the locale is required for a region-specific compliance reason.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
references/requests.md:44