T09 · Insecure Skill Coding Practices
- Location
scripts/expense_snap.py:191- Finding
CSV Formula Injection in Expense Export
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is a coherent local expense tracker, with expected local storage and CSV export behavior but some hardening gaps users should understand.
Install only if you are comfortable storing receipt and spending details in a local SQLite database inside the skill directory. Keep CSV exports in a location you choose, avoid overwriting important files, and treat exported CSVs as sensitive; be cautious opening exports in spreadsheet apps if receipt fields came from untrusted text or OCR.
scripts/expense_snap.py:191CSV Formula Injection in Expense Export
The skill invokes a Python helper and writes persistent state to a SQLite database and CSV output, but the manifest does not declare any explicit tool scope such as permissions or allowed-tools. That mismatch weakens least-privilege controls and can let a host agent run shell/file-write capable behavior without clear policy review, which is especially relevant because user-influenced receipt data may be passed into command execution paths.
The skill persists expense information, including merchant, payment method, notes, and image path, to a local database via sqlite3.connect and subsequent inserts. The code does not provide a confirmation prompt, user-facing warning, or explanatory comment/docstring near this persistence behavior, even though it stores potentially sensitive financial data.
The manifest describes capturing receipt details, categorizing spending, and generating monthly reports from a local SQLite ledger. In addition to those functions, the record command also creates and updates a separate budgets table via --budget inputs, which is a broader finance-management capability not mentioned in the manifest description.
The export-csv command writes potentially sensitive receipt data to any attacker-controlled filesystem path supplied via --output. In an agent setting, this can enable unintended data exfiltration or overwriting of user files outside the skill’s runtime area, especially because the manifest description does not clearly disclose arbitrary file export behavior.
The export path is fully user-controlled and the code creates parent directories and writes receipt contents without constraining the destination. In agentic or semi-trusted environments, this increases the risk of silently placing sensitive financial data in unexpected locations or clobbering existing files.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
self.temp_dir.cleanup()
def run_cli(self, *args):
result = subprocess.run(
[sys.executable, str(self.base_dir / "scripts" / "expense_snap.py"), *self.base_arg, *args],
capture_output=True,
text=True,
No suspicious patterns detected.