Back to skill

Security audit

Agent Comm Hub

Security checks across malware telemetry and agentic risk

Overview

This is a coherent local multi-agent hub, but several runtime paths expose agent messages, tasks, or automation triggers without enough identity scoping or user review.

Install only in an environment where you trust the hub operator and participating agents. Bind it to localhost or a protected network, require Bearer auth on SSE and REST endpoints, enforce agent_id == authenticated identity for message/task APIs, avoid automatic task execution without a policy gate, do not point HUB_URL at untrusted servers, and do not run the test or DB-repair scripts against a real database without a backup.

SkillSpector

By NVIDIA
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (85)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
"""发送 macOS 系统通知"""
    try:
        script = f'display notification "{message}" with title "{title}" sound name "Glass"'
        subprocess.run(
            ["osascript", "-e", script],
            timeout=5,
            capture_output=True,
Confidence
96% confidence
Finding
subprocess.run( ["osascript", "-e", script], timeout=5, capture_output=True, )

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Content
def stop_hub():
    """停止 Hub"""
    os.system("lsof -ti:3100 | xargs kill -9 2>/dev/null")
    time.sleep(1.5)

def db_setup_agents(agents_tokens: list):
Confidence
93% confidence
Finding
os.system("lsof -ti:3100 | xargs kill -9 2>/dev/null")

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Content
print("  ✓ DB 写入完成")

        # 启 Hub
        os.system(f"cd {HUB_DIR} && {NPX_BIN} tsx src/server.ts > /tmp/hub-p2d2.log 2>&1 &")
        for _ in range(15):
            time.sleep(1)
            code2, _ = http("GET", "/health")
Confidence
86% confidence
Finding
os.system(f"cd {HUB_DIR} && {NPX_BIN} tsx src/server.ts > /tmp/hub-p2d2.log 2>&1 &")

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def tsx(script: str) -> dict:
    """执行 tsx 脚本,返回 JSON 结果"""
    result = subprocess.run(
        ["npx", "tsx", "-e", script],
        capture_output=True, text=True, cwd=os.path.dirname(os.path.dirname(__file__))
    )
Confidence
95% confidence
Finding
result = subprocess.run( ["npx", "tsx", "-e", script], capture_output=True, text=True, cwd=os.path.dirname(os.path.dirname(__file__)) )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def tsx_eval(code):
    """执行 tsx 代码片段并返回 JSON 结果"""
    cmd = ["npx", "tsx", "-e", code]
    proc = subprocess.run(cmd, capture_output=True, text=True, timeout=15,
                          cwd=os.path.join(os.path.dirname(__file__), ".."))
    if proc.returncode != 0:
        return {"success": False, "error": proc.stderr.strip() or proc.stdout.strip()}
Confidence
94% confidence
Finding
proc = subprocess.run(cmd, capture_output=True, text=True, timeout=15, cwd=os.path.join(os.path.dirname(__file__), ".."))

subprocess module call

Medium
Category
Dangerous Code Execution
Content
with open(tmpfile, 'w') as f:
        f.write(script_content)
    try:
        result = subprocess.run(
            ['npx', 'tsx', tmpfile],
            capture_output=True, text=True, timeout=30, cwd=HUB_ROOT
        )
Confidence
93% confidence
Finding
result = subprocess.run( ['npx', 'tsx', tmpfile], capture_output=True, text=True, timeout=30, cwd=HUB_ROOT )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
with open(tmpfile, 'w') as f:
        f.write(script_content)
    try:
        result = subprocess.run(
            ['npx', 'tsx', tmpfile],
            capture_output=True, text=True, timeout=30, cwd=HUB_ROOT
        )
Confidence
87% confidence
Finding
result = subprocess.run( ['npx', 'tsx', tmpfile], capture_output=True, text=True, timeout=30, cwd=HUB_ROOT )

subprocess module call

Medium
Category
Dangerous Code Execution
Content
with open(tmpfile, 'w') as f:
        f.write(script_content)
    try:
        result = subprocess.run(
            ['npx', 'tsx', tmpfile],
            capture_output=True, text=True, timeout=30, cwd=HUB_ROOT
        )
Confidence
86% confidence
Finding
result = subprocess.run( ['npx', 'tsx', tmpfile], capture_output=True, text=True, timeout=30, cwd=HUB_ROOT )

Tainted flow: 'req' from os.getenv (line 94, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
method="PATCH",
        )
        req.add_header("Content-Type", "application/json")
        with urlopen(req, timeout=10) as resp:
            return resp.status < 400
    except Exception as e:
        logger.error(f"更新任务状态失败: {e}")
Confidence
83% confidence
Finding
with urlopen(req, timeout=10) as resp:

Tainted flow: 'req' from os.getenv (line 87, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
"""简单的 HTTP GET,用于健康检查和 REST API 调用"""
    try:
        req = Request(url)
        with urlopen(req, timeout=timeout) as resp:
            return resp.read()
    except Exception as e:
        logger.warning(f"HTTP GET {url} 失败: {e}")
Confidence
94% confidence
Finding
with urlopen(req, timeout=timeout) as resp:

Tainted flow: 'req' from os.getenv (line 87, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
body = json.dumps(data).encode("utf-8")
        req = Request(url, data=body, method="PATCH")
        req.add_header("Content-Type", "application/json")
        with urlopen(req, timeout=timeout) as resp:
            return resp.status < 400
    except Exception as e:
        logger.error(f"HTTP PATCH {url} 失败: {e}")
Confidence
94% confidence
Finding
with urlopen(req, timeout=timeout) as resp:

Tainted flow: 'req' from os.getenv (line 87, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Content
try:
                logger.info(f"连接 SSE: {self.url}")
                req = Request(self.url)
                with urlopen(req, timeout=self.timeout) as resp:
                    logger.info("SSE 连接成功,开始监听...")
                    self._read_stream(resp)
Confidence
97% confidence
Finding
with urlopen(req, timeout=self.timeout) as resp:

Lp3

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding
The skill advertises and references substantial capabilities including environment-variable access, filesystem interaction, network services, and likely command execution, yet it declares no explicit permissions. That creates a dangerous trust gap: a caller or hosting platform may invoke or approve the skill without understanding that it can read secrets, manipulate local data, or expose services over stdio/HTTP-SSE.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The documented purpose presents the skill primarily as a communication hub, but the file also describes significantly broader powers: token/auth management, RBAC/admin functions, file transfer, monitoring endpoints, data maintenance, backup/repair operations, and local automation hooks. This mismatch is dangerous because reviewers or users may grant access expecting messaging features while actually enabling administrative, persistence, and local-system capabilities with materially higher security impact.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
This test intentionally drops the trigger that enforces audit log immutability and then deletes audit records, which normalizes and exercises a capability to tamper with security evidence. Even though it appears to be test code, embedding direct audit-bypass logic in the skill repository is dangerous because it can be copied into production paths, run against a real database, or weaken assumptions about forensic integrity.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
This script directly spawns and force-kills local processes as part of its normal flow, which is hazardous operationally even if intended for testing. Because the skill is a local communication hub exposing many tools and a web panel, unsafe lifecycle control increases the chance of disrupting real local services or corrupting active state when run in the wrong environment.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
The test directly inserts agents and bearer-token hashes into the production-style SQLite database, bypassing normal registration and authorization flows. In a local multi-agent communication hub, this is security-relevant because anyone able to run the test or reuse its logic can mint valid credentials and exercise privileged API/MCP paths without audit-consistent onboarding.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The test deliberately opens the hub's SQLite database and inserts an admin API token directly into the auth_tokens table, bypassing the application's normal authentication and authorization flow. Even though this appears intended for testing, it normalizes and documents a privilege-escalation path that would grant full administrative access to anyone with filesystem access to the database, which is especially dangerous in a local multi-agent hub exposing many tools and a web panel.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The test deliberately writes an admin agent, admin API token, and invite codes directly into the SQLite database, bypassing the normal authentication and provisioning controls. Even though this appears intended for test setup, it creates a dangerous pattern: if run against a shared, real, or insufficiently isolated environment, it can mint privileged credentials and permanently weaken trust boundaries.

Context-Inappropriate Capability

Medium
Confidence
97% confidence
Finding
The test code directly inserts hashed admin and member API tokens into the live SQLite database, bypassing the hub's intended authentication and provisioning flows. Even if intended for testing, this normalizes privileged backdoor creation and can grant unauthorized access if pointed at a real or reused database.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The script performs unconditional DELETE operations on strategy-related tables in the hub database before running tests. In a local agent hub with shared memory/orchestration state, this can destroy operational data or corrupt concurrent runs if the test is executed against the wrong database file.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The test directly inserts authentication tokens into the SQLite database, bypassing the hub’s normal authentication, issuance, and authorization paths. Even in test code, this is a privileged backdoor capability: if run against a non-isolated environment or copied into operational workflows, it can create arbitrary admin/member access and invalidate security assurances.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The test deliberately drops audit-log immutability triggers and deletes audit records, which normalizes and demonstrates a workflow for tampering with forensic data. In a communication hub that relies on auditability and trust scoring, the ability to remove or rewrite audit history can hide malicious actions, invalidate trust calculations, and defeat incident investigation.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The test setup deliberately drops audit-log immutability triggers and deletes audit records to prepare state. Even though this is in a test, it normalizes and automates a mechanism for tampering with security evidence; if pointed at a non-test database or reused in the wrong environment, it directly defeats audit integrity guarantees.

Intent-Code Divergence

Low
Confidence
88% confidence
Finding
The code comments acknowledge trigger-validation limitations, but the implementation repeatedly bypasses immutability protections by dropping triggers to manipulate `audit_log`. This weakens confidence in the security control and creates a reusable pattern for disabling protections rather than validating them safely.

VirusTotal

VirusTotal findings are pending for this skill version.

View on VirusTotal

Static analysis

Detected: suspicious.dangerous_exec, suspicious.dynamic_code_execution

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
tests/integration/stdio-node-version.test.ts:272

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
tests/unit/audit-worm.test.ts:156

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
tests/test-phase2-day5.py:362

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
tests/test-phase2-gogo.py:280