T09 · Insecure Skill Coding Practices
- Location
scripts/hot_scanner.py:22- Finding
Third-Party Twitter CLI Receives the Complete Process Environment
- Content
View full analysis
Vulnerability Details
File Locations:
scripts/hot_scanner.py:22-30scripts/hot_scanner.py:387-391scripts/rumor_scanner.py:30-38scripts/rumor_scanner.py:79-81scripts/rumor_scanner.py:132-134
Vulnerability Type: Excessive exposure of environment variables to a third-party subprocess
Risk Level: MediumVulnerable Code
scripts/hot_scanner.py:22-30:python # Load .env file if exists ENV_FILE = Path(__file__).parent.parent / ".env" if ENV_FILE.exists(): with open(ENV_FILE) as f: for line in f: line = line.strip() if line and not line.startswith("#") and "=" in line: key, value = line.split("=", 1) os.environ[key] = valuescripts/hot_scanner.py:387-391:python env = os.environ.copy() result = subprocess.run( [bird_bin, "search", query, "-n", "15", "--json"], capture_output=True, text=True, timeout=30, env=env )scripts/rumor_scanner.py:30-38:python BIRD_ENV = Path(__file__).parent.parent / ".env" def load_env(): """Load environment variables from .env file.""" if BIRD_ENV.exists(): for line in BIRD_ENV.read_text().splitlines(): if '=' in line and not line.startswith('#'): key, value = line.split('=', 1) os.environ[key.strip()] = value.strip().strip('"').strip("'")scripts/rumor_scanner.py:79-81:python env = os.environ.copy() result = subprocess.run(cmd, capture_output=True, text=True, timeout=30, env=env)scripts/rumor_scanner.py:132-134:python env = os.environ.copy() result = subprocess.run(cmd, capture_output=True, text=True, timeout=30, env=env)Technical Analysis
Both scanners load every key found in the project-level
.envfile into the global process environment. They then copy the complete environment and provide it to ...[truncated 2004 chars]- Remediation
View remediation
Remediation Suggestions
- Do not load arbitrary
.enventries into globalos.environ. - Parse only explicitly permitted keys, such as
AUTH_TOKENandCT0. - Construct a minimal subprocess environment rather than copying the parent environment:
python allowed_env = { "PATH": os.environ.get("PATH", ""), "HOME": os.environ.get("HOME", ""), "LANG": os.environ.get("LANG", "C.UTF-8"), "AUTH_TOKEN": auth_token, "CT0": ct0, } subprocess.run( [bird_bin, "search", query, "-n", "15", "--json"], capture_output=True, text=True, timeout=30, env=allowed_env, check=False, )- Validate
.envkey names and reject duplicate or unexpected entries. - Keep Twitter credentials in a dedicated credential store or dedicated configuration file with owner-only permissions rather than a general-purpose project
.env. - Resolve
birdfrom an explicitly configured, trusted project-local path and verify the expected version before execution. - Run the social-media integration in a restricted subprocess or container with limited filesystem and network access.
- Document precisely which credentials are disclosed to the Twitter integration.
- Do not load arbitrary
