T09 · Insecure Skill Coding Practices
- Location
- scripts/linkedin-api.js:84
- Finding
- LinkedIn Session State Stored Without Restrictive File Permissions## Vulnerability Details **File Location**: `scripts/linkedin-api.js:84-89` **Vulnerability Type**: Insecure storage of reusable authentication material **Risk Level**: High **Vulnerable Code**: ```js saveSession() { if (this.context) { this.ensureConfigDir(); this.context.storageState().then(state => { fs.writeFileSync(SESSION_FILE, JSON.stringify(state)); }); } } ``` ### Technical Analysis Playwright storage state can contain authenticated LinkedIn cookies and other reusable browser authentication data. The application writes this state to `~/.config/linkedin-outreach/session.json` using `fs.writeFileSync` without specifying an owner-only file mode. When a new file is created, Node.js uses default permissions subject to the process umask. Depending on the host configuration, the session file may consequently be readable by other local users or processes. The containing configuration directory is also created without an explicit owner-only mode. No permission validation is performed when an existing session file is loaded. Possession of valid session cookies may allow authentication without knowing the account password or completing multi-factor authentication. ### Attack Path 1. The victim runs the `linkedin login` command and successfully authenticates to LinkedIn. 2. The Skill obtains the authenticated Playwright storage state. 3. The storage state is written to `~/.config/linkedin-outreach/session.json` with permissions determined by the environment's default umask. 4. Another local user or compromised process reads the session file if filesystem permissions permit it. 5. The attacker imports the captured cookies and browser state into a compatible browser context. 6. If the session remains valid and LinkedIn does not reject it, the attacker accesses the victim's LinkedIn account as the victim. ### Impact Assessment Successful exploitation could disclose reusable LinkedIn ...[truncated 486 chars]
- Remediation
- ## Remediation Suggestions - Create `~/.config/linkedin-outreach` with owner-only permissions, such as mode `0700`. - Write `session.json` with an explicit mode of `0600`. - Write the state to a securely created temporary file, apply restrictive permissions, and atomically rename it into place. - Check and correct the permissions of existing session files before loading them. - Reject session paths that are symbolic links or otherwise resolve outside the expected configuration directory. - Add a logout or session-deletion command that securely removes stored authentication state. - Consider using an operating-system credential store or encrypted secret-storage facility instead of a plaintext JSON file. - Apply equivalent owner-only protections to `data.json`, which contains collected profile and outreach-message data.
