T09 · Insecure Skill Coding Practices
- Location
scripts/get_price_chart.py:37- Finding
Predictable Shared Temporary Files Permit Symlink Attacks and Cache Poisoning
- Content
View full analysis
max_age_sec: return None try: with open(path, "r", encoding="utf-8") as handle: return json.load(handle) except (OSError, json.JSONDecodeError): return None def _write_cache(path, payload): try: with open(path, "w", encoding="utf-8") as handle: json.dump(payload, handle) except OSError: return ``` ```python ts = int(time.time()) chart_path = f"/tmp/crypto_chart_{symbol}_{ts}.png" fig.tight_layout() fig.savefig(chart_path, dpi=150) ``` ### Technical Analysis The Skill stores cache and chart files directly in the globally shared `/tmp` directory. Cache filenames are deterministic, while chart filenames contain only the requested symbol and a timestamp with one-second resolution. The files are accessed without: - A private, permission-restricted temporary directory - Exclusive file creation - Symbolic-link rejection - File ownership or regular-file validation - Atomic cache replacement The standard `open(path, "w")` operation used for cache files can follow a symbolic link placed at the predictable path. The matplotlib `fig.savefig()` operation similarly writes to a predictable pathname without first ensuring that the destination is a newly and securely created regular file. Cache reads also trust any syntactically valid and sufficiently recent JSON file already present at the expected path. A local attacker able to write to `/ ...[truncated 2110 chars]- Remediation
View remediation
