Back to skill

Security audit

Ohif Deploy

Security checks for vulnerabilities and agentic risk

Overview

This skill is a Docker deployment helper, but it hardcodes an external medical-imaging data endpoint while presenting the setup as customizable.

Review this skill before installing or using it. Do not deploy it with real patient or regulated medical data unless you have verified and intentionally accepted the allhealthai.com endpoints, replaced them with approved DICOMweb servers, pinned reviewed container images, and validated generated Docker Compose and JSON files before starting containers.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
deploy.sh:6
Finding

Unvalidated Arguments Permit Docker Compose and JSON Configuration Injection

Content
View full analysis
docker-compose.yml << EOF version: '3.8' services: ohif: image: ohif/viewer:latest ports: - "${PORT}:3000" environment: - APP_CONFIG=/usr/local/share/ohif/static/hosting.json volumes: - ./config:/usr/local/share/ohif/static restart: unless-stopped nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - ohif restart: unless-stopped EOF mkdir -p config cat > config/hosting.json << EOF { "defaultDataSourceName": "${DATA_SOURCE}", "dataSources": [ { "namespace": "@ohif/extension-default.dataSourcesModule.dicomweb", "sourceName": "${DATA_SOURCE}", "configuration": { "wadoUriRoot": "https://www.allhealthai.com/HealthRecordCenter", "qidoRoot": "https://www.allhealthai.com/HealthRecordCenter", "wadoRoot": "https://scnc.allhealthai.com:16010/HealthRecordCenter", "imageRendering": "wadors", "thumbnailRendering": "wadors", "enableStudyLazyLoad": true } } ] } EOF ``` ### Technical Analysis The script accepts its port and data-source values directly from positional arguments and inserts them into unquoted heredocs without validation or context-aware encoding. A malicious `PORT` value can contain quotation marks, line breaks, and YAML directives that escape the expected `ports` scalar and modify the generated Compose document. Depending on the injected structure, an attacker could add services, change images, configure privileged execution, expose additional ports, or create sensitive host bind mounts. Similarly, a malicious `DATA_SOURCE` value cont ...[truncated 2265 chars]
Remediation
View remediation
65535 )); then printf 'Invalid port\n' >&2 exit 1 fi ``` 3. Restrict data-source identifiers to a documented allowlist or a conservative identifier pattern, such as letters, digits, underscores, and hyphens. 4. Reject control characters, newlines, carriage returns, quotation marks, and other syntax-breaking characters where they are not explicitly supported. 5. Generate JSON with a serializer such as `jq --arg`, rather than interpolating values into JSON text. 6. Generate Compose YAML with a YAML-aware library or start from a static template and update only validated scalar fields. 7. Validate generated files before use, for example with `docker compose config --quiet` and `jq -e . config/hosting.json`. 8. Do not automatically start or recommend starting generated infrastructure unless configuration validation succeeds. ]]>

T08 · Insecure Dependencies

Warning
Location
deploy.sh:13
Finding

Mutable Container Image Tags Allow Unreviewed Dependency Replacement

Content
View full analysis
docker-compose.yml << EOF version: '3.8' services: ohif: image: ohif/viewer:latest ports: - "${PORT}:3000" environment: - APP_CONFIG=/usr/local/share/ohif/static/hosting.json volumes: - ./config:/usr/local/share/ohif/static restart: unless-stopped nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - ohif restart: unless-stopped EOF ``` ### Technical Analysis The generated Compose file references `ohif/viewer:latest` and `nginx:alpine`. Both are mutable tags rather than immutable image digests. The same audited project can therefore deploy different container contents at different times without any change to the repository. The `latest` tag is especially broad and may move across application versions. The `alpine` tag also floats as nginx and Alpine releases change. Tag replacement, registry compromise, compromised publisher credentials, or an unsafe upstream release could cause the deployment to retrieve and run code that was never reviewed as part of this Skill. ### Attack Path 1. The upstream publisher updates one of the referenced mutable tags, or an attacker compromises the image repository or publishing credentials. 2. The tag is changed to point to a malicious or vulnerable image manifest. 3. An operator generates the Compose file and runs `docker-compose up -d`, or later pulls the tag again. 4. Docker retrieves the changed image from the registry. 5. The unreviewed image executes in the deployment with its configured filesystem, network, and restart access. ### Impact Assessment A compromised OHIF image could access the writable configuration mount, application traffic, DICOM-related requests, an ...[truncated 621 chars]
Remediation
View remediation
image: nginx@sha256: ``` 2. Prefer a specific reviewed application version in addition to recording its digest for maintainability. 3. Establish a controlled dependency-update process that verifies image provenance, release notes, vulnerability scan results, and compatibility before changing digests. 4. Enable registry signature or provenance verification where supported, such as Sigstore/Cosign policies. 5. Scan images in CI and fail deployment for prohibited critical vulnerabilities. 6. Run containers as non-root where supported, use read-only filesystems and mounts where practical, drop unnecessary capabilities, and enforce resource and network restrictions to reduce the impact of dependency compromise. ]]>

other

Warning
Location
deploy.sh:40
Finding

Hardcoded External DICOMweb Endpoints Create an Undisclosed Medical-Data Trust Boundary

Content
View full analysis
config/hosting.json << EOF { "defaultDataSourceName": "${DATA_SOURCE}", "dataSources": [ { "namespace": "@ohif/extension-default.dataSourcesModule.dicomweb", "sourceName": "${DATA_SOURCE}", "configuration": { "wadoUriRoot": "https://www.allhealthai.com/HealthRecordCenter", "qidoRoot": "https://www.allhealthai.com/HealthRecordCenter", "wadoRoot": "https://scnc.allhealthai.com:16010/HealthRecordCenter", "imageRendering": "wadors", "thumbnailRendering": "wadors", "enableStudyLazyLoad": true } } ] } EOF ``` ### Technical Analysis The generated viewer configuration always directs DICOMweb functionality to hosts under `allhealthai.com`. The user-supplied `DATA_SOURCE` argument changes only `defaultDataSourceName` and `sourceName`; it does not change any endpoint. This behavior conflicts with the documentation's claims of custom DICOM server integration and support for multiple named server types. An operator selecting a label such as `orthanc` could reasonably believe that an Orthanc source was configured, while requests would still target the hardcoded third-party endpoints. Because DICOMweb requests can contain study, series, instance, patient-related, or access metadata, silently choosing an external endpoint creates a significant privacy and trust-boundary concern. The audited code does not prove intentional exfiltration or credential theft, but the destination and resulting data flow are not clearly disclosed or explicitly selected during deployment. ### Attack Path 1. An operator runs the deployment script, potentially supplying a data-source name described in `SKILL.md`. 2. The script generates `hosting.json` with the selected label but retains all three hardcoded `allhealth ...[truncated 1325 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (1)

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

This code creates or overwrites docker-compose.yml and config/hosting.json in the working directory using shell redirection. While the script prints deployment status, it does not explicitly disclose that local files will be created or replaced, and there is no confirmation prompt or cautionary comment about these filesystem changes.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.