T09 · Insecure Skill Coding Practices
- Location
login_save_session.py:4- Finding
Broad browser-session capture and plaintext storage of reusable credentials
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is a daily tech-brief tool, but it handles live browser session cookies, runs authenticated X/Twitter scraping, and installs recurring jobs in ways users should review carefully before installing.
Install only if you are comfortable with a local automation job saving reusable X/Twitter session cookies, scraping your personalized timeline, and running recurring scheduled jobs. Use a dedicated browser profile, protect and exclude .env and x_session.json from version control, revoke the X session if exposed, pin the code and dependencies, and disable the cron jobs when you no longer need the brief.
login_save_session.py:4Broad browser-session capture and plaintext storage of reusable credentials
SKILL.md:91Indirect prompt injection through attacker-controlled feed content
requirements.txt:5Mutable and unpinned dependencies are executed during automated setup
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
).strftime("%Y-%m-%dT00:00:00Z")
variables["postedAfter"] = posted_after
resp = requests.post(
_GRAPHQL_URL,
json={"query": _QUERY, "variables": variables},
headers={
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
"days": days,
}
resp = requests.post(self.API_URL, json=payload, timeout=30)
resp.raise_for_status()
data = resp.json()
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Some sources require API keys — you'll need to register and fill them into .env. Tavily powers web search (catching trending topics not covered by any feed), and Product Hunt requires an API token for its GraphQL endpoint.
cp .env.example .env
# Fill in TAVILY_API_KEY (free: https://tavily.com)
# Fill in PRODUCTHUNT_API_TOKEN (free: https://api.producthunt.com/v2/docs)
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
Some sources require API keys — you'll need to register and fill them into .env. Tavily powers web search (catching trending topics not covered by any feed), and Product Hunt requires an API token for its GraphQL endpoint.
cp .env.example .env
# Fill in TAVILY_API_KEY (free: https://tavily.com)
# Fill in PRODUCTHUNT_API_TOKEN (free: https://api.producthunt.com/v2/docs)
The skill includes undeclared execution of local scraper workflows tied to X/Twitter access, which goes beyond a simple configuration assistant. Even if functionally related, hidden subprocess-style scraping behavior is riskier in an agent skill because it obscures what code will run and what data will be accessed.
The skill includes undeclared execution of local scraper workflows tied to X/Twitter access, which goes beyond a simple configuration assistant. Even if functionally related, hidden subprocess-style scraping behavior is riskier in an agent skill because it obscures what code will run and what data will be accessed.
The skill includes undeclared execution of local scraper workflows tied to X/Twitter access, which goes beyond a simple configuration assistant. Even if functionally related, hidden subprocess-style scraping behavior is riskier in an agent skill because it obscures what code will run and what data will be accessed.
The skill includes undeclared execution of local scraper workflows tied to X/Twitter access, which goes beyond a simple configuration assistant. Even if functionally related, hidden subprocess-style scraping behavior is riskier in an agent skill because it obscures what code will run and what data will be accessed.
The skill includes undeclared execution of local scraper workflows tied to X/Twitter access, which goes beyond a simple configuration assistant. Even if functionally related, hidden subprocess-style scraping behavior is riskier in an agent skill because it obscures what code will run and what data will be accessed.
The skill includes undeclared execution of local scraper workflows tied to X/Twitter access, which goes beyond a simple configuration assistant. Even if functionally related, hidden subprocess-style scraping behavior is riskier in an agent skill because it obscures what code will run and what data will be accessed.
The skill includes undeclared execution of local scraper workflows tied to X/Twitter access, which goes beyond a simple configuration assistant. Even if functionally related, hidden subprocess-style scraping behavior is riskier in an agent skill because it obscures what code will run and what data will be accessed.
The skill includes undeclared execution of local scraper workflows tied to X/Twitter access, which goes beyond a simple configuration assistant. Even if functionally related, hidden subprocess-style scraping behavior is riskier in an agent skill because it obscures what code will run and what data will be accessed.
The skill instructs the agent to attach to the user’s already-open Chrome instance via remote debugging and extract/save X/Twitter session cookies. This is highly sensitive credential material: anyone obtaining those cookies may be able to impersonate the user’s account, and the use of CDP against a live browser can expose more than just the intended site if misused.
The skill describes extracting and saving X/Twitter session cookies without any explicit privacy or account-security warning. Session cookies are often equivalent to live authentication; storing them on disk dramatically increases the risk of account takeover if the file is stolen, reused, or mishandled by later automation.
This heuristic correctly flags behavior consistent with information stealing: the skill directs extraction of live browser cookies and writes them to x_session.json. Even if intended for convenience, collecting reusable authentication material from a live browser is a high-risk credential-access pattern that can enable account hijacking.
window
3. Once logged in, I'll run a script that connects to that browser and saves your session cookies."
After the user confirms they are logged in to X in Chrome, run:
cd ~/multi-source-feed && source .venv/bin/activate && python login_save_session.py
This script connects to the already-open Chrome instance via CDP (Chrome DevTools Protocol) on port 9222, extracts the session/cookies, and saves them to x_session.json in the project root. It does not open a new browser window — it requires Chrome to already be running with --remote-debugging-port=9222.
This step directly affects the quality of the daily brief. Strongly encourage the user to customize before proceeding.
Ask the user:
"The default profile is a generic template. I strongly recommend customizing these files to match your interests — this directly determines the quality of your daily brief. What topics do you care about? What should be filtered out?"
Based on t
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).
summary (number of sources, items fetched, any errors). If successful, show 5-10 sample titles from feed_slim.json.
The system runs in two phases. Phase 1 (scraping) must complete before Phase 2 (memo generation) starts.
Phase 1: Scrape (crontab) — Pure Python job that fetches all sources, deduplicates, and writes feed_slim.json. Set up a daily cron job:
(crontab -l 2>/dev/null; echo "0 9 * * * cd ~/multi-source-feed && .venv/bin/python3 -m src.pipeline >> /tmp/msf-scrape.log 2>&1") | crontab -
Phase 2: Memo (OpenClaw cron) — LLM-powered job that generates the daily brief and sends it to the user. Must run ~20 min after Phase 1 to ensure scraping is complete.
Create an OpenClaw cron job that:
feed_slim.json exists and is from todayconfig/user_profile.md and config/preferences.mdfeed_slim.json (the scrape output)The manual setup fallback instructs users to create and populate a .env file with API keys, which is a form of credential handling. While commonplace, it is still sensitive because the skill offers no safeguards around permissions, secure storage, or preventing accidental disclosure.
pip install -r requirements.txt && playwright install chromium
# 3. Configure
cp .env.example .env
# Edit .env with your API keys
# 4. X Login
The adjacent X login step compounds the credential risk by pairing local secret storage with a script that saves browser session state. In context, this creates a concentrated local repository of both API keys and authenticated session material, substantially increasing the blast radius of any local compromise.
# 3. Configure
cp .env.example .env
# Edit .env with your API keys
# 4. X Login
python login_save_session.py
YARA rule matched a known malware signature (reverse shell, backdoor, ransomware, C2 framework, or info stealer).
│ └───────────────────────────────┬─────────────────────────────────────┘ │ ▼ User's configured channel
## Daily Brief Pipeline
09:00 — crontab triggers python -m src.pipeline │ ├── X/Twitter (Playwright) ──┐ ├── Hacker News (Algolia API) │ ├── GitHub Trending (BeautifulSoup) │ ├── AI blogs & tech media (RSS) ├── raw items ├── Indie blogs & VC blogs (RSS) │ ├── arXiv (RSS) │ ├── Reddit subs (API) │ ├── Product Hunt (GraphQL) │ └── Tavily web searches (API) ──┘ │ ▼ Dedup ├──
The code connects to an already-running Chrome instance over the local DevTools protocol and exports the active browser storage state, including authentication cookies, to disk. For a skill whose stated purpose is configuring a multi-source daily tech brief, this is unrelated capability that can enable credential or session theft and downstream account takeover.
The skill implements browser session extraction by accessing the user's existing Chrome context and serializing its session data to x_session.json. In the context of a news/briefing configuration skill, this behavior is unjustified and especially dangerous because it covertly repurposes unrelated authenticated state from the user's browser for potential impersonation.
The script includes anti-bot evasion measures such as launching Chrome with '--disable-blink-features=AutomationControlled' and redefining 'navigator.webdriver' to hide automation. In a skill advertised for configuring a tech brief, concealment of browser automation is not necessary for legitimate setup and strongly suggests an attempt to bypass platform detection or policy controls.
The implementation directly opens an authenticated X session via a local storage state, navigates to the user's home/following/trending feeds, and bulk-scrapes personalized content. That behavior exceeds the stated purpose of 'setup/configuration' for a daily brief and collects potentially sensitive account-specific data, making the mismatch itself a significant security and privacy risk.
The code launches Chrome with automation-evasion flags and injects a script to hide navigator.webdriver, which are classic anti-detection techniques. In a skill whose purpose is benign feed setup, such stealth behavior is unjustified and increases the likelihood that the code is trying to bypass platform safeguards while accessing user-account content.
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
"""Centralized configuration — reads from .env if present."""
from __future__ import annotations