Skills/PyPI/portal-mcp-server

portal-mcp-server@4.0.3

CAUTION· not started

Publisher claims: "Agent-feels-local SSH orchestration MCP server — persistent bash, hash-protected editing, SFTP, tunnels, multi-host orchestration over AsyncSSH" Observed in sandbox: no network, touches nothing outside the project, writes no memory.

Registry PyPI (MCP server)Publisher tmytimidly · publishing for 185 daysInstalls 172Last detonated 28 min ago

Coverage

Not started: dependency install failed; the server itself was not observed.
Tested
the dependency install step · every file read, file written and host contacted by what ran
Not tested
server startup · the tool list · tool behavior

What this means for the label: Caution here covers what ran. The server's tools were not exercised with a real credential, so nothing about their behavior is asserted; the credential summary below says what to do with that.

Before you give it your token

It will ask for
GITHUB_TOKENPORTAL_AUTH_TOKENPORTAL_CREDENTIAL_AGENT_SOCKETConfiguration, not credentials: PORTAL_ALLOW_LOCAL_EXEC, PORTAL_ALLOW_TUNNEL_EXPOSURE, PORTAL_BASH_HEARTBEAT_INTERVAL, PORTAL_JOB_MAX_LIVE, PORTAL_JOB_PERSIST, PORTAL_JOB_STATE_FILE, PORTAL_JOB_TTL, PORTAL_LOGIN_SHELL, PORTAL_MAX_TIMEOUT, PORTAL_SSH_CONFIG, PROGRAMDATA, XDG_RUNTIME_DIR
Where it talks to
no vendor host named in the code
What the honeypot saw
no credential files read · no network
What we could not test
server startup · the tool list · tool behavior

Connect it with a scoped credential, under the guard. It asks for GITHUB_TOKEN, PORTAL_AUTH_TOKEN, PORTAL_CREDENTIAL_AGENT_SOCKET and talks to its vendor. Give the credential to the guard, not the server: the value never enters the server's environment and only travels to the host you bind. What the tools do with a real credential was not observed.

$vet-skills run --net declared -- uvx portal-mcp-server

Never paste a credential into a chat, a ticket or a report, including ours. How the guard holds it.

Is [email protected] safe to install?

KillerSkills ran it in the KillerSkills honeypot sandbox (2 scenarios; not started: dependency install failed; the server itself was not observed) on 2026-11-14 and scored it 62/100 (Caution). It is not known to be malicious, but it has behaviour or code a security policy should decide on before install. Notable findings: Privileged sudo command; Access to sensitive file paths; Privileged sudo command. Summary: no network, touches nothing outside the project, writes no memory.

Behavior trace

Honeypot run · 0 s · 2 scenarios · 0 deviations
t+CategoryObserved action
0.0sprocessno install scripts in bundle
0.2sprocessdependency install exit 1 ·
0.2sclaimednot started: dependency install failed (exit 1); the server itself was not observed
0.2sprocessscript backend runs setup only
0.2sprocessno install scripts to re-run

Static findings

HIGH
Privileged sudo commandportal_mcp_server/cli.py:380 · Privileged sudo command — agent may execute with elevated privilegesf"No sudo password available for host '{host}'; the command was NOT "Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Access to sensitive file pathsportal_mcp_server/cli.py:517 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files# (c) Only a name was given. If ~/.ssh/config has a matching HostFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
HIGH
Privileged sudo commandportal_mcp_server/cli.py:396 · Privileged sudo command — agent may execute with elevated privileges"""Friendly error when no sudo password is available for the LOCAL machine.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
CRITICAL
Prompting user to enter sensitive credentialsportal_mcp_server/cli.py:407 · Prompting user to enter sensitive credentials — social engineering"in a separate terminal, type the password at the hidden prompt, then "Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST03
HIGH
Collapsed <details> block carrying instructionsREADME.en.md:343 · Collapsed <details> block carrying instructions<summary>Expand</summary> A stdio MCP server's stderr is invisible to the user, so operationally important warnings (misconfigured yaml, missing credentials, igFix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.
AST01
CRITICAL
Reads credential paths from the home directoryportal_mcp_server/cli.py:496 · Reads credential paths from the home directoryHosts already defined in ~/.ssh/config are auto-resolved on first use; explicitFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST03
HIGH
Access to sensitive file pathsportal_mcp_server/cli.py:486 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesor just `name` if ~/.ssh/config has a matching Host alias (registers aFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
HIGH
Privileged sudo commandportal_mcp_server/cli.py:403 · Privileged sudo command — agent may execute with elevated privileges"No sudo password available for THIS machine (local_exec); the command "Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Collapsed <details> block carrying instructionsREADME.md:219 · Collapsed <details> block carrying instructions<summary>为什么这是一条不为便利让步的边界("活过 agent 关闭"为何不靠子进程)</summary> agent 常想要"持久传输 / 活过 agent 关闭",最直觉的实现是 `nohup` 一个 `scp` / `rsync` 子进程。portal **故意不做**——子进程那条路绕开了上面这条统一凭Fix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.
AST01
HIGH
Collapsed <details> block carrying instructionsREADME.en.md:326 · Collapsed <details> block carrying instructions<summary>Expand</summary> Every credential kind — SSH key, login password, key passphrase, sudo password, named secret — is resolved on one in-process asyncssh Fix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.
AST01
HIGH
Privileged sudo commandportal_mcp_server/cli.py:383 · Privileged sudo command — agent may execute with elevated privilegesf" • Temporary (no-echo, cached with a TTL): run `portal sudo set "Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Access to sensitive file pathsportal_mcp_server/cli.py:478 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesclient config (`~/.ssh/config` + system-wide fallback; or onlyFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
HIGH
Collapsed <details> block carrying instructionsREADME.en.md:352 · Collapsed <details> block carrying instructions<summary>Maintainer boundaries & footguns</summary> - **exec-output-strip vs. file-read-must-not-strip**: one-shot exec strips trailing newlines (shell conventiFix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.
AST01
HIGH
References a credential file in the home directoryportal_mcp_server/cli.py:488 · References a credential file in the home directory22), key_path (else asyncssh falls back to ~/.ssh/id_* or ssh-agent),Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST03
CRITICAL
Destructive command against a filesystem root or deviceportal_mcp_server/shell_engine.py:9 · Destructive command against a filesystem root or deviceexpanded to ``cd /tmp; rm -rf / && <cmd>``.Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
CRITICAL
Destructive command against a filesystem root or deviceportal_mcp_server/shell_engine.py:8 · Destructive command against a filesystem root or device``cd`` argument. Before this fix, ``cwd="/tmp; rm -rf /"`` would haveFix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
CRITICAL
Destructive command against a filesystem root or deviceportal_mcp_server/safety.py:154 · Destructive command against a filesystem root or deviceworst (e.g. ``"FOO; rm -rf /"``) an injection sink. Reject up-front.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
CRITICAL
Prompting user to enter sensitive credentialsportal_mcp_server/cli.py:384 · Prompting user to enter sensitive credentials — social engineeringf"{host}` in a separate terminal, type the password at the hidden "Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST03
CRITICAL
Prompting user to enter sensitive credentialsportal_mcp_server/cli.py:156 · Prompting user to enter sensitive credentials — social engineeringf"user to paste the secret value into this conversation."Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST03
HIGH
Collapsed <details> block carrying instructionsREADME.en.md:314 · Collapsed <details> block carrying instructions<summary>Expand</summary> [asyncssh](https://github.com/ronf/asyncssh) (EPL-2.0 / GPL-2.0 dual-licensed) is an independent pure-Python SSHv2 implementation, proFix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.
AST01
HIGH
Credential pass-through configurationportal_mcp_server/cli.py:1217 · Credential pass-through configuration — agent relays sensitive credentials`portal secret set <name>` in their own terminal; you passFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST02
CRITICAL
Prompting user to enter sensitive credentialsportal_mcp_server/cli.py:441 · Prompting user to enter sensitive credentials — social engineering"terminal first — never have them paste the password into the chat."Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST03
HIGH
Privileged sudo commandportal_mcp_server/cli.py:375 · Privileged sudo command — agent may execute with elevated privileges"""Friendly error when no sudo password is available for ``host``.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Access to sensitive file pathsportal_mcp_server/cli.py:488 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files22), key_path (else asyncssh falls back to ~/.ssh/id_* or ssh-agent),Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
CRITICAL
Prompting user to enter sensitive credentialsportal_mcp_server/remote_bash.py:64 · Prompting user to enter sensitive credentials — social engineering"terminal first (never have them paste the password into the conversation)."Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST03
HIGH
Collapsed <details> block carrying instructionsREADME.en.md:417 · Collapsed <details> block carrying instructions<summary>Expand the dev setup</summary> ```bash git clone [email protected]:TMYTiMidlY/portal-mcp-server.git cd portal-mcp-server uv sync --all-extras source .venvFix: Remove the text that addresses the agent rather than the reader; describe behavior, do not instruct.
AST01
HIGH
Access to sensitive file pathsportal_mcp_server/cli.py:496 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesHosts already defined in ~/.ssh/config are auto-resolved on first use; explicitFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
HIGH
Destructive file system command detectedportal_mcp_server/cli.py:791 · Destructive file system command detected- command="rm -rf /" : check whether this command would be allowed on this host.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
CRITICAL
Destructive command against a filesystem root or deviceportal_mcp_server/cli.py:791 · Destructive command against a filesystem root or device- command="rm -rf /" : check whether this command would be allowed on this host.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Credential pass-through configurationportal_mcp_server/cli.py:1429 · Credential pass-through configuration — agent relays sensitive credentialsyou pass secrets=["<name>"] and reference it as the uppercased env varFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST02
MEDIUM
File permission modification commandportal_mcp_server/shell_engine.py:177 · File permission modification command — agent changes file ownership/permissionsf"chmod +x {quoted_path} && {interpreter} {quoted_path}",Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
HIGH
Privileged sudo commandportal_mcp_server/secrets_store.py:6 · Privileged sudo command — agent may execute with elevated privilegessudo password (see :mod:`sudo_creds`): the value must reach the executed commandFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Access to sensitive file pathsportal_mcp_server/paths.py:143 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files# asyncssh's *discovery* is a single inline line — ``Path('~/.ssh/config')``Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Process kill commandportal_mcp_server/safety.py:52 · Process kill command — agent can terminate processes# Unix signal names accepted by `kill -<NAME>`. We don't accept numeric signalsFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Privileged sudo commandportal_mcp_server/secrets_store.py:129 · Privileged sudo command — agent may execute with elevated privilegesinput framing in one place. Values are fed in list order, AFTER the sudoFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Access to sensitive file pathsportal_mcp_server/paths.py:177 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files"the literal 'none' is accepted. Falling back to ~/.ssh/config.", raw,Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
MCP server using network transport (SSE/HTTP)pyproject.toml:95 · MCP server using network transport (SSE/HTTP) — data sent over network[![PyPI](https://img.shields.io/pypi/v/portal-mcp-server)](https://pypi.org/project/portal-mcp-server/)Fix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them.
AST04
HIGH
Privileged sudo commandportal_mcp_server/remote_bash.py:62 · Privileged sudo command — agent may execute with elevated privileges"feeds the stored sudo password to `sudo -S -k` on stdin. If no password is "Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Access to sensitive file pathsportal_mcp_server/paths.py:186 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesconventional ``~/.ssh/config`` default. :func:`ssh_config_files` remains theFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
HIGH
Privileged sudo commandportal_mcp_server/local_exec.py:94 · Privileged sudo command — agent may execute with elevated privilegeslog). ``-k`` forces a fresh auth so a cached sudo ticket can't mask a wrongFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Privileged sudo commandportal_mcp_server/session_manager.py:105 · Privileged sudo command — agent may execute with elevated privileges# The zh_CN sudo prompt "的密码" is its UTF-8 bytes. Kept deliberately small:Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandportal_mcp_server/safety_net.py:205 · Process kill command — agent can terminate processes"""Best-effort kill of a stuck subprocess (timeout path)."""Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Privileged sudo commandportal_mcp_server/sudo_creds.py:6 · Privileged sudo command — agent may execute with elevated privilegesmodel entirely, then feeds it to ``sudo -S`` on stdin (see remote_bash):Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
References a credential file in the home directorytests/live_smoke.py:36 · References a credential file in the home directoryTEST_KEY = os.environ.get("PORTAL_TEST_KEY_PATH", os.path.expanduser("~/.ssh/id_ed25519"))Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST03
HIGH
Privileged sudo commandportal_mcp_server/remote_bash.py:55 · Privileged sudo command — agent may execute with elevated privileges"(most often sudo asking for a password, but also ssh's first-connect "Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Destructive file system command detectedportal_mcp_server/shell_engine.py:9 · Destructive file system command detectedexpanded to ``cd /tmp; rm -rf / && <cmd>``.Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
npx invocation of non-well-known packageportal_mcp_server/safety_net.py:143 · npx invocation of non-well-known package — may execute untrusted codethe loop keep scheduling other coroutines while the npx subprocessFix: Pin versions and sources; vendor anything fetched at install time.
AST06
MEDIUM
npx invocation of non-well-known packageportal_mcp_server/safety_net.py:32 · npx invocation of non-well-known package — may execute untrusted codekeeps scheduling other coroutines while the npx subprocess runs — a syncFix: Pin versions and sources; vendor anything fetched at install time.
AST06
HIGH
Privileged sudo commandportal_mcp_server/remote_bash.py:50 · Privileged sudo command — agent may execute with elevated privileges# sudo command is the one-shot sudo path, not a retry (which would wedge again).Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Destructive file system command detectedportal_mcp_server/shell_engine.py:8 · Destructive file system command detected``cd`` argument. Before this fix, ``cwd="/tmp; rm -rf /"`` would haveFix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
HIGH
Privileged sudo commandportal_mcp_server/local_exec.py:110 · Privileged sudo command — agent may execute with elevated privilegeswrapped = f"sudo -S -k -p '' -- bash -c {quote_shell(body)}"Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Access to sensitive file pathsportal_mcp_server/paths.py:135 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files# * unset -> user ``~/.ssh/config`` + system ``/etc/ssh/ssh_config``Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Process kill commandportal_mcp_server/job_manager.py:329 · Process kill command — agent can terminate processesf"if kill -0 {rec.remote_pid} 2>/dev/null; then A=yes; else A=no; fi; "Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/conftest.py:176 · Privileged sudo command — agent may execute with elevated privileges# Clear credential caches (sudo / ssh / key passphrase / named-secret).Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Privileged sudo commandportal_mcp_server/job_manager.py:25 · Privileged sudo command — agent may execute with elevated privileges* ``use_sudo`` / ``secrets`` are NOT supported in the background (sudo -S wantsFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Privileged sudo commandportal_mcp_server/ssh_creds.py:5 · Privileged sudo command — agent may execute with elevated privilegeskey passphrase and not the sudo password (the one fed to ``sudo -S`` on stdinFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Access to sensitive file pathsportal_mcp_server/remote_search.py:356 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files# (e.g. './.github/x' -> 'github/x', './.env' -> 'env').Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Process kill commandportal_mcp_server/job_manager.py:438 · Process kill command — agent can terminate processesf'[ -n "$PGID" ] && kill -{sig} -"$PGID" 2>/dev/null; 'Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandportal_mcp_server/job_manager.py:439 · Process kill command — agent can terminate processesf'kill -{sig} {pid} 2>/dev/null; 'Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandportal_mcp_server/cli.py:1638 · Process kill command — agent can terminate processes# still kill its jobs (consistent with remote_tunnel close).Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Privileged sudo commandportal_mcp_server/local_exec.py:7 · Privileged sudo command — agent may execute with elevated privilegesderivative (it happens to reuse the secret / sudo credential machinery), so theFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Hex-encoded string detectedportal_mcp_server/session_manager.py:110 · Hex-encoded string detected — may contain obfuscated payloadsrb"\[sudo\][^\n]*(?:password for |\xe7\x9a\x84\xe5\xaf\x86\xe7\xa0\x81)"Fix: Put hosts, commands and strings in plain source. Decoding at runtime looks identical to malware and costs points on its own.
AST07
HIGH
Privileged sudo commandportal_mcp_server/sudo_creds.py:8 · Privileged sudo command — agent may execute with elevated privileges1. **Live input (1b)** — ``portal sudo set <host>`` prompts withFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Privileged sudo commandportal_mcp_server/local_exec.py:24 · Privileged sudo command — agent may execute with elevated privilegesthe shell / sudo don't survive a timeout. Falls back to killing just theFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive file system command detectedtests/live_smoke.py:123 · Destructive file system command detectedcommand="rm -rf /tmp/x", timeout=5)Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Destructive file system command detectedportal_mcp_server/safety.py:154 · Destructive file system command detectedworst (e.g. ``"FOO; rm -rf /"``) an injection sink. Reject up-front.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Access to sensitive file pathsportal_mcp_server/paths.py:194 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesreturn "~/.ssh/config"Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
MCP server using network transport (SSE/HTTP)pyproject.toml:100 · MCP server using network transport (SSE/HTTP) — data sent over network📖 [Repository & full docs](https://github.com/TMYTiMidlY/portal-mcp-server) | 🇬🇧 [English README](https://github.com/TMYTiMidlY/portal-mcp-server/blob/main/README.en.md)Fix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them.
AST04
HIGH
Privileged sudo commandportal_mcp_server/sudo_creds.py:1 · Privileged sudo command — agent may execute with elevated privileges"""sudo_creds — out-of-band sudo password provisioning.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Privileged sudo commandportal_mcp_server/sudo_creds.py:15 · Privileged sudo command — agent may execute with elevated privileges``secret-tool lookup sudo web01``). Symmetric to the existingFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Privileged sudo commandportal_mcp_server/safety.py:78 · Privileged sudo command — agent may execute with elevated privilegesprevents mismatches like a sudo password cached under ``'web01 '`` neverFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Privileged sudo commandportal_mcp_server/local_exec.py:92 · Privileged sudo command — agent may execute with elevated privileges``sudo -S -k -p '' -- bash -c <body>`` and writes the password to theFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
HIGH
Privileged sudo commandportal_mcp_server/sudo_creds.py:3 · Privileged sudo command — agent may execute with elevated privilegesThe agent (LLM) must never see a sudo password: if a password were passed asFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
npx invocation of non-well-known packageportal_mcp_server/safety_net.py:173 · npx invocation of non-well-known package — may execute untrusted code# backgrounded npx that keeps holding pipes open.Fix: Pin versions and sources; vendor anything fetched at install time.
AST06
MEDIUM
npx invocation of non-well-known packageportal_mcp_server/safety_net.py:233 · npx invocation of non-well-known package — may execute untrusted code"and runnable (`npx -y cc-safety-net@latest doctor`), or set "Fix: Pin versions and sources; vendor anything fetched at install time.
AST06
HIGH
Privileged sudo commandportal_mcp_server/secrets_store.py:87 · Privileged sudo command — agent may execute with elevated privilegesname, AFTER the sudo password) and decoded back inside the already-elevatedFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandportal_mcp_server/job_manager.py:441 · Process kill command — agent can terminate processesf'if kill -0 {pid} 2>/dev/null; then echo ALIVE; else echo DEAD; fi'Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_host_ssh_config.py:341 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesuser ~/.ssh/config and the system-wide config are suppressed."""Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Access to sensitive file pathstests/live_smoke.py:36 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesTEST_KEY = os.environ.get("PORTAL_TEST_KEY_PATH", os.path.expanduser("~/.ssh/id_ed25519"))Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Privileged sudo commandtests/test_local_sudo.py:6 · Privileged sudo command — agent may execute with elevated privileges``localhost``. The sudo password reaches ``sudo -S`` only through the in-memoryFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_host_ssh_config.py:1 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files"""hosts.yaml <-> ~/.ssh/config interaction: conflict detection + overlay.Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Destructive file system command detectedtests/live_smoke.py:165 · Destructive file system command detectedout = await cli.remote_shell("live-smoke", "rm -rf /tmp/whatever", timeout=2)Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_exec_credentials_ux.py:147 · Privileged sudo command — agent may execute with elevated privileges# ── explicit ssh-login-password → sudo cache convenience ────────────────────Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Destructive file system command detectedtests/test_live_ssh.py:367 · Destructive file system command detectederr = await pol.check_command("rm -rf /")Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_gate_coverage_fixes.py:232 · Destructive command against a filesystem root or deviceerr = await cli._gate_exec(["safe-01"], ["echo a", "rm -rf /"])Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_host_ssh_config.py:109 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesassert "~/.ssh/config" in outFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Privileged sudo commandtests/test_exec_credentials_ux.py:40 · Privileged sudo command — agent may execute with elevated privilegesto the sudo exec as env (delivered on stdin inside the elevated shell), andFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Privileged sudo commandtests/test_host_normalize.py:3 · Privileged sudo command — agent may execute with elevated privileges(the reported ``sudo password for host 'LisaHost '`` bug).Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
References a credential file in the home directorytests/test_live_ssh.py:30 · References a credential file in the home directoryTEST_KEY = os.environ.get("PORTAL_TEST_KEY_PATH", os.path.expanduser("~/.ssh/id_ed25519"))Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST03
MEDIUM
Destructive file system command detectedtests/test_live_ssh.py:362 · Destructive file system command detectedpol.command_blocklist = ["rm -rf /"]Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_local_sudo.py:1 · Privileged sudo command — agent may execute with elevated privileges"""Local sudo for local_exec — the LOCAL counterpart of the remoteFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_host_ssh_config.py:389 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files(PORTAL_SSH_CONFIG), not a hardcoded ~/.ssh/config."""Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Privileged sudo commandtests/test_bash_heartbeat.py:195 · Privileged sudo command — agent may execute with elevated privileges# sudo + secrets moved here (one-shot paths).Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive file system command detectedtests/test_command_injection.py:97 · Destructive file system command detectedassert cmd.startswith("cd '/tmp; rm -rf /'")Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandtests/test_encoding_resilience.py:136 · Process kill command — agent can terminate processesasyncssh so GBK / Latin-1 bytes don't kill the channel."""Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_exec_multihost.py:137 · Privileged sudo command — agent may execute with elevated privilegeswith pytest.raises(ToolError, match="No sudo password"):Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_host_ssh_config.py:378 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files(read nothing) instead of letting it fall back to ~/.ssh/config."""Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Destructive file system command detectedtests/test_command_injection.py:92 · Destructive file system command detected# which would have run `rm -rf /` as a separate command.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_grep_glob.py:226 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files".github/workflows/ci.yml", ".env", "src/app.py"}Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_command_injection.py:97 · Destructive command against a filesystem root or deviceassert cmd.startswith("cd '/tmp; rm -rf /'")Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
MCP server using network transport (SSE/HTTP)tests/test_http_transport_bind.py:32 · MCP server using network transport (SSE/HTTP) — data sent over network["portal-mcp-server", "--transport", "streamable_http", "--host", "0.0.0.0"])Fix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them.
AST04
MEDIUM
Destructive file system command detectedtests/test_command_injection.py:91 · Destructive file system command detected# BEFORE the fix this produced: cd /tmp; rm -rf / && idFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_command_injection.py:96 · Destructive command against a filesystem root or device_assert_no_unquoted_metas(cmd, ["; rm -rf /", "&& rm"])Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_exec_credentials_ux.py:99 · Privileged sudo command — agent may execute with elevated privilegesassert "portal sudo set web01" in msg # temporary (no-echo)Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Access to sensitive file pathstests/test_grep_glob.py:217 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesleading dots: './.github/x' -> 'github/x', './.env' -> 'env'). Regression."""Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Destructive file system command detectedtests/test_gate_coverage_fixes.py:232 · Destructive file system command detectederr = await cli._gate_exec(["safe-01"], ["echo a", "rm -rf /"])Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive file system command detectedtests/test_command_injection.py:96 · Destructive file system command detected_assert_no_unquoted_metas(cmd, ["; rm -rf /", "&& rm"])Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Reads credential paths from the home directorytests/test_host_normalize.py:59 · Reads credential paths from the home directorymonkeypatch.setenv("PORTAL_SSH_CONFIG", "none") # don't read real ~/.ssh/configFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST03
MEDIUM
Access to sensitive file pathstests/test_live_ssh.py:30 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesTEST_KEY = os.environ.get("PORTAL_TEST_KEY_PATH", os.path.expanduser("~/.ssh/id_ed25519"))Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Destructive file system command detectedtests/test_command_injection.py:94 · Destructive file system command detectedawait ssh_exec("h", "id", cwd="/tmp; rm -rf /")Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_exec_multihost.py:130 · Privileged sudo command — agent may execute with elevated privileges# ── sudo across the fan-out ─────────────────────────────────────────────────Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_exec_credentials_ux.py:2 · Privileged sudo command — agent may execute with elevated privileges* sudo / secret exec results are flagged high_risk so the agent reports it;Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_live_ssh.py:367 · Destructive command against a filesystem root or deviceerr = await pol.check_command("rm -rf /")Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_local_sudo.py:7 · Privileged sudo command — agent may execute with elevated privilegescache / per-user agent (``portal sudo set-local``) or a TOP-LEVEL ``<local>:``Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_live_ssh.py:362 · Destructive command against a filesystem root or devicepol.command_blocklist = ["rm -rf /"]Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_grep_glob.py:220 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files"./.github/workflows/ci.yml\n./.env\n./src/app.py\n",Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Access to sensitive file pathstests/test_host_normalize.py:59 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesmonkeypatch.setenv("PORTAL_SSH_CONFIG", "none") # don't read real ~/.ssh/configFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_command_injection.py:94 · Destructive command against a filesystem root or deviceawait ssh_exec("h", "id", cwd="/tmp; rm -rf /")Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedtests/test_local_sudo.py:175 · Python subprocess execution detectedproc = subprocess.run(["bash", "-c", body], input=payload.encode(),Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Privileged sudo commandtests/test_exec_multihost.py:148 · Privileged sudo command — agent may execute with elevated privilegesassert all("no sudo password" in r.get("error", "") for r in out)Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_command_injection.py:91 · Destructive command against a filesystem root or device# BEFORE the fix this produced: cd /tmp; rm -rf / && idFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_exec_credentials_ux.py:188 · Privileged sudo command — agent may execute with elevated privilegesassert "sudo password also cached" in capsys.readouterr().outFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Access to sensitive file pathstests/test_host_key_policy.py:33 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files# Empty tuple = "use default ~/.ssh/known_hosts and be strict",Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Privileged sudo commandtests/test_local_sudo.py:168 · Privileged sudo command — agent may execute with elevated privilegesRuns the generated script body (minus the sudo wrapper) through real bashFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_host_key_policy.py:57 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files# The shortcut path that defers to ~/.ssh/config used to beFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_policy_enforcement.py:81 · Destructive command against a filesystem root or devicecommand="rm -rf /", timeout=5)Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive file system command detectedtests/test_policy_enforcement.py:130 · Destructive file system command detectedcommand="rm -rf /tmp/x", serialize=True, timeout=5,Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_osc133_session.py:258 · Privileged sudo command — agent may execute with elevated privilegesawait sm.execute_in_session(sid, "sudo whoami", timeout=10)Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Python subprocess execution detectedtests/test_server_lifespan.py:74 · Python subprocess execution detectedresult = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
AST05
MEDIUM
Destructive file system command detectedtests/test_patch_sudo.py:148 · Destructive file system command detectedwired["stat"] = "ro;rm -rf / root 644\n" # injected metacharsFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_patch_sudo.py:119 · Privileged sudo command — agent may execute with elevated privilegeswith pytest.raises(rte.RemoteEditError, match="sudo password"):Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_patch_sudo.py:120 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesawait rte._sudo_cat("h", "/etc/shadow", "utf-8")Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Privileged sudo commandtests/test_osc133_session.py:285 · Privileged sudo command — agent may execute with elevated privilegesawait sm.execute_in_session(sid, "sudo whoami", timeout=10)Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive file system command detectedtests/test_safety.py:110 · Destructive file system command detectedassert "; rm -rf /" not in out.split(" && ", 1)[0].replace("'", "")[:0]Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_osc133_session.py:401 · Privileged sudo command — agent may execute with elevated privileges"h", ["echo a", "sudo whoami", "echo b"])Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_patch_sudo.py:156 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesres = await rte.remote_read("h", "/etc/shadow", use_sudo=True)Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_safety.py:77 · Destructive command against a filesystem root or device("a;rm -rf /", "'a;rm -rf /'"),Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive file system command detectedtests/test_safety.py:108 · Destructive file system command detectedassert out.startswith("cd '/tmp; rm -rf /'")Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_ssh_login.py:89 · Privileged sudo command — agent may execute with elevated privileges`portal sudo set`, `portal secret set`) must keep independent caches so clearing oneFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_safety.py:108 · Destructive command against a filesystem root or deviceassert out.startswith("cd '/tmp; rm -rf /'")Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_safety.py:110 · Destructive command against a filesystem root or deviceassert "; rm -rf /" not in out.split(" && ", 1)[0].replace("'", "")[:0]Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive file system command detectedtests/test_policy_enforcement.py:236 · Destructive file system command detectedcommands=["uptime", "rm -rf /var", "echo done"], timeout=5)Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_patch_sudo.py:111 · Privileged sudo command — agent may execute with elevated privilegesassert cmd.startswith("sudo -S -k -p '' cat -- ") and stdin == "sekret\n"Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
File permission modification commandtests/test_patch_sudo.py:131 · File permission modification command — agent changes file ownership/permissionsassert "chown root:root" in place and "chmod 644" in placeFix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts.
AST05
MEDIUM
Destructive file system command detectedtests/test_safety.py:105 · Destructive file system command detectedout = build_cwd_prefix("/tmp; rm -rf /", "ls")Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_paths.py:192 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system files(home / ".ssh").mkdir(parents=True) # no ~/.ssh/config writtenFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Privileged sudo commandtests/test_osc133_session.py:406 · Privileged sudo command — agent may execute with elevated privilegesassert res["stopped_at"] == "sudo whoami"Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandtests/test_portal_job.py:231 · Process kill command — agent can terminate processesassert not any("kill -" in c and "PGID=" in c for c in rec) # no signal sentFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_portal_job.py:313 · Destructive command against a filesystem root or deviceawait cli.remote_job(action="submit", host="h", command="rm -rf /")Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandtests/test_portal_job.py:6 · Process kill command — agent can terminate processesmarker, cancel uses `kill -`).Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_safety.py:105 · Destructive command against a filesystem root or deviceout = build_cwd_prefix("/tmp; rm -rf /", "ls")Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_resource_lifecycle.py:213 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesout = await ssh_read_file("h", "/etc/passwd\x00trick")Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Privileged sudo commandtests/test_sudo_auth.py:4 · Privileged sudo command — agent may execute with elevated privileges``sudo -S`` only through the in-memory cache (populated by the ``portal sudo set``Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Process kill commandtests/test_portal_job.py:191 · Process kill command — agent can terminate processesassert any("kill -KILL 100" in c for c in rec)Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive file system command detectedtests/test_policy_enforcement.py:81 · Destructive file system command detectedcommand="rm -rf /", timeout=5)Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_safety.py:49 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesvalidate_remote_path("/tmp/legit\x00/etc/passwd")Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Destructive file system command detectedtests/test_policy_enforcement.py:23 · Destructive file system command detected"""Install a policy that blocks ``rm -rf /`` and only allows hostsFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_paths.py:151 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesassert paths.ssh_config_source_label() == "~/.ssh/config"Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Privileged sudo commandtests/test_sudo_auth.py:3 · Privileged sudo command — agent may execute with elevated privilegesMirrors the philosophy of test_password_auth.py: a sudo password must reachFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive file system command detectedtests/test_portal_job.py:313 · Destructive file system command detectedawait cli.remote_job(action="submit", host="h", command="rm -rf /")Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
npx invocation of non-well-known packagetests/test_safety_net.py:15 · npx invocation of non-well-known package — may execute untrusted codeevent loop must not be blocked while the npx subprocess runs).Fix: Pin versions and sources; vendor anything fetched at install time.
AST06
MEDIUM
Access to sensitive file pathstests/test_patch_sudo.py:108 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesout = await rte._sudo_cat("h", "/etc/shadow", "utf-8")Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Access to sensitive file pathstests/test_paths.py:171 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesassert paths.ssh_config_source_label() == "~/.ssh/config"Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Privileged sudo commandtests/test_sudo_auth.py:1 · Privileged sudo command — agent may execute with elevated privileges"""sudo password provisioning — out-of-band sources, never via the LLM.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_remote_text_editor.py:258 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesawait remote_read("h", "/etc/passwd\x00fake")Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Destructive file system command detectedtests/test_safety.py:77 · Destructive file system command detected("a;rm -rf /", "'a;rm -rf /'"),Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive file system command detectedtests/test_resource_lifecycle.py:9 · Destructive file system command detected* ssh_exec_script's cleanup ``rm -f /tmp/<x>`` was outside ``finally``, soFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_patch_sudo.py:2 · Privileged sudo command — agent may execute with elevated privilegessudo path that preserves the patch hash contract, owner/mode, and atomicity.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Destructive command against a filesystem root or devicetests/test_patch_sudo.py:148 · Destructive command against a filesystem root or devicewired["stat"] = "ro;rm -rf / root 644\n" # injected metacharsFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Access to sensitive file pathstests/test_safety.py:70 · Access to sensitive file paths — SSH keys, AWS credentials, env files, or system filesassert validate_remote_path("../etc/passwd") == "../etc/passwd"Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
AST05
MEDIUM
Destructive file system command detectedtests/test_policy_enforcement.py:172 · Destructive file system command detectedcommands=["uptime", "rm -rf /opt"],Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_patch_sudo.py:153 · Privileged sudo command — agent may execute with elevated privileges# ── remote_read(use_sudo=True) uses sudo cat with a valid hash ───────────────Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_patch_sudo.py:95 · Privileged sudo command — agent may execute with elevated privileges# connection_manager — patch both so every sudo hop hits the fake pool.Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
Privileged sudo commandtests/test_sudo_auth.py:139 · Privileged sudo command — agent may execute with elevated privileges# Live agent round trip (1b): `portal sudo set` client → per-user agent cacheFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.
AST05
MEDIUM
File type combined with upload actiontests/test_transfer_sync_mirror.py:319 · File type combined with upload action — agent may exfiltrate local data filesassert "/remote/dir/a.txt" in sftp.put_callsFix: Remove the call, or declare the host in frontmatter and explain in the README what is sent and why.
AST07

Cost to the agent

Instructions loaded
≈75 tok
1 file · 81 in bundle
Tool list per prompt
≈0 tok
0 tools · 0 per tool
Handshake
no reply
launch to tools/list, stdio
Undocumented tools
0
description under 20 chars · avg 0

Tokens estimated at four characters each. The tool list is re-read by the agent on every turn, so it is the number to compare between servers that do the same job: ranked across the index.

Known vulnerabilities

No advisories in OSV for portal-mcp-server@4.0.3 as of 4 min ago. This is the package itself, not its dependencies.

What would make this Verified

18 points to 80 · weights: behavior 45%, static 25%, prompt 15%, publisher 15%
  1. Prompting user to enter sensitive credentials≈ +9 on the totalStop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
  2. Reads credential paths from the home directory≈ +9 on the totalStop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
  3. Destructive command against a filesystem root or device≈ +9 on the totalBuild commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.
  4. Unclaimed publisher≈ +8 on the totalClaim tmytimidly: a verified publisher gets +50 on publisher trust. It is free and usually instant with GitHub sign-in.
  5. Hidden instructions≈ +6 on the totalRemove HTML comments, zero-width characters and white-on-white text that carry instructions. Everything the agent is meant to read should be visible to the person reading the file.
  6. Privileged sudo command≈ +4 on the totalBuild commands from fixed arguments; do not interpolate untrusted strings into a shell.
Publish a new version to PyPI, then queue it here. Not your skill? Claim the handle to get verdict changes by email.Claim tmytimidlyPropose a patch to the maintainer