Back to skill

Security audit

ROS

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent and not deceptive, but it gives an agent broad control over real robots with limited built-in safeguards, so it needs review before installation.

Install only for trusted ROS environments. Treat mutating commands as capable of moving real hardware or changing live system state, require operator approval before movement/actions/service calls/parameter writes, prefer simulation first, keep an emergency stop available, and avoid exposing rosbridge or this CLI over untrusted networks unless transport security and access controls are added.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/ros_cli.py:168
Finding

Robot control traffic uses plaintext WebSocket transport without client-side authentication

Content
View full analysis

Vulnerability Details

File Location: scripts/ros_cli.py, lines 168-175
Vulnerability Type: Plaintext, unauthenticated control channel
Risk Level: High
Category: T09: Insecure Skill Coding Practices

Vulnerable Code

python
def ws_connect(ip, port, timeout=5.0):
    """Create a WebSocket connection to rosbridge."""
    try:
        url = f"ws://{ip}:{port}"
        ws = websocket.create_connection(url, timeout=timeout)
        return ws, None
    except Exception as e:
        return None, str(e)

The client always constructs a ws:// URL. It provides no option for TLS, server certificate validation, authentication credentials, or integrity protection at the application layer.

The transmitted operations include topic publication, arbitrary ROS service calls, parameter modification, and action goals. These operations can control physical movement or modify robot state. Sensor responses may also include camera images, LiDAR scans, odometry, joint states, or other operationally sensitive data.

Technical Analysis

Plain WebSocket traffic provides neither confidentiality nor transport integrity. An attacker able to observe or modify traffic between this CLI and rosbridge can inspect ROS messages, alter outgoing control operations, inject protocol frames, forge responses, or terminate the connection.

Because the client does not authenticate the rosbridge endpoint, it also cannot establish that it has connected to the intended robot. Network redirection, DNS manipulation when a hostname is used, ARP spoofing, a malicious access point, or routing compromise could direct the connection to an attacker-controlled WebSocket server.

The implementation also offers no authentication mechanism for the ROS control session. Whether an independently connecting remote attacker can reach rosbridge depends on external network controls and rosbridge deployment settings, but this client does not enforce ...[truncated 1686 chars]

Remediation
View remediation

Remediation Suggestions

  1. Add explicit support for wss:// and make encrypted transport the default for non-loopback destinations.
  2. Validate the server certificate against a trusted CA and reject invalid, expired, or hostname-mismatched certificates.
  3. Support certificate or public-key pinning for safety-critical robot deployments.
  4. Add an authentication mechanism appropriate to the rosbridge deployment, such as mutually authenticated TLS, a secured reverse proxy, or rosbridge authentication.
  5. Refuse plaintext remote connections by default. If plaintext is retained for local development, require an explicit flag such as --allow-insecure-ws.
  6. Restrict rosbridge at the network layer using host firewalls, VPNs, private interfaces, and allowlisted management hosts.
  7. Apply rosbridge or ROS-side authorization policies that allow only required topics and services instead of exposing the entire ROS graph.
  8. Separate read-only monitoring from state-changing operations and require explicit confirmation for movement, service calls, parameter changes, and actions.
  9. Document that rosbridge must not be exposed directly to untrusted networks and provide a secure deployment example.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:24
Finding

Runtime dependency is installed without a version or integrity constraint

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 24-28
Vulnerability Type: Unpinned third-party package installation
Risk Level: Medium
Category: T08: Insecure Dependencies

Vulnerable Code

markdown
### 1. Install dependency

```bash
pip install websocket-client
text

The same unversioned dependency is also declared in the skill metadata and repeated in `README.md` and `examples/turtlesim.md`. The project contains no lock file, hash-verified requirements file, or other integrity constraint for the installed package.

### Technical Analysis

`pip install websocket-client` resolves the package version at installation time. Consequently, the reviewed source does not determine the exact dependency code that will execute. A future release, compromised package release, compromised package index, or maliciously configured package source could change installation behavior without any modification to this project.

This is not evidence that the named package is currently malicious or typosquatted. The issue is the lack of reproducibility and integrity verification for code imported and executed by `scripts/ros_cli.py`.

Python imports the package at module startup:

```python
try:
    import websocket
except ImportError:
    print(json.dumps({"error": "websocket-client not installed. Run: pip install websocket-client"}))
    sys.exit(1)

Any malicious code in the installed distribution could therefore execute with the privileges of the user running the CLI before a ROS command is processed.

Attack Path

  1. An operator, agent platform, or deployment workflow follows the documented pip install websocket-client command.
  2. Pip resolves the dependency from the configured package index without a project-enforced version or artifact hash.
  3. A compromised upstream release, malicious index mirror, dependency-resolution manipulation, or future vulnerable version is selected.

...[truncated 1128 chars]

Remediation
View remediation

Remediation Suggestions

  1. Define a reviewed dependency version or tightly bounded compatible range in a dedicated requirements or lock file.
  2. Use hash verification, for example a requirements file containing exact versions and SHA-256 hashes installed with pip install --require-hashes.
  3. Generate and commit a reproducible lock file using a dependency-management tool suitable for the project.
  4. Configure automated vulnerability and release monitoring for the pinned dependency.
  5. Update SKILL.md, README.md, examples, and skill metadata so all installation paths use the same constrained dependency definition.
  6. Install dependencies into an isolated virtual environment under a non-privileged account.
  7. Use a trusted internal package mirror or explicitly approved package index in controlled deployments.
  8. Review and deliberately update dependency pins rather than allowing installation-time selection of arbitrary future releases.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (13)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README provides a concrete example for publishing to /cmd_vel to move a robot but gives no safety warning, precondition checks, or guidance about operating in a safe environment. In a robot-control skill, omission of physical safety guidance materially increases the chance that an agent or user will issue motion commands that can cause collisions, injury, or equipment damage.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill exposes shell-based capabilities that can install packages, launch services, and send operational commands to a robot, but it declares no permissions or allowed-tools scope. That omission removes an important policy boundary, making it easier for an agent to invoke powerful commands without explicit review or least-privilege constraints.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 49)May include surrounding context.

ROS 1:

bash
sudo apt install ros-${ROS_DISTRO}-rosbridge-server
roslaunch rosbridge_server rosbridge_websocket.launch

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 34)May include surrounding context.

ROS 1:

bash
sudo apt install ros-${ROS_DISTRO}-rosbridge-server
roslaunch rosbridge_server rosbridge_websocket.launch

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 40)May include surrounding context.

ROS 1:

bash
sudo apt install ros-${ROS_DISTRO}-rosbridge-server
roslaunch rosbridge_server rosbridge_websocket.launch

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The documentation explicitly provides ready-to-run robot motion commands (/cmd_vel, repeated publish, motion sequences) without any safety warning, gating guidance, or requirement to verify simulation/test mode first. In a ROS robot-control skill, omission of physical-world movement cautions materially increases the chance of unsafe real-world actuation, collisions, or injury when an agent or user copies these commands to a live robot.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The documentation includes state-changing service calls, parameter writes, and action execution against a live ROS system without warning that they mutate robot/system state. In this skill context, these commands can reset nodes, alter configuration, trigger behaviors, or otherwise change operational state, which can disrupt services or contribute to unsafe robot behavior if run on production hardware.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This CLI exposes robot-control capabilities such as publishing movement commands, calling services, sending actions, and changing parameters without any safety interlock, confirmation, or explicit warning at execution time. In the context of a ROS robot, these operations can directly affect physical behavior or safety-critical configuration, making misuse or accidental invocation potentially harmful in the real world.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/ros_cli.py (reported line 240)May include surrounding context.

python
param = "-n" if platform.system().lower() == "windows" else "-c"
    timeout_param = "-w" if platform.system().lower() == "windows" else "-W"
    try:
        result = subprocess.run(
            ["ping", param, "1", timeout_param, str(int(timeout)), ip],
            capture_output=True, text=True, timeout=timeout + 2
        )

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · tests/test_ros_cli.py (reported line 281)May include surrounding context.

python
mock_ws = MagicMock()
        import websocket as ws_mod
        mock_ws.recv.side_effect = ws_mod.WebSocketTimeoutException()
        result = ros_cli.ws_subscribe_once(mock_ws, "/slow", "std_msgs/String", timeout=0.5)
        self.assertIn("error", result)
        self.assertIn("Timeout", result["error"])

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The README shows how to subscribe to sensor data over rosbridge without warning that sensor streams may expose sensitive environmental, operational, or telemetry data. In this context, an agent skill designed for ROS interaction could be used to access camera, lidar, localization, or diagnostic topics, creating privacy and system exposure risks if operators are not warned about scope and authorization.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The tool sends command payloads, topic subscriptions, service requests, parameter values, and action goals to a rosbridge endpoint over the network. Although networking is part of the tool's purpose, there is no visible warning that supplied data will be transmitted to the target robot or host, which is relevant for users handling sensitive telemetry or configuration data.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill's stated purpose is controlling and querying ROS/ROS2 robots via rosbridge WebSocket. While opening sockets and WebSocket connections is directly justified, spawning the system 'ping' command is a separate host-level capability that is not necessary to perform ROS interactions and expands execution privileges beyond the manifest's described interface.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.