Back to skill

Security audit

Quantum Agent Engineering

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate Quantinuum/Guppy skill, but it also guides agents through authenticated Nexus jobs that can spend credits and persist job/auth state without a single clear consent boundary.

Install only if you want an agent to help with Quantinuum/Guppy/Selene and Nexus workflows. Before any Nexus or hardware-backed run, require an explicit live-mode confirmation, target device, max_cost, total budget, account/group choice, and cleanup plan for ~/.qnx auth tokens and cached job refs. Prefer pinned dependency versions and review generated Python/temp files before running them.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T08 · Insecure Dependencies

Warning
Location
SKILL.md:11
Finding
Unpinned Third-Party Dependencies Create a Mutable Supply-Chain Risk<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:11-19` **Additional Locations**: `references/guppy-v1-migration.md:7,103`; `references/pytket.md:14`; `scripts/qtda_template.py:7-10` **Vulnerability Type**: Unpinned third-party package installation **Risk Level**: Medium ### Complete Code Snippet ```bash pip install "guppylang>=1.0" # Python >= 3.12; Selene ships inside guppylang pip install pytket pytket-quantinuum # only for the TKET compile lane (offline; no credentials, no HQCs) ``` The Skill also recommends installing dependencies into a project-local directory without exact version or integrity constraints: ```bash pip install --target .pydeps "guppylang>=1.0" numpy scipy ``` The executable template repeats the mutable installation instruction: ```python """ Minimal Guppy + Selene smoke test. Run: pip install "guppylang>=1.0" python qtda_template.py """ ``` ### Technical Analysis The installation instructions permit pip to resolve dependency versions at installation time. The lower-bound constraint `"guppylang>=1.0"` accepts every future compatible or incompatible release, while `pytket`, `pytket-quantinuum`, `numpy`, and `scipy` have no version constraints at all. No lock file, package hashes, or explicitly constrained package index is supplied. Python package installation can execute package build backends and installation hooks with the privileges of the user running pip. Consequently, the effective code installed by following these instructions can change after the Skill has been audited. This creates a supply-chain exposure if: - an upstream package or maintainer account is compromised; - a future release is malicious or unexpectedly incompatible; - dependency resolution selects a compromised transitive dependency; - an untrusted or misconfigured package index supplies a package with the expected name. The project documentation elsewhere recommends `qnexus==0.48.2`, demonstrating that exact pinning is feasibl ...[truncated 1341 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace lower-bound and unconstrained dependencies with exact, reviewed versions, for example: ```text guppylang==<reviewed-version> pytket==<reviewed-version> pytket-quantinuum==<reviewed-version> numpy==<reviewed-version> scipy==<reviewed-version> ``` 2. Generate and commit a lock file that includes all transitive dependencies. 3. Require package hashes during installation, such as with a hash-locked requirements file and: ```bash python -m pip install --require-hashes -r requirements.lock ``` 4. Explicitly use the intended official package index and prohibit fallback to untrusted indexes in automated environments. 5. Install dependencies in an isolated virtual environment rather than into a shared interpreter. 6. Review and test dependency updates before deliberately regenerating the lock file. 7. Add automated dependency vulnerability and provenance checks to CI. 8. Update `SKILL.md`, `references/guppy-v1-migration.md`, `references/pytket.md`, and `scripts/qtda_template.py` so every installation example points to the same immutable dependency manifest. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (18)

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This skill explicitly instructs users to submit potentially billable Nexus hardware and costing jobs, and even notes that some estimation calls are themselves billable, but it does not place a clear up-front user confirmation or safety gate before real spend. In an agent setting, that can lead to unintended charges or costly automated actions if the skill is invoked without an explicit budget approval step.

Session Persistence

Medium
Category
Rogue Agent
Content
27. **Role and group semantics decide who can delete your evidence.** Roles are `Reader | Contributor | Maintainer | Administrator`, and where a user holds both a personal and a team role the **most permissive wins** — revoking the personal one changes nothing. Deleting a project deletes it for everyone. A *group* shares a quota (`user_group=` at submission); a *team* shares resources; they are not interchangeable. Hardware queue position is an admin-set priority 1–10, default 5. See `references/nexus-admin.md`.
28. **A lost hardware sweep is re-attached, never re-run — and every job carries a meter.** Recover by job id, by the `execution` block of a shipped dump, or by property query (`--gate`), into an on-disk cache keyed by job id; make resume a command (`python -m quantum.resume`), because an ad-hoc script under pressure becomes a resubmission. Take the decode width from the job's stamped `n_qubits`, not from a driver constant that has moved on. Report a non-`COMPLETED` job with a plain reason and skip it — one `DEPLETED` id must not abandon the other nine — and fail loudly on an unknown id rather than silently executing the row and buying the shots twice. Emit one uniform meter per job (mode `emulator | dry | live | refetch`, device, job id, qubits, shots, seed, estimated + billed HQC, derived delta/ratio) into the dump's `execution` block: `None` must mean "this lane has no such value", so a re-fetch keeps its real `qnx.jobs.cost` even with no estimate, or a resumed sweep reports itself as free. `SweepRunner(resume_from=…)` consumes cached jobs per row and falls through to execution once they run out. See `references/sweep-runner.md` and `references/nexus-jobs.md`.
29. **Run a known-fidelity Bell control beside every batch.** A `|Φ+⟩` pair in the same job costs almost nothing and is the only check that catches a *corrupted batch* rather than a wrong circuit: accept when `anti_correlated / shots <= 4*sqrt(0.5/shots)`, and **fail the whole batch** when it does n
...[truncated 26 chars]
Confidence
91% confidence
Finding
The skill repeatedly recommends persisting job IDs, saved refs, cache rows, execution metadata, and on-disk recovery artifacts for later reattachment and resume. While operationally useful, this creates a session-persistence surface that can expose sensitive provenance, enable unintended job recovery/replay behavior, or leak account/project context if stored insecurely or reused across sessions.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Context-Inappropriate Capability

Medium
Confidence
85% confidence
Finding
The document explicitly recommends generating Python source into a temp directory and then dynamically importing and executing it. Even if intended to work around Guppy's source-inspection behavior, this creates a code-execution path where any untrusted values that reach the rendered source or the writable temp location can result in arbitrary Python execution, which is broader than the stated quantum-circuit task.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The documentation normalizes writing executable Python into a shared temp directory and immediately executing it, but does not warn about the security implications. Users may adopt the pattern without understanding that temp directories can be shared or writable by other processes and that executing generated code carries arbitrary-code-execution risk.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Vague Triggers

Medium
Confidence
97% confidence
Finding
The instruction to use this skill whenever a user asks about broad topics like 'quantum + graphs' or fraud/anomaly detection creates an overly broad trigger surface. This can cause unintended invocation in loosely related conversations, increasing the chance that the agent applies specialized guidance out of context and amplifies irrelevant or risky operational instructions.

Session Persistence

Medium
Category
Rogue Agent
Content
## Persistence canary pattern

Start every new experiment session with a trivial write (comment in
`quantum/requirements.txt`, a version note in a changelog file) and **end the
turn immediately**. If that trivial edit persists, larger gates are safe to
attempt. If the canary itself rolls back twice in a row, stop — further code
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.

Session Persistence

Medium
Category
Rogue Agent
Content
a remembered URL, then poll `/device/token` until the user approves and `write_token` the
refresh/access pair.

Run the poller **in the background** (`nohup … &`, print the code from its log). A foreground
poller races the command timeout and dies while the user is still on the approval screen, and
the code it printed is then dead too.
Confidence
65% 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.

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Ae4

Medium
Category
analysis-evasion
Confidence
80% confidence
Finding
Suspicious Unicode normalization or mixed-script content

Context-Inappropriate Capability

Low
Confidence
80% confidence
Finding
The guidance to inject a project root into sys.path expands import resolution and can cause unintended or attacker-influenced modules to be loaded if the path is writable or not tightly controlled. In combination with dynamic module loading, this increases the attack surface beyond what is necessary for running emulator jobs.

Missing User Warnings

Low
Confidence
88% confidence
Finding
This markdown file describes a file-write operation that creates `src/data/qtda-results.json`, and later notes that rerunning the command rewrites that file. The skill description does not include any caution that it modifies checked-in project data, which is relevant user-facing disclosure for a workflow that changes repository contents.

Missing User Warnings

Low
Confidence
82% confidence
Finding
The markdown instructs the operator to identify and kill surviving worker processes, which is a potentially disruptive operation affecting running jobs. While the step is operationally justified, the text does not explicitly warn that killing the wrong process or terminating active workers can interrupt ongoing work.

Natural-Language Policy Violations

Low
Confidence
81% confidence
Finding
The certified/forbidden-language table repeatedly instructs the model to use only approved phrasing and to 'never say' certain terms. This is a natural-language policy constraint embedded in the skill, but it does not offer user choice or opt-in for wording/locale preferences.

Static analysis

No suspicious patterns detected.