Back to skill

Security audit

Chromia Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is coherent Chromia development guidance, but it under-protects production signing keys and recommends high-impact deployment/reset commands without enough safeguards.

Review this skill before installing. It is not malicious documentation, but use it only with explicit control over deployments and secrets: avoid putting production admin private keys in project .env files or browser/client code, omit -y unless you have independently checked the target network/container/key, and treat --wipe and deployment remove as destructive commands requiring confirmation.

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

Warning
Location
SKILL.md:108
Finding
Production Private Keys Are Directed into Plaintext Environment Files<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 108-111; related guidance at lines 456-461 and 482-484 **Vulnerability Type**: Plaintext storage of sensitive signing credentials **Risk Level**: Medium ### Vulnerable Snippet ```markdown 1. Run `chr keygen --key-id <dapp-name>` to generate a keypair (stored in `~/.chromia/`) 2. Provide the public key — readable via `cat ~/.chromia/<dapp-name>.pubkey` or from CLI output 3. Store the **private key** (`~/.chromia/<dapp-name>`) in `.env` as e.g. `ADMIN_PRIVKEY=<hex>` — it will be needed for signing admin transactions from the client 4. Add `.env` to `.gitignore` ``` Related policy: ```markdown ### Zero-Secret Policy - **NEVER** embed private keys, mnemonics, or secrets in Rell code or `chromia.yml` - Use `moduleArgs` with `"PLACEHOLDER_PUBKEY"` for admin keys in config - Store secrets in `.env` files; load via client-side tooling only - Add `.env` to `.gitignore` in every project ``` ### Technical Analysis The Skill explicitly instructs users to copy a production private key into a plaintext `.env` file within the project environment. Adding the file to `.gitignore` only reduces the likelihood of committing it to Git; it does not encrypt the key or protect it from: - Malicious or compromised dependencies running under the same user account. - Local processes with access to the project directory. - Backup, synchronization, indexing, or diagnostic tools. - Accidental inclusion in archives, build contexts, logs, or support bundles. - Frontend build systems that expose selected environment variables in generated assets. - Excessively permissive filesystem permissions. The key is described as an administrative signing credential. Its confidentiality therefore directly protects privileged blockchain operations. ### Attack Path 1. A developer follows the Skill and copies the production private key into `.env` as `ADMIN_PRIVKEY`. 2. A malicious package, compromised build tool, local process ...[truncated 1134 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not direct users to copy production private keys into project-local `.env` files. 2. Retain keys in the Chromia key store where supported and refer to them through `--key-id` rather than exporting raw key material. 3. For automated production signing, use a managed secret service, OS credential store, hardware-backed wallet, HSM, or KMS-backed signing service. 4. Separate administrative signing into a server-side process; never load administrative keys into browser or frontend application code. 5. Apply least privilege by using distinct keys for deployment, asset administration, and routine application operations. 6. If plaintext storage is temporarily unavoidable: - Store it outside the project directory. - Restrict permissions to the owning user. - Exclude it from backups, archives, container build contexts, and frontend bundling. - Add automated secret scanning to CI and pre-commit checks. - Rotate the key immediately after suspected exposure. 7. Update the Skill to explain that `.gitignore` is not a security boundary and does not protect secrets already committed or accessible to local processes. ]]>

T08 · Insecure Dependencies

Warning
Location
references/postchain-client.md:230
Finding
Dependency Installation Guidance Does Not Pin Reviewed Versions<![CDATA[ ## Vulnerability Details **File Location**: `references/postchain-client.md`, lines 230-238 **Vulnerability Type**: Unpinned third-party package installation **Risk Level**: Medium ### Vulnerable Snippet ```markdown | Language | Package | Install | |---|---|---| | TypeScript/JS | `postchain-client` | `npm install postchain-client` | | TypeScript/JS (FT4) | `@chromia/ft4` | `npm install @chromia/ft4` | | Kotlin/Java | `postchain-client` | Maven (GitLab registry) | | Rust | `postchain-client` | `cargo add postchain-client` | | Go | Chromia Go client | GitLab | | C# | Postchain C# client | NuGet | | Python | Postchain Python | pip | ``` ### Technical Analysis The recommended npm and Cargo commands do not specify exact reviewed versions. Their resolution therefore depends on registry state at installation time. The broader table also names package sources without requiring a version, immutable commit, checksum, or lockfile. This weakens reproducibility and allows later releases to enter a project without explicit review. If an upstream package, publisher account, registry, or transitive dependency is compromised, installation may introduce hostile code. In npm ecosystems, package lifecycle scripts may execute during installation; at runtime, compromised blockchain client code may also interact directly with transaction arguments and signing material. The audit did not establish that any named package is currently malicious. The finding concerns unsafe dependency acquisition practices and exposure to future supply-chain compromise. ### Attack Path 1. A developer follows the documented unpinned installation command. 2. The package manager resolves the current package version and its dependency graph at that time. 3. An upstream package or transitive dependency has been compromised, or an unreviewed release contains malicious behavior. 4. The malicious component executes through an installation hook or when imported by the application. 5. It reads ac ...[truncated 1026 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace generic installation commands with exact, reviewed versions, for example `npm install --save-exact package@X.Y.Z`. 2. Commit package lockfiles and use reproducible CI installation commands such as `npm ci`. 3. Pin Git-based libraries to immutable commits or verified release tags; use Chromia library RIDs where supported. 4. Require explicit security review before dependency upgrades. 5. Enable dependency integrity and provenance verification where supported by the package manager. 6. Audit transitive dependencies and installation scripts before allowing packages into signing or deployment environments. 7. Disable unnecessary lifecycle scripts in high-trust build environments, while validating that doing so does not break legitimate installation. 8. Isolate dependency installation and builds from production keys and deployment credentials. 9. Use automated vulnerability, license, provenance, and secret-access checks in CI. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (12)

Missing User Warnings

Medium
Confidence
88% confidence
Finding
The skill instructs users to place a private key in .env for later signing but does not explicitly warn that this is a highly sensitive secret requiring strict handling, restricted permissions, no logging, and secure storage. In a developer-assistance context, omission of those warnings can lead to accidental exposure through commits, terminal history, screenshots, backups, or insecure local environments.

Context Window Stuffing

Medium
Category
Memory Poisoning
Content
# Test config — use rell.test.keypairs.alice keypair (deterministic, no real-world value)
# pubkey:  02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27
# privkey: 0101010101010101010101010101010101010101010101010101010101010101
# When generating client code that signs with this test admin key, always provide
# the private key so the user can store it (e.g. in .env) for later signing.
test:
Confidence
84% confidence
Finding
Including an actual private key value, even if described as deterministic test material, conditions agents and users to handle/export private keys directly and increases the chance that the pattern is copied into real workflows. In a security skill, embedding raw secret material is especially risky because it can blur the boundary between safe test fixtures and real secret-management practices.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The command 'chr node start --wipe' is destructive because it resets local database state, but the skill presents it as a normal validation step without a warning. This can cause unintentional loss of local test or development data, and an agent following the skill could recommend it in inappropriate contexts.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The skill contains contradictory secret-handling guidance: one section says to never write placeholder pubkeys and to wait for a real user-provided public key, while another 'Zero-Secret Policy' section says to use PLACEHOLDER_PUBKEY in moduleArgs. Conflicting instructions in a security-sensitive workflow can cause agents to generate unusable or unsafe configs, or normalize placeholder/secret mishandling in deployment paths.

Vague Triggers

Medium
Confidence
86% confidence
Finding
This markdown file is in scope for vague-trigger review. The phrase "Every agent trigger must enforce ALL of the following" refers to triggers without defining what counts as a trigger, invocation phrase, or boundary, which leaves activation scope ambiguous and can cause inconsistent or unintended invocation behavior.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
Mandating 'chr node start --wipe' before deployment validation without a destructive-action warning increases the risk of accidental local state deletion. Because this appears in a critical rules section, agents are more likely to treat it as mandatory and repeat it automatically, amplifying the chance of harm.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The AI Inference section states that AI inputs and outputs can be recorded on-chain for transparency, but it does not warn that blockchain records may be durable, broadly visible, and inappropriate for sensitive prompts, secrets, or personal data. In a developer guidance skill, this omission can lead builders to design systems that permanently expose user content or operational secrets.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
### Key Details

- Signatures are auto-verified by the extension — no verification logic needed in Rell
- Complete asset list available at Stork documentation
- Override Stork and publisher public keys in config if needed
Confidence
75% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Session Persistence

Medium
Category
Rogue Agent
Content
```bash
# First deployment (create)
chr deployment create \
  --network testnet \
  --blockchain <blockchain_name> \
  --key-id <key_name> \
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- `-s chromia.yml` — settings file (always include this)
- `-bc <name>` / `--blockchain <name>` — which blockchain to deploy
- `-d <name>` / `--network <name>` — which deployment target from `deployments:` in settings
- `-y` — skip confirmation prompt

## Deployment Workflow
Confidence
85% confidence
Finding
The `-y` flag enables non-interactive execution by bypassing confirmation, which reduces human oversight at the exact point where destructive or costly deployment actions occur. In an agent skill meant to guide automation, this meaningfully increases the risk of autonomous execution of unintended deployments or changes.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The documentation explicitly recommends using `-y` to skip the deployment confirmation prompt during blockchain deployment, but does not pair that advice with a warning about reviewing target network, container, blockchain name, and key before execution. In a deployment context, suppressing the last interactive safeguard increases the chance of accidental or automated misdeployment, especially when an AI agent is following instructions non-interactively.

Missing User Warnings

Medium
Confidence
86% confidence
Finding
The file includes a command to remove a deployment, which is a destructive operation. Although the label says "permanent!", there is no fuller warning about consequences such as service disruption, data loss risk, or the need to confirm intent before executing it.

Static analysis

No suspicious patterns detected.