Back to skill

Security audit

Aionis

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent memory-service purpose, but its automatic bootstrap can run persistent Docker code and handle local credentials with weak safeguards.

Install only if you trust the Aionis container source and are comfortable with a persistent local Docker service. Before use, prefer digest-pinned images, review or disable automatic bootstrap, protect `.runtime` credential files with restrictive permissions, avoid sourcing untrusted env files, and stop/remove the container and volume when no longer needed.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
bootstrap-local-standalone.sh:114
Finding
Arbitrary Shell Execution Through a Sourced Runtime Environment File<![CDATA[ ## Vulnerability Details **File Location**: `bootstrap-local-standalone.sh`, lines 4–6 and 114–119 **Vulnerability Type**: Unsafe sourcing of externally controllable configuration **Risk Level**: High ### Vulnerable Code ```bash RUNTIME_DIR="${AIONIS_RUNTIME_DIR:-${SKILL_DIR}/.runtime}" ENV_FILE="${RUNTIME_DIR}/aionis.env" CLAWBOT_ENV_FILE="${RUNTIME_DIR}/clawbot.env" ``` ```bash if [[ -f "$ENV_FILE" ]]; then # shellcheck disable=SC1090 source "$ENV_FILE" memory_api_key="$(extract_api_key "${MEMORY_API_KEYS_JSON:-}")" admin_token="${ADMIN_TOKEN:-}" fi ``` ### Technical Analysis The script treats `aionis.env` as executable shell code by loading it with `source`. A shell environment file is not merely parsed as key-value data: command substitutions, function definitions, redirections, and arbitrary shell commands inside the file are executed with the privileges of the user running the bootstrap script. The file location is also influenced by the caller-controlled `AIONIS_RUNTIME_DIR` environment variable. Consequently, an attacker who can control this variable, pre-create the default `.runtime/aionis.env`, or modify a runtime directory shared with another user can cause the bootstrap operation to execute attacker-supplied commands. The script does not verify the file's owner, permissions, canonical path, or content before sourcing it. ### Attack Path 1. The attacker creates an `aionis.env` file containing a shell payload, for example a command that copies credentials or installs additional software. 2. The attacker places it in the default `.runtime` directory or causes the victim to invoke the script with `AIONIS_RUNTIME_DIR` pointing to the attacker's directory. 3. The victim runs the documented command: ```bash bash ./bootstrap-local-standalone.sh ``` 4. The script reaches `source "$ENV_FILE"`. 5. Bash executes the attacker's commands with the victim's current privileges before the Docker container is started. ### Impact A ...[truncated 473 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not use `source` to read runtime configuration. - Parse only explicitly permitted keys, such as `MEMORY_API_KEYS_JSON` and `ADMIN_TOKEN`, using a non-executing parser. - Reject malformed lines, command substitutions, shell metacharacters, duplicate keys, and unexpected variables. - Resolve and validate the canonical runtime path before accessing it. - Require the runtime directory and configuration file to be owned by the invoking user and not writable by groups or other users. - If existing credentials must be retained, store them in a dedicated secret file with a narrowly defined format rather than an executable shell file. - Add automated tests proving that values such as `$(touch /tmp/pwned)` are treated as inert text and never executed. ]]>

T06 · System Persistence

Warning
Location
bootstrap-local-standalone.sh:139
Finding
Cross-Session Container Persistence Enabled by Default<![CDATA[ ## Vulnerability Details **File Location**: `bootstrap-local-standalone.sh`, lines 139–146 **Vulnerability Type**: Persistent background service installation **Risk Level**: Medium ### Vulnerable Code ```bash docker run -d \ --name "$AIONIS_CONTAINER_NAME" \ --restart unless-stopped \ -p "127.0.0.1:${AIONIS_PORT}:3001" \ --env-file "$ENV_FILE" \ -v "${AIONIS_VOLUME}:/var/lib/postgresql/data" \ "$AIONIS_IMAGE" >/dev/null ``` The same persistent configuration is presented in `README.md`, lines 24–28: ```bash docker run -d --name aionis-standalone-local --restart unless-stopped \ -p 127.0.0.1:3001:3001 \ --env-file ./.runtime/aionis.env \ -v aionis-standalone-data:/var/lib/postgresql/data \ ghcr.io/cognary/aionis:standalone-v0.2.5 ``` ### Technical Analysis The bootstrap installs a detached Docker container with the `unless-stopped` restart policy. This directs Docker to restart the workload following Docker daemon or host restarts unless an operator explicitly stops it. The container also uses a named volume, preserving application data independently of the current shell session and container lifecycle. Although persistence can be operationally useful for a local service, enabling it automatically during a one-command skill bootstrap creates cross-session execution without a separate opt-in step. This persistence increases the impact of any compromised or substituted container image because its code can regain execution after system restarts. ### Attack Path 1. A user follows the skill documentation and runs the bootstrap script. 2. The script creates a detached container with `--restart unless-stopped`. 3. The initiating shell or agent session ends, but the container continues running. 4. When Docker or the host restarts, Docker automatically launches the container again. 5. If the image is compromised or later abused, its code retains cross-session execution until the operator explicitly stops and removes it. ### Impact A ...[truncated 509 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Default to `--restart no` for skill-initiated local development containers. - Require explicit, informed user opt-in before enabling a persistent restart policy. - Clearly state that the service survives the invoking session and may restart with Docker. - Provide a complete removal command that stops and removes the container and optionally deletes the named volume and generated credential files. - Consider launching a foreground or explicitly temporary container for agent-scoped operations. - If persistence is required, expose it through a clearly named option such as `--enable-persistence` rather than enabling it implicitly. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
bootstrap-local-standalone.sh:129
Finding
Remote Container Image Is Pulled and Executed Without Integrity Verification<![CDATA[ ## Vulnerability Details **File Location**: `bootstrap-local-standalone.sh`, lines 9 and 129–146 **Vulnerability Type**: Unverified remote payload retrieval and execution **Risk Level**: High ### Vulnerable Code ```bash AIONIS_IMAGE="${AIONIS_IMAGE:-ghcr.io/cognary/aionis:standalone-v0.2.5}" ``` ```bash if ! docker image inspect "$AIONIS_IMAGE" >/dev/null 2>&1; then if ! docker pull "$AIONIS_IMAGE" >/dev/null; then echo "failed to pull image: ${AIONIS_IMAGE}" >&2 echo "hint: set AIONIS_IMAGE to an available local image, or run docker login for private registry" >&2 exit 1 fi fi docker rm -f "$AIONIS_CONTAINER_NAME" >/dev/null 2>&1 || true docker run -d \ --name "$AIONIS_CONTAINER_NAME" \ --restart unless-stopped \ -p "127.0.0.1:${AIONIS_PORT}:3001" \ --env-file "$ENV_FILE" \ -v "${AIONIS_VOLUME}:/var/lib/postgresql/data" \ "$AIONIS_IMAGE" >/dev/null ``` ### Technical Analysis The bootstrap fetches a container image from an external registry and immediately executes it. The image is referenced by the mutable tag `standalone-v0.2.5`, not by an immutable content digest. No cryptographic signature, provenance attestation, publisher identity, or expected digest is verified. The `AIONIS_IMAGE` environment variable also permits the caller's environment to replace the expected image with an arbitrary image reference. Therefore, the payload that actually executes can differ from the artifact reviewed in this audit. This creates a supply-chain execution boundary: compromise of the registry account, replacement of the tag, a malicious environment override, or use of an untrusted local image can cause different code to run. ### Attack Path A registry-based exploitation path is: 1. An attacker compromises the publishing account or otherwise causes the mutable tag to reference a malicious image. 2. A user runs the bootstrap on a system where that image is not already present. 3. The script runs `docker pull "$AIONIS_IMAGE"` wi ...[truncated 1137 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Pin the image to an immutable digest, for example `repository@sha256:<verified-digest>`. - Verify an image signature and trusted publisher identity using a mechanism such as Cosign before execution. - Publish provenance or an SBOM and validate it as part of bootstrap. - Do not silently accept arbitrary `AIONIS_IMAGE` overrides. Require a dedicated explicit option and display a warning and confirmation when the verified image is replaced. - Reject tag-only references in production or persistent bootstrap modes. - Avoid running an already-present local image solely because its tag matches; verify that its digest equals the approved digest. - Apply container hardening such as a non-root user, dropped capabilities, `no-new-privileges`, a read-only root filesystem where supported, and resource limits. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
bootstrap-local-standalone.sh:51
Finding
API and Administrative Credentials Are Written Without Enforced Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `bootstrap-local-standalone.sh`, lines 51–94 and 112 **Vulnerability Type**: Insecure plaintext secret-file permissions **Risk Level**: Medium ### Vulnerable Code ```bash write_env_file() { local memory_api_key="$1" local admin_token="$2" { echo "NODE_ENV=production" echo "APP_ENV=prod" echo "AIONIS_MODE=service" echo "PORT=3001" echo "TRUST_PROXY=false" echo echo "MEMORY_AUTH_MODE=api_key" echo "MEMORY_API_KEYS_JSON={\"${memory_api_key}\":{\"tenant_id\":\"default\",\"agent_id\":\"clawbot\",\"team_id\":\"default\"}}" echo "ADMIN_TOKEN=${admin_token}" echo echo "EMBEDDING_PROVIDER=${EMBEDDING_PROVIDER}" echo "EMBEDDING_DIM=1536" if [[ "${EMBEDDING_PROVIDER}" == "minimax" ]]; then echo "MINIMAX_API_KEY=${MINIMAX_API_KEY}" echo "MINIMAX_GROUP_ID=${MINIMAX_GROUP_ID}" echo "MINIMAX_EMBED_MODEL=${MINIMAX_EMBED_MODEL}" echo "MINIMAX_EMBED_TYPE=${MINIMAX_EMBED_TYPE}" echo "MINIMAX_EMBED_ENDPOINT=${MINIMAX_EMBED_ENDPOINT}" fi echo echo "CORS_ALLOW_ORIGINS=" echo "CORS_ADMIN_ALLOW_ORIGINS=" } >"$ENV_FILE" } write_clawbot_env_file() { local memory_api_key="$1" local admin_token="$2" { echo "AIONIS_BASE_URL=http://127.0.0.1:${AIONIS_PORT}" echo "AIONIS_API_KEY=${memory_api_key}" echo "AIONIS_ADMIN_TOKEN=${admin_token}" echo "AIONIS_TENANT_ID=default" echo "AIONIS_SCOPE_PREFIX=clawbot" } >"$CLAWBOT_ENV_FILE" } ``` ```bash mkdir -p "$RUNTIME_DIR" ``` ### Technical Analysis The script stores the generated memory API key and administrative token in plaintext files. When the MiniMax provider is selected, the provider API key is also written to `aionis.env`. Neither the runtime directory nor the files are created with explicit restrictive permissions. The effective permissions depend on the invoking process's ambient `umask` and any pre-existing directory or file modes. With a common `02 ...[truncated 1493 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Set `umask 077` before creating the runtime directory or credential files. - Create the runtime directory with mode `0700`. - Create or replace secret files atomically with mode `0600`, such as through `install -m 600` and a securely created temporary file. - Validate ownership and permissions of pre-existing files before reading or overwriting them. - Refuse to use runtime directories that are group-writable, world-writable, or owned by another user. - Avoid duplicating the administrative token into the agent-facing environment file unless the agent genuinely requires administrative access. - Separate memory-client credentials, administrative credentials, and third-party provider credentials according to least privilege. - Document secure deletion and credential-rotation procedures for generated runtime files. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (9)

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.

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.

External Transmission

Medium
Category
Data Exfiltration
Content
Health check:

```bash
curl -fsS http://127.0.0.1:3001/health
```

Auth check (`x-api-key`):
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Lp3

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding
The skill advertises a memory-loop integration but declares no explicit tool scope while instructing use of shell capabilities later in the document. This creates an authority gap: an agent may invoke shell commands without a narrowly declared permission boundary, increasing the risk of unintended command execution or privilege expansion in environments that trust skill metadata for enforcement or review.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The skill instructs the agent to execute a broad local shell bootstrap command and source an environment file if the service is not running. This goes beyond normal API interaction and can execute arbitrary local code from the workspace, making the skill dangerous in adversarial or untrusted repositories where the script or env file could be modified to run malicious commands or exfiltrate secrets.

External Transmission

Medium
Category
Data Exfiltration
Content
MINIMAX_GROUP_ID="${MINIMAX_GROUP_ID:-}"
MINIMAX_EMBED_MODEL="${MINIMAX_EMBED_MODEL:-embo-01}"
MINIMAX_EMBED_TYPE="${MINIMAX_EMBED_TYPE:-db}"
MINIMAX_EMBED_ENDPOINT="${MINIMAX_EMBED_ENDPOINT:-https://api.minimax.chat/v1/embeddings}"

need() {
  command -v "$1" >/dev/null 2>&1 || {
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The script generates or reuses sensitive credentials and writes them in plaintext to local env files under `.runtime` without setting restrictive permissions or clearly warning the user about persistence. On multi-user systems, in shared workspaces, or if the directory is later committed, these tokens could be exposed and then used to access the local Aionis service with API or admin privileges.

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.

Missing User Warnings

Low
Confidence
84% confidence
Finding
Sourcing an existing env file executes shell syntax from that file, not just variable assignments. Because the file contains secrets and is loaded from a writable runtime directory, a local attacker or accidental modification could inject arbitrary shell commands that run with the user's privileges when the bootstrap script is executed.

Static analysis

No suspicious patterns detected.