T09 · Insecure Skill Coding Practices
- Location
scripts/scraper.py:75- Finding
Instagram Session State Is Persisted in Plaintext
- Content
View full analysis
dict | None: """ Returns a Playwright storage_state dict (cookies + localStorage) for Instagram. - If SESSION_FILE exists, loads and returns the saved session. - Otherwise logs in fresh using config credentials and saves the session. - Returns None if no credentials are configured or login fails. """ if not config.INSTAGRAM_USERNAME or not config.INSTAGRAM_PASSWORD: return None # Reuse saved session if SESSION_FILE.exists(): print("Loading saved Instagram session.") return json.loads(SESSION_FILE.read_text(encoding="utf-8")) ``` ```python if "accounts/login" not in page.url and "challenge" not in page.url: state = ctx.storage_state() SESSION_FILE.write_text(json.dumps(state), encoding="utf-8") print(" Login successful — session saved.") return state ``` The session file is defined at line 21: ```python SESSION_FILE = Path(__file__).parent / ".instagram_session.json" ``` ### Technical Analysis Playwright storage state can contain authenticated cookies and local-storage values that function as reusable bearer credentials. The application writes this state as unencrypted JSON inside the skill directory. The write operation does not explicitly enforce restrictive file permissions, validate the destination against symbolic-link attacks, use an operating-system credential store, or establish an expiration and revocation policy. The loading path also does not verify ownership or permissions before trusting the saved file. Although default process permissions may be influenced by the operating system and the user's `umask`, the code itself does not guarantee that only the account owner can read the authentication state. Storing t ...[truncated 1418 chars]- Remediation
View remediation
