T09 · Insecure Skill Coding Practices
- Location
tracker.js:6- Finding
Financial Records Stored Without Explicitly Restrictive Permissions
- Content
View full analysis
Vulnerability Details
File Location:
tracker.js, lines 6-47
Vulnerability Type: Plaintext sensitive-data storage with permissions inherited from the process environment
Risk Level: Mediumjs const DATA_DIR = path.join(process.env.HOME, '.openclaw/workspace/data/income'); const INCOME_FILE = path.join(DATA_DIR, 'income.jsonl'); const EXPENSE_FILE = path.join(DATA_DIR, 'expenses.jsonl'); // Ensure data directory exists if (!fs.existsSync(DATA_DIR)) { fs.mkdirSync(DATA_DIR, { recursive: true }); } function addIncome(source, amount, description) { const entry = { timestamp: new Date().toISOString(), source, amount: parseFloat(amount), description, type: 'income' }; fs.appendFileSync(INCOME_FILE, JSON.stringify(entry) + '\n'); console.log(`✅ Added income: $${amount} from ${source}`); } function addExpense(category, amount, description) { const entry = { timestamp: new Date().toISOString(), category, amount: parseFloat(amount), description, type: 'expense' }; fs.appendFileSync(EXPENSE_FILE, JSON.stringify(entry) + '\n'); console.log(`✅ Added expense: $${amount} for ${category}`); }Technical Analysis
The application stores transaction timestamps, amounts, income sources, expense categories, and user-supplied descriptions in plaintext JSONL files. Neither
fs.mkdirSyncnorfs.appendFileSyncspecifies an explicit restrictive mode. Consequently, newly created directory and file permissions depend on the process umask and surrounding filesystem configuration.On a system with a permissive umask or improperly configured parent directories, other local users may be able to traverse the data directory and read the financial records. Free-form descriptions may increase the sensitivity of the exposed data if users enter customer names, project details, invoice references, or other confidential inform ...[truncated 1740 chars]
- Remediation
View remediation
Remediation Suggestions
- Create the data directory with mode
0700, for example:js fs.mkdirSync(DATA_DIR, { recursive: true, mode: 0o700 }); fs.chmodSync(DATA_DIR, 0o700); - Create transaction files with mode
0600. Prefer opening them with flags that safely create the file and explicitly constrain its permissions before writing. - Use
fs.lstatSyncto reject symbolic links and verify that each storage object is a regular file owned by the expected user before appending. - Consider using
O_NOFOLLOWwhere supported to reduce symbolic-link race exposure. - Fail closed when ownership or permissions are broader than expected rather than silently continuing.
- Document that records are retained in plaintext and advise users not to place secrets, credentials, or unnecessary personal data in transaction descriptions.
- If the threat model includes untrusted local users or shared backups, protect records with authenticated encryption and store encryption keys separately using an operating-system credential facility.
- Create the data directory with mode
