T09 · Insecure Skill Coding Practices
Error
- Location
- login_save_session.py:4
- Finding
- Broad browser-session capture and plaintext storage of reusable credentials<![CDATA[ ## Vulnerability Details **File Location**: `login_save_session.py:4-9`; related setup instructions in `SKILL.md:45-57` and credential reuse in `scrape_feed.py:77-81` **Vulnerability Type**: Excessive browser-session capture and insecure local secret storage **Risk Level**: High ### Vulnerable Code ```python # login_save_session.py:4-9 # Connect to the user's already-open Chrome via CDP browser = p.chromium.connect_over_cdp("http://127.0.0.1:9222") context = browser.contexts[0] # Save the login session/cookies to a file context.storage_state(path="x_session.json") ``` The resulting file is subsequently loaded into an automated browser: ```python # scrape_feed.py:77-81 context = browser.new_context( storage_state="x_session.json", viewport={"width": 1280, "height": 900}, ) ``` The setup instructions explicitly tell the user to expose Chrome through the Chrome DevTools Protocol: ```text # SKILL.md:45-57 1. Open Chrome with remote debugging enabled by running: open -a 'Google Chrome' --args --remote-debugging-port=9222 2. Log in to X/Twitter in that Chrome window 3. Once logged in, I'll run a script that connects to that browser and saves your session cookies. ``` ### Technical Analysis Playwright's `storage_state()` serializes cookies and origin-specific browser storage from the selected browser context. The implementation selects `browser.contexts[0]` without confirming that it is a dedicated X-only context and saves the result to a plaintext file. The instructions tell the user to launch Chrome with remote debugging but do not require a separate browser profile. If the selected context contains active sessions for services other than X, their cookies or origin storage may also be copied into `x_session.json`. Even if only X credentials are captured, the file contains reusable authentication material. No permission hardening is applied when the file is created, and no `.gitignore` was present in the audited project tree to exclude ...[truncated 1875 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Launch a dedicated Chrome profile used exclusively for X, for example with a new `--user-data-dir` that contains no unrelated sessions. 2. Do not attach to an arbitrary first context. Identify and validate the expected dedicated context explicitly. 3. Where supported, filter exported cookies and storage to the minimum required X domains, such as `x.com` and necessary authentication domains. 4. Create the session file atomically and enforce owner-only permissions (`0600`) immediately. 5. Add `.env`, `x_session.json`, `feed_raw*.json`, and other generated credential or feed artifacts to `.gitignore`. 6. Display a clear warning that the file is equivalent to a credential and must not be shared or committed. 7. Document how to delete the session file and revoke active X sessions. 8. Instruct the user to terminate the remote-debugging browser after session capture. Avoid leaving CDP exposed longer than necessary. 9. Prefer a fresh Playwright persistent context dedicated to this application instead of connecting to the user's general-purpose browser. ]]>
