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. ]]>
