T09 · Insecure Skill Coding Practices
- Location
src/hardening/auto-hardener.js:26- Finding
Asynchronous Permission Fixes Can Erase the OpenClaw Configuration
- Content
View full analysis
{ await fs.chmod(filePath, 0o600); } ``` The hardener treats every fix as a synchronous configuration transformation: ```js // Apply each auto-fixable issue for (const issue of issues) { if (issue.autoFixable && issue.autoFix) { config = issue.autoFix(config); } } // Write updated config await fs.writeFile( configPath, JSON.stringify(config, null, 2), 'utf-8' ); ``` ### Technical Analysis Configuration fixes return the modified configuration object synchronously, while permission fixes are declared as `async` functions and return a Promise. `AutoHardener.applyFixes()` does not await the result and unconditionally assigns it to `config`. When a permission fix is processed, `config` becomes a Promise rather than the parsed OpenClaw configuration. Serializing a Promise with `JSON.stringify()` produces `{}`, so the final write can replace the complete `openclaw.json` file with an empty JSON object. If additional fixes follow the permission fix, they may receive a Promise where a normal configuration object is expected, potentially causing exceptions or additional incorrect mutations. ### Attack Path 1. An OpenClaw installation contains `openclaw.json`, `credentials.json`, or `.env` with world-readable or world-writable permissions. 2. `ConfigAuditor.checkFilePermissions()` creates an asynchronous `autoFix` finding. 3. The user runs `openclaw-guard fix` and approves the changes, or runs `openclaw-guard fix --auto`. 4. `AutoHardener.applyFixes()` invokes the asynchronous callback without `await`. 5. The returned Promise is as ...[truncated 831 chars]- Remediation
View remediation
