oraios/serena
Dangerous patterns detected — do not install blindly.
View source ↗AI review
The extension contains several patterns that could be risky in an AI agent context, but none appear to be intentionally malicious or deceptive. The usage reporting telemetry is opt-out and runs in CI only, and the remote code execution in build scripts is standard CI/CD practice. The main concern is the copilot-instructions.md file that attempts to force the AI to read a CLAUDE.md file, which could be a vector for prompt injection if that file contains malicious instructions.
- medium Potential prompt injection vector via copilot-instructions.md — The .github/copilot-instructions.md file contains a non-negotiable instruction telling the AI to immediately read and follow instructions from CLAUDE.md. If CLAUDE.md contains malicious or deceptive instructions, this could be used to manipulate the AI agent. However, this appears to be a legitimate project configuration file for GitHub Copilot, not an attempt at injection.
- low Opt-out usage telemetry in agent.py — The agent sends usage data to oraios-software.de via HTTP GET request. The telemetry is gated by CI environment variables and a SERENA_USAGE_REPORTING flag, defaulting to opt-out. While not malicious, this is unnecessary data exfiltration that should be opt-in for an AI agent extension.
- low Remote code execution in CI/CD and Dockerfile — The CI workflow and Dockerfile download and execute remote scripts (curl piped to sh/bash). This is standard practice for CI/CD pipelines and Docker builds, not a runtime risk for the AI agent extension itself.
Model: deepseek-chat
Static findings
Remote code execution · Downloads and executes remote code
.github/workflows/pytest.yml:58
run: curl -LsSf https://astral.sh/uv/install.sh | sh
Dockerfile:30
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install.sh | bash
src/solidlsp/language_servers/lean4_language_server.py:41
" curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | sh\n"
Filesystem writes · Reads or writes the filesystem
docs/autogen_docs.py:73
shutil.rmtree(rst_root)
repo_dir_sync.py:163
shutil.rmtree(self.libRepo.libDirectory)
scripts/demo_diagnostics.py:175
shutil.rmtree(temp_dir, ignore_errors=True)
src/serena/cli.py:591
os.remove(path)
src/serena/config/serena_config.py:866
shutil.move(old_config_path, config_path)
src/serena/hooks.py:520
shutil.rmtree(self.session_persistence_dir, ignore_errors=True)
src/serena/memories/memory_manager.py:311
shutil.move(old_path, new_path)
src/solidlsp/language_servers/elixir_tools/elixir_tools.py:191
os.remove(executable_path)
src/solidlsp/language_servers/haxe_language_server.py:155
os.remove(vsix_path)
src/solidlsp/language_servers/pascal_server.py:396
os.remove(file_path)
Shell / command execution · Executes shell / system commands
docs/create_toc.py:9
os.system(cmd)
repo_dir_sync.py:12
def popen(cmd):
scripts/build_news_json.py:55
os.system(f"scp news/news.json {user}@hades:/var/www/html/oraios-software/serena_news.json")
scripts/bump_version.py:56
os.system("uv lock")
src/serena/cli.py:111
subprocess.run([editor, path], check=False, **run_kwargs)
src/serena/dashboard.py:816
p = subprocess.Popen(
src/serena/util/dotnet.py:30
result = subprocess.run([self._system_dotnet, "--list-runtimes"], capture_output=True, text=True, check=True)
src/serena/util/shell.py:28
process = subprocess.Popen(
src/solidlsp/language_servers/bsl_language_server.py:55
result = subprocess.run(
src/solidlsp/language_servers/clojure_lsp.py:62
return subprocess.run(
src/solidlsp/language_servers/common.py:113
completed_process = subprocess.run(
src/solidlsp/language_servers/elixir_tools/elixir_tools.py:68
result = subprocess.run(["elixir", "--version"], capture_output=True, text=True, check=False)
+ 17 more
Environment variables (config / keys) · Reads environment variables (config / API keys)
scripts/build_news_json.py:53
user = os.getenv("HADES_USER")
src/serena/agent.py:721
if os.getenv("CI") == "true" or os.getenv("GITHUB_ACTIONS") == "true" or os.getenv("SERENA_USAGE_REPORTING") == "false":
src/serena/cli.py:107
editor = os.environ.get("EDITOR")
src/serena/config/serena_config.py:61
home_dir = os.getenv("SERENA_HOME")
src/serena/hooks.py:18
serena_home_dir = os.getenv("SERENA_HOME", "").strip() or str(Path.home() / ".serena")
src/serena/util/exception.py:22
if not os.environ.get("DISPLAY"): # type: ignore
src/serena/util/gui.py:16
display = os.environ.get("DISPLAY", "")
src/serena/util/shell.py:49
args, stdin=subprocess.DEVNULL, stderr=subprocess.PIPE, timeout=timeout, env=os.environ.copy(), cwd=cwd, **subprocess_kwargs()
src/solidlsp/language_servers/al_language_server.py:236
env_path = os.environ.get("AL_EXTENSION_PATH")
src/solidlsp/language_servers/bash_language_server.py:195
"PATH": managed_bin_dir + os.pathsep + os.environ.get("PATH", ""),
src/solidlsp/language_servers/common.py:178
uvx_path = os.environ.get("UVX") or shutil.which("uvx")
src/solidlsp/language_servers/eclipse_jdtls.py:682
elif env_home := os.environ.get("JAVA_HOME"):
+ 12 more
Outbound network · Makes outbound network requests
src/serena/agent.py:731
requests.get("https://oraios-software.de/serena_usage.php", params=params, timeout=1)
src/serena/dashboard.py:10
import urllib.request
src/serena/util/dotnet.py:103
urllib.request.urlretrieve(script_url, script_path)
src/solidlsp/language_servers/haxe_language_server.py:11
import urllib.request
src/solidlsp/language_servers/pascal_server.py:60
import urllib.request
Scanning every extension your team installs?
Pro & Team add monitoring, private scans, and a CI gate for unsafe extensions.
MCPVet is a heuristic aid, not a security guarantee. A clean grade does not prove an extension is safe; always review code and instructions you don't trust.