Back to skill

Security audit

AIOZ Storage Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but it handles powerful AIOZ account, bucket, grant, and storage credentials in ways that can leak or persist longer than users may expect.

Review before installing. Only use this with an AIOZ account and bucket you control, avoid entering passwords or seed phrases directly in chat or shell history, avoid the /tmp config-file workflow, prefer short-lived least-privilege grants, and rotate any exposed ZKeys, grants, S3 keys, or bucket recovery phrases if you already ran the documented commands in a logged or shared environment.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
SKILL.md:188
Finding

Bucket recovery phrase and root authorization key exposed through command-line arguments

Content
View full analysis
" \ --account "" \ --url w3s \ --duration 0 \ --bucket "" \ --passphrase "<12_WORD_SEED_PHRASE>" \ --permissions 1,2,3 \ --output json \ --quiet ``` ```bash npx ts-node {baseDir}/grant-cli.ts \ --mode per-bucket \ --zkey "" \ --account "" \ --url w3s \ --duration 0 \ --bucket "" \ --passphrase "<12_WORD_SEED_PHRASE>" \ --permissions 1,3 \ --output json \ --quiet ``` The CLI consumes these sensitive values directly from its argument vector: ```typescript const zkey = getArg(args, "zkey"); const account = getArg(args, "account"); const url = getArg(args, "url") || "w3s"; const duration = parseInt(getArg(args, "duration") || "0", 10); if (!mode) throw new Error("--mode is required (per-bucket or all-buckets)"); if (!zkey) throw new Error("--zkey is required"); if (!account) throw new Error("--account is required"); if (mode === "per-bucket") { const bucketNames = args.get("bucket") || []; const passphrases = args.get("passphrase") || []; const permsList = args.get("permissions") || []; const prefixes = args.get("prefix") || []; if (bucketNames.length === 0) { throw new Error("--bucket is required for per-bucket mode"); } if (passphrases.length === 0) { throw new Error("--passphrase is required"); } } ``` ### Technical Analysis The documented deployment process places both the root ZKey and the 12-word bucket recovery phrase in the command-line argument vector. Command-line arguments are not an appropriate secret-transport channel because they may be exposed through: - Shell histo ...[truncated 1742 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:228
Finding

Predictable plaintext temporary files store bucket recovery and authorization secrets

Content
View full analysis
","accountId":"","url":"w3s","duration":0,"buckets":[{"name":"","passphrase":"","permissions":["1","2","3"]}]}' > /tmp/upload-grant-config.json npx ts-node {baseDir}/grant-cli.ts --config /tmp/upload-grant-config.json --output json --quiet echo '{"mode":"per-bucket","rootZKey":"","accountId":"","url":"w3s","duration":0,"buckets":[{"name":"","passphrase":"","permissions":["1","3"]}]}' > /tmp/website-grant-config.json npx ts-node {baseDir}/grant-cli.ts --config /tmp/website-grant-config.json --output json --quiet ``` ### Technical Analysis The alternative configuration workflow writes the root ZKey and bucket recovery phrase to fixed, predictable paths under the shared `/tmp` directory. The commands do not: - Create the files atomically with exclusive-create semantics. - Apply a restrictive `umask` or explicit owner-only permissions. - Check whether the destination is an existing file or symbolic link. - Verify file ownership and type before reading. - Delete the files after grant generation. The resulting files may remain on disk indefinitely. Their effective permissions depend on the invoking environment's `umask`, and the predictable names make them easy to monitor. Existing symbolic links are followed by normal shell redirection, creating an additional unsafe-file-handling condition. ### Attack Path A local information-disclosure attack can proceed as follows: 1. The attacker monitors `/tmp` for `upload-grant-config.json` and `website-grant-config.json`. 2. A legitimate user runs the documented commands. 3. The configuration files are created with plaintext root ZKeys and recovery phrases. 4. If local permission ...[truncated 1328 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
grant-cli.ts:143
Finding

Generated bucket grants have no expiration by default

Content
View full analysis
${to?.toISOString() || "no expiry"}`); ``` The documented upload and website commands explicitly select that behavior: ```bash npx ts-node {baseDir}/grant-cli.ts \ --mode per-bucket \ --zkey "" \ --account "" \ --url w3s \ --duration 0 \ --bucket "" \ --passphrase "<12_WORD_SEED_PHRASE>" \ --permissions 1,2,3 \ --output json \ --quiet ``` ```bash npx ts-node {baseDir}/grant-cli.ts \ --mode per-bucket \ --zkey "" \ --account "" \ --url w3s \ --duration 0 \ --bucket "" \ --passphrase "<12_WORD_SEED_PHRASE>" \ --permissions 1,3 \ --output json \ --quiet ``` ### Technical Analysis Authorization grants should have the shortest lifetime needed for the requested operation. In this implementation, an omitted duration defaults to zero, and zero is interpreted as no expiration. The documented deployment process also explicitly requests zero. The upload grant contains Read, Write, and List permissions. If copied from process output, logs, temporary files, or another co ...[truncated 1669 chars]
Remediation
View remediation
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
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (28)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is presented as a static website deployment helper, but it also orchestrates credentialed login, root key generation, grant creation, and access-control material handling. That mismatch obscures the real security-sensitive behavior, making users and agents less likely to apply appropriate scrutiny before exposing credentials and passphrases.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill performs multiple network operations involving authentication, key generation, credential registration, and cloud deployment, but it declares no explicit tool scope or permission boundaries. That makes the skill harder to govern safely and increases the risk of an agent invoking networked actions involving secrets without clear authorization constraints.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill asks for an email, password, and later a 12-word seed phrase, but gives no warning about entering them into chat, command history, logs, or process lists. These are highly sensitive secrets, and exposure could enable account takeover, bucket access, and unauthorized grant generation.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This command transmits a user's email and password to an external service. While that is functionally expected for login, it is still security-sensitive behavior that becomes dangerous in an agent skill because it encourages collection and forwarding of raw credentials.

Content

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

Ask user for AIOZ Storage email and password.

bash
curl -s 'https://api.aiozstorage.network/api/v1/login' \
  -H 'accept: application/json' \
  -H 'content-type: application/json' \
  -H 'origin: https://aiozstorage.network' \

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This command transmits a user's email and password to an external service. While that is functionally expected for login, it is still security-sensitive behavior that becomes dangerous in an agent skill because it encourages collection and forwarding of raw credentials.

Content

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

Ask user for AIOZ Storage email and password.

bash
curl -s 'https://api.aiozstorage.network/api/v1/login' \
  -H 'accept: application/json' \
  -H 'content-type: application/json' \
  -H 'origin: https://aiozstorage.network' \

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

This step sends an authenticated request to generate or retrieve a root ZKey from an external API. Although part of the workflow, it is security-relevant because it extends external handling of authentication context and key-management material.

Content

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

STEP 5: GET ROOT ZKEY

bash
curl -s 'https://api.aiozstorage.network/api/v1/zkeys' \
  -H 'accept: application/json' \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer <BEARER_TOKEN>' \

External Transmission

Medium
Category
Data Exfiltration
Confidence
86% confidence
Finding

This step sends an authenticated request to generate or retrieve a root ZKey from an external API. Although part of the workflow, it is security-relevant because it extends external handling of authentication context and key-management material.

Content

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

STEP 5: GET ROOT ZKEY

bash
curl -s 'https://api.aiozstorage.network/api/v1/zkeys' \
  -H 'accept: application/json' \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer <BEARER_TOKEN>' \

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The alternative workflow writes secret-bearing config JSON to /tmp and also emits grant material to stdout, creating multiple leakage paths through temporary files, shell history, process inspection, and logging. Because grants and passphrases protect storage access, these exposures can lead directly to unauthorized data access or persistent credential misuse.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
91% confidence
Finding

This request sends a grant to an external registration API to obtain S3 credentials, effectively transforming one sensitive access artifact into another. If intercepted, logged, or misused, the resulting credentials could allow unauthorized upload access to the user's bucket.

Content

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

Use the upload grant (permissions 1,2,3):

bash
curl -s 'https://reg-api.aiozstorage.network/api/v1/access' \
  -H 'accept: application/json' \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer <BEARER_TOKEN>' \

Cloud Storage Exfiltration

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is uploaded to cloud storage (S3 / GCS / Azure Blob). This may be a legitimate backup or exfiltration to an external bucket. Manual review is recommended.

Content

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

bash
AWS_ACCESS_KEY_ID="<ACCESS_KEY_ID>" \
AWS_SECRET_ACCESS_KEY="<SECRET_KEY>" \
aws s3 sync ./<project_folder>/ s3://<BUCKET_NAME>/ \
  --endpoint-url https://s3.aiozstorage.network \
  --region us-east-1

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

This step transmits the website grant and bucket information to an external API to enable website hosting. The action is expected in context, but it still exposes access-control material externally and changes remote state.

Content

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

Use the website grant (permissions 1,3 — Read+List only):

bash
curl -s 'https://api.aiozstorage.app/api/v1/websites' \
  -H 'accept: application/json' \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer <BEARER_TOKEN>' \

External Transmission

Medium
Category
Data Exfiltration
Confidence
84% confidence
Finding

This step transmits the website grant and bucket information to an external API to enable website hosting. The action is expected in context, but it still exposes access-control material externally and changes remote state.

Content

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

Use the website grant (permissions 1,3 — Read+List only):

bash
curl -s 'https://api.aiozstorage.app/api/v1/websites' \
  -H 'accept: application/json' \
  -H 'content-type: application/json' \
  -H 'authorization: Bearer <BEARER_TOKEN>' \

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The CLI explicitly accepts sensitive passphrases via command-line arguments and repeatedly documents that usage. Command-line arguments are commonly exposed through shell history, process listings, audit logs, CI job logs, and telemetry, which can leak the secrets used to derive encryption keys and grants. In this skill context, the passphrase protects storage access material, so disclosure could enable unauthorized grant generation or decryption-related abuse.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The manifest describes a skill for deploying static websites to AIOZ Storage, which would ordinarily involve file handling and remote storage interaction. The declared runtime dependency on argon2-browser suggests a credential- or password-processing capability that is not justified by that stated purpose, and no code context is present here to connect it to deployment behavior.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.