Back to skill

Security audit

Bohrium Image Management

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches Bohrium image management, but it includes an unverified remote installer and account-changing image operations that need closer review before use.

Install only if you trust Bohrium and the CLI installer source. Prefer downloading and verifying the installer before running it, use a scoped ACCESS_KEY, inspect Dockerfiles for secrets before any build or validation upload, and require explicit confirmation before deleting, sharing, unsharing, or building images.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Findings (1)

T03 · Remote Payload Retrieval and Execution

Error
Location
SKILL.md:24
Finding

Unverified Remote Installer Download and Execution

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 24–27
Vulnerability Type: Remote payload retrieval and execution
Risk Level: Critical

Complete Code Snippet:

bash
# macOS
/bin/bash -c "$(curl -fsSL https://dp-public.oss-cn-beijing.aliyuncs.com/bohrctl/1.0.0/install_bohr_mac_curl.sh)"
# Linux
/bin/bash -c "$(curl -fsSL https://dp-public.oss-cn-beijing.aliyuncs.com/bohrctl/1.0.0/install_bohr_linux_curl.sh)"

Technical Analysis

These prerequisite commands retrieve shell scripts from an external object-storage host and pass their contents directly to Bash. The downloaded payload is not present in the audited package, and the commands do not verify a cryptographic signature or pinned checksum before execution. Consequently, the code that ultimately runs can differ from the code reviewed during this audit.

Although installing the Bohrium CLI supports the declared image-management functionality, immediate execution of unverified network content exceeds the minimum privilege and trust necessary to perform that installation. Separating download, integrity verification, inspection, and execution would materially reduce the risk.

Exploitation would require an attacker to control or alter the content delivered by the referenced host, such as through compromise of the storage account or release infrastructure. Compromise of the applicable DNS or TLS trust path could create an equivalent result. The fixed HTTPS destination reduces arbitrary-destination risk but does not establish payload integrity.

Attack Path

  1. An attacker compromises the external object-storage account, hosted installer, publishing pipeline, or an applicable network trust component.
  2. The attacker replaces or modifies one of the referenced installer scripts with malicious shell commands.
  3. A user or agent follows the prerequisite instructions in SKILL.md.
  4. curl retrieves the altered content.
  5. Command substitut ...[truncated 821 chars]
Remediation
View remediation

Remediation Suggestions

  1. Do not execute downloaded content through command substitution or a curl | shell equivalent.
  2. Prefer installation through a trusted package manager whose metadata and artifacts are cryptographically authenticated.
  3. If a standalone installer is necessary:
    • Download it to a non-executable file.
    • Pin an immutable artifact version.
    • Verify a vendor-published cryptographic signature or an independently distributed SHA-256 checksum.
    • Abort on every verification failure.
    • Review the downloaded script before execution.
    • Execute it with the least-privileged account capable of completing the installation.
  4. Host an auditable installer in the reviewed project when practical, while separately verifying any binaries it installs.
  5. Document the files, network destinations, and configuration changes made by the installer.
  6. Avoid requesting administrator or root privileges unless a specific installation step demonstrably requires them.

A safer documented flow should resemble:

bash
curl -fL --proto '=https' --tlsv1.2 \
  -o install_bohr_linux.sh \
  'https://example.invalid/immutable-version/install_bohr_linux.sh'

printf '%s  %s\n' 'PINNED_SHA256_VALUE' 'install_bohr_linux.sh' | sha256sum -c -
less install_bohr_linux.sh
/bin/bash install_bohr_linux.sh

The checksum must be obtained through a trusted channel independent of the downloaded artifact.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (16)

Tainted flow: 'HEADERS' from os.environ.get (line 20, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · search_images.py (reported line 26)May include surrounding context.

python
def search_versions(keyword: str, limit: int = 5):
    """Search public image versions by keyword."""
    r = requests.get(
        f"{BASE_V2}/public/version/search",
        headers=HEADERS,
        params={"keyword": keyword, "page": 1, "pageSize": limit},

Tainted flow: 'HEADERS' from os.environ.get (line 20, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · search_images.py (reported line 54)May include surrounding context.

python
def browse_public(limit: int = 10):
    """Browse public image categories."""
    r = requests.get(
        f"{BASE_V2}/public",
        headers=HEADERS,
        params={"page": 1, "pageSize": limit},

Tainted flow: 'HEADERS_JSON' from os.environ.get (line 21, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · search_images.py (reported line 78)May include surrounding context.

python
dockerfile_content = f.read()

    # Validate Dockerfile first
    check = requests.post(
        f"{BASE_V2}/dockerfile/check",
        headers=HEADERS_JSON,
        json={"dockerfile": dockerfile_content},

Tainted flow: 'HEADERS_JSON' from os.environ.get (line 21, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · search_images.py (reported line 91)May include surrounding context.

python
print("Dockerfile validation passed.")

    # Build
    r = requests.post(
        f"{BASE_V2}/private",
        headers=HEADERS_JSON,
        json={

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill metadata and introductory description frame the module primarily as search/browse functionality, but the file also supports creating private images from a local Dockerfile. In an agent setting, this capability mismatch can cause the tool to be invoked with less scrutiny than a write-capable, file-uploading operation deserves, increasing the risk of unintended remote actions and disclosure of local content.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill documents code paths that use environment variables and make outbound network/API requests, but it declares no explicit tool scope or permission boundaries. In an agent setting, this can lead to overbroad execution where the model may access secrets from the environment and transmit them externally without clear policy gating.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill provides destructive deletion commands for custom images without any warning, dry-run guidance, or requirement to confirm target IDs with the user. In an agent workflow, this increases the risk of accidental or unauthorized destructive operations causing loss of custom images or disrupting projects.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

This duplicate finding is also valid: the build endpoint transmits base64-encoded Dockerfile content and uses an access key header. Base64 is not protection, so any secrets or sensitive internal build details in the Dockerfile are effectively sent in clear application data to an external service.

Content

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

md
dockerfile_content = "FROM ubuntu:22.04\nRUN apt-get update && apt-get install -y python3"
dockerfile_b64 = base64.b64encode(dockerfile_content.encode()).decode()

r = requests.post("https://open.bohrium.com/openapi/v2/image/private",
    headers=HEADERS_JSON, json={
        "name": "my-image", "projectId": 154, "device": "container",
        "desc": "Custom training image", "buildType": 1,

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

This duplicate finding is also valid: the build endpoint transmits base64-encoded Dockerfile content and uses an access key header. Base64 is not protection, so any secrets or sensitive internal build details in the Dockerfile are effectively sent in clear application data to an external service.

Content

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

md
dockerfile_content = "FROM ubuntu:22.04\nRUN apt-get update && apt-get install -y python3"
dockerfile_b64 = base64.b64encode(dockerfile_content.encode()).decode()

r = requests.post("https://open.bohrium.com/openapi/v2/image/private",
    headers=HEADERS_JSON, json={
        "name": "my-image", "projectId": 154, "device": "container",
        "desc": "Custom training image", "buildType": 1,

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

This duplicate validation-call finding is valid for the same reason: content is externally transmitted to a third-party API and may include sensitive build commands or references. The impact is somewhat lower than image creation because it is a validation endpoint, but the confidentiality exposure remains.

Content

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

Validate Dockerfile (also requires base64)

check_b64 = base64.b64encode(b"FROM ubuntu:22.04\nRUN apt-get update").decode() requests.post("https://open.bohrium.com/openapi/v2/image/dockerfile/check", headers=HEADERS_JSON, json={"dockerfile": check_b64})

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

This duplicate validation-call finding is valid for the same reason: content is externally transmitted to a third-party API and may include sensitive build commands or references. The impact is somewhat lower than image creation because it is a validation endpoint, but the confidentiality exposure remains.

Content

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

Validate Dockerfile (also requires base64)

check_b64 = base64.b64encode(b"FROM ubuntu:22.04\nRUN apt-get update").decode() requests.post("https://open.bohrium.com/openapi/v2/image/dockerfile/check", headers=HEADERS_JSON, json={"dockerfile": check_b64})

text

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The top-level documentation emphasizes searching and browsing public images while also exposing build functionality that uploads local Dockerfile contents and triggers a state-changing operation. This contradiction is dangerous in an automated or semi-automated environment because users and orchestrators may underestimate the tool's side effects and data egress.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function reads an arbitrary local Dockerfile and sends its full contents to a remote API for validation without an explicit warning at the point of use. In an agent skill context, this matters because local Dockerfiles can embed sensitive repository URLs, internal base image names, build arguments, or comments that the user may not realize are being transmitted off-host.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

This line performs external transmission of local file content to a third-party service, which is a genuine security-relevant behavior even if intended. In the context of an agent skill, such transmission is more dangerous because users may expect local analysis, while the code actually uploads the Dockerfile to a remote validator.

Content

Scanner excerpt · search_images.py (reported line 78)May include surrounding context.

python
dockerfile_content = f.read()

    # Validate Dockerfile first
    check = requests.post(
        f"{BASE_V2}/dockerfile/check",
        headers=HEADERS_JSON,
        json={"dockerfile": dockerfile_content},

External Transmission

Medium
Category
Data Exfiltration
Confidence
94% confidence
Finding

This request transmits the Dockerfile contents again, this time to initiate a remote private-image build, creating both data egress and a state-changing remote action. In this skill context, that is materially more sensitive than a read-only query because it can disclose local build logic and consume remote resources under the user's account.

Content

Scanner excerpt · search_images.py (reported line 91)May include surrounding context.

python
print("Dockerfile validation passed.")

    # Build
    r = requests.post(
        f"{BASE_V2}/private",
        headers=HEADERS_JSON,
        json={

Static analysis

No suspicious patterns detected.