Skip to content

fix: security and crash bugs in shell, crypto, browser, content skills#302

Closed
lbartoszcze wants to merge 1 commit intomainfrom
fix/security-and-crash-bugs
Closed

fix: security and crash bugs in shell, crypto, browser, content skills#302
lbartoszcze wants to merge 1 commit intomainfrom
fix/security-and-crash-bugs

Conversation

@lbartoszcze
Copy link
Copy Markdown
Contributor

Summary

Fixes 2 security vulnerabilities and 2 crash bugs in the agent runtime, with 22 tests.

1. shell.py_spawn() bypasses all command safety checks (CRITICAL)

The bug: _bash() checks commands against a dangerous-command blocklist before execution. _spawn() does NOT — it passes commands directly to subprocess.Popen(command, shell=True). Any agent can bypass all safety by using shell:spawn instead of shell:bash to run destructive commands as background processes.

The fix: Extracted the blocklist check into _check_dangerous_command() and apply it to both _bash() and _spawn().

2. crypto.py — Private keys leaked in SkillResult.data (CRITICAL)

The bug: _create_wallet() returns the private key in SkillResult.data["_private_key"]. This data flows into:

  • recent_actions → included in LLM prompts → sent to third-party API providers
  • activity.json → written to disk in plaintext

Any agent holding real funds has its keys exposed to LLM providers and log files.

The fix: Removed _private_key from result data. The key remains stored securely in self._wallets for actual blockchain operations.

3. browser.pyAttributeError on cleanup (HIGH)

The bug: __init__() initializes self.browser, self.context, self.page but never self._playwright. When _close_browser() runs before _ensure_browser() (e.g., during shutdown), it crashes with AttributeError: 'BrowserSkill' object has no attribute '_playwright'.

The fix: Initialize self._playwright = None in __init__(). Also guard _close_browser() to handle _playwright and browser independently.

4. content.pyAttributeError when no API key available (MEDIUM)

The bug: _init_llm() sets self.model in the Anthropic and OpenAI branches, but the else branch (no API key) only sets self.llm and self.llm_type, leaving self.model undefined. Downstream code that accesses self.model crashes with AttributeError.

The fix: Set self.model = None in the else branch.

Files changed

File Change
singularity/skills/shell.py Extract _check_dangerous_command(), apply to _spawn()
singularity/skills/crypto.py Remove _private_key from SkillResult.data
singularity/skills/browser.py Initialize self._playwright = None, guard cleanup
singularity/skills/content.py Set self.model = None in else branch
pyproject.toml Add pytest-timeout to dev deps, pytest config
.github/workflows/ci.yml CI workflow (lint + test + build)
tests/test_security_and_crash_fixes.py 22 tests covering all 4 fixes

Test plan

  • 22 tests pass locally (pytest tests/ -v --timeout=30)
  • Lint passes on modified files
  • Package builds cleanly

🤖 Generated with Claude Code

1. shell.py: _spawn() bypassed all dangerous command checks that _bash()
   applied — any agent could run destructive commands as background processes
   by using shell:spawn instead of shell:bash. Extracted check into shared
   _check_dangerous_command() method, applied to both execution paths.

2. crypto.py: _create_wallet() leaked private keys in SkillResult.data
   under '_private_key'. This data flows into LLM context (via recent_actions)
   and activity logs, exposing keys to third-party LLM providers and disk.
   Removed the key from result data; it remains in self._wallets for use.

3. browser.py: self._playwright was never initialized in __init__(), causing
   AttributeError when _close_browser() was called before _ensure_browser()
   (e.g., during cleanup/shutdown). Added initialization and guarded cleanup.

4. content.py: _init_llm() else branch set self.llm and self.llm_type but
   never initialized self.model, causing AttributeError downstream.

22 tests covering all fixes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@lbartoszcze lbartoszcze deleted the fix/security-and-crash-bugs branch February 11, 2026 18:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant