Vehicle Expense Tracker

AdvisoryAudited by Static analysis on Apr 30, 2026.

Overview

No suspicious patterns detected.

Findings (0)

Artifact-based informational review of SKILL.md, metadata, install specs, static scan signals, and capability signals. ClawScan does not execute the skill or run runtime probes.

What this means

A mistaken or malicious vehicle/category value could make the skill create directories and copy files outside the intended vehicle expense folder.

Why it was flagged

The destination directory for photo copies is built directly from vehicle_name and category without sanitizing or resolving those path components. Absolute paths or '..' components could escape PHOTO_BASE_DIR.

Skill content
target_dir = Path(PHOTO_BASE_DIR) / vehicle_name / category ... target_dir.mkdir(parents=True, exist_ok=True) ... shutil.copy2(src, dst)
Recommendation

Sanitize vehicle and category path components, reject absolute paths and '..', resolve the final path, and enforce that it remains under the configured photo base directory.

What this means

If untrusted receipt text or a crafted description starts with spreadsheet formula characters, it could become an active formula in the user's Google Sheet.

Why it was flagged

User-provided category, cost, unit, and description values are sent to Google Sheets as USER_ENTERED data, which can cause formula-like values to be interpreted by the spreadsheet.

Skill content
row_data = [
        args.mileage,
        category,
        final_cost,
        quantity,
        unit,
        args.description,
        args.date
    ] ... valueInputOption='USER_ENTERED'
Recommendation

Use RAW for text insertion or escape leading formula characters such as '=', '+', '-', and '@' before writing user-controlled text to spreadsheets.

What this means

A user may believe dry-run makes no changes, but the skill can still edit its local config file.

Why it was flagged

The config save can occur before the dry-run branch, so a preview run can still mutate persistent config for new categories or save flags.

Skill content
if args.save_unit or args.save_default or (category not in category_defaults): ... save_config(config) ... if args.dry_run:
Recommendation

Move all persistent writes after the dry-run check, or clearly document and separately confirm config updates during dry-run.

What this means

The skill can add expense rows to any configured spreadsheet that the Google credential can access.

Why it was flagged

The skill uses Google Sheets API credentials from another auth helper to append rows. This is expected for the stated Google Sheets integration, but it is a real delegated account permission.

Skill content
from google_auth import get_service
sheets = get_service('sheets', 'v4') ... spreadsheets().values().append(
Recommendation

Use a dedicated Google service account with access only to the intended vehicle-expense spreadsheet.

What this means

Google Sheets mode depends on code outside this skill package, so behavior also depends on the installed google-workspace skill.

Why it was flagged

The skill imports runtime code from a sibling google-workspace skill that is not included in this manifest. This is understandable for shared Google auth, but it expands the trusted code base.

Skill content
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../google-workspace')))
Recommendation

Install google-workspace only from a trusted source and declare this dependency clearly in the skill metadata or setup instructions.