fix: security and crash bugs in shell, crypto, browser, content skills#302
Closed
lbartoszcze wants to merge 1 commit intomainfrom
Closed
fix: security and crash bugs in shell, crypto, browser, content skills#302lbartoszcze wants to merge 1 commit intomainfrom
lbartoszcze wants to merge 1 commit intomainfrom
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 tosubprocess.Popen(command, shell=True). Any agent can bypass all safety by usingshell:spawninstead ofshell:bashto 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 inSkillResult.data(CRITICAL)The bug:
_create_wallet()returns the private key inSkillResult.data["_private_key"]. This data flows into:recent_actions→ included in LLM prompts → sent to third-party API providersactivity.json→ written to disk in plaintextAny agent holding real funds has its keys exposed to LLM providers and log files.
The fix: Removed
_private_keyfrom result data. The key remains stored securely inself._walletsfor actual blockchain operations.3.
browser.py—AttributeErroron cleanup (HIGH)The bug:
__init__()initializesself.browser,self.context,self.pagebut neverself._playwright. When_close_browser()runs before_ensure_browser()(e.g., during shutdown), it crashes withAttributeError: 'BrowserSkill' object has no attribute '_playwright'.The fix: Initialize
self._playwright = Nonein__init__(). Also guard_close_browser()to handle_playwrightandbrowserindependently.4.
content.py—AttributeErrorwhen no API key available (MEDIUM)The bug:
_init_llm()setsself.modelin the Anthropic and OpenAI branches, but theelsebranch (no API key) only setsself.llmandself.llm_type, leavingself.modelundefined. Downstream code that accessesself.modelcrashes withAttributeError.The fix: Set
self.model = Nonein the else branch.Files changed
singularity/skills/shell.py_check_dangerous_command(), apply to_spawn()singularity/skills/crypto.py_private_keyfromSkillResult.datasingularity/skills/browser.pyself._playwright = None, guard cleanupsingularity/skills/content.pyself.model = Nonein else branchpyproject.tomlpytest-timeoutto dev deps, pytest config.github/workflows/ci.ymltests/test_security_and_crash_fixes.pyTest plan
pytest tests/ -v --timeout=30)🤖 Generated with Claude Code