T09 · Insecure Skill Coding Practices
- Location
scripts/analyze.py:476- Finding
Plaintext Persistence and Distribution of Sensitive Financial Data
- Content
View full analysis
Vulnerability Details
File Location:
scripts/analyze.py:430-431,scripts/analyze.py:476-482,scripts/report.py:852-860; sensitive generated artifacts are present indata/positions.json:4-24anddata/report_close_20260325.md:8-49
Vulnerability Type: Plaintext storage of sensitive financial information
Risk Level: MediumVulnerable Code
python # scripts/analyze.py:430-431 out = {"type": "positions", "positions": raw} print(json.dumps(out, ensure_ascii=False, indent=2)) (DATA_DIR / "positions.json").write_text( json.dumps(out, ensure_ascii=False, indent=2), encoding="utf-8", )python # scripts/analyze.py:476-482 # Save the analysis and raw portfolio data. (DATA_DIR / "analysis_report.json").write_text( json.dumps(analysis, ensure_ascii=False, indent=2), encoding="utf-8" ) (DATA_DIR / "positions.json").write_text( json.dumps(raw.get("positions", {}), ensure_ascii=False, indent=2), encoding="utf-8" )python # scripts/report.py:852-860 report_path = DATA_DIR / f"report_{args.mode}_{datetime.now().strftime('%Y%m%d')}.md" report_path.write_text(report, encoding="utf-8") print(f"Report saved: {report_path}") if args.feishu: feishu_data = format_feishu_card(report) feishu_path = DATA_DIR / f"report_{args.mode}_{datetime.now().strftime('%Y%m%d')}_feishu.json" feishu_path.write_text( json.dumps(feishu_data, ensure_ascii=False, indent=2), encoding="utf-8", )The distributed artifact demonstrates the type of persisted data:
json { "overview": { "total_asset": 10007.98, "total_value": 1052.0, "money_remain": 8955.98, "total_liability": 0.0 }, "items": [ { "stock_code": "300098", "hold_count": 200, "cost_price": 5.21, "current_price": 5.26, "market_value": 1052.0, "hold_profit": 7.98 } ] }Technical Analysis
The Skill retrieves confidential investment-account information and writes it t ...[truncated 2643 chars]
- Remediation
View remediation
Remediation Suggestions
-
Remove generated financial records from distribution
- Delete committed or packaged
data/*.json,data/*.md, and Feishu-format output files. - Add generated financial files and dated reports to
.gitignoreand package-exclusion rules. - Add a release check that rejects artifacts containing portfolio or transaction data.
- Delete committed or packaged
-
Make persistence explicit and optional
- Process account data in memory by default.
- Require an explicit option such as
--save-sensitive-databefore writing raw positions or transactions. - Clearly disclose which data is retained, its location, and its retention period.
-
Minimize retained data
- Store only the values required by the monitor rather than complete raw account responses.
- Avoid retaining transaction details, balances, quantities, or cost basis when they are not required.
- Support redacted reports that omit exact balances and transaction amounts.
-
Apply restrictive filesystem controls
- Create sensitive files with owner-only permissions, such as mode
0600on POSIX systems. - Create sensitive directories with mode
0700. - Avoid relying solely on the process umask.
- Refuse to store sensitive output in a world-readable or shared directory unless the user explicitly confirms.
- Create sensitive files with owner-only permissions, such as mode
-
Protect and expire retained records
- Encrypt cached financial data using a user-managed key or operating-system credential store.
- Implement automatic expiration and secure deletion where supported.
- Provide a command that removes all cached portfolio data and reports.
-
Reduce terminal disclosure
- Avoid printing complete raw portfolio and transaction objects by default.
- Provide a redacted summary mode for logs and scheduled executions.
- Ensure cron or agent logs do not retain complete financial reports indefinitely.
-
