T08 · Insecure Dependencies
- Location
install_dependencies.py:63- Finding
Unpinned Dependencies Installed from an External Package Repository
- Content
View full analysis
Vulnerability Details
File Location:
install_dependencies.py:63-70, 92-95
Vulnerability Type: Uncontrolled third-party dependency installation
Risk Level: Mediumpython # Base dependencies dependencies = [ "PyPDF2>=3.0.0", "python-docx>=0.8.11", "pdf2docx>=0.5.6", "Pillow>=9.0.0", "pdfplumber>=0.8.0", "docx2pdf>=0.1.8", ]python for dep in dependencies: package_name = dep.split('>=')[0] if '>=' in dep else dep.split('==')[0] if '==' in dep else dep if run_command(f"{sys.executable} -m pip install --upgrade {dep}", f"Install {package_name}"):The command execution helper used by this installation path is defined at
install_dependencies.py:10-14:python def run_command(cmd, description): """Run command and display progress""" print(f"🔧 {description}...") try: result = subprocess.run(cmd, shell=True, capture_output=True, text=True)Technical Analysis
Every dependency uses an open-ended minimum version constraint. The
--upgradeoption instructs pip to retrieve the newest version accepted by each constraint whenever the installer runs. There is no lock file, exact version pinning, package hash verification, or explicitly configured trusted package index.Consequently, the code that users install is not necessarily the code that was reviewed with this project. If a dependency release or its package-distribution account is compromised, a later execution of the installer can retrieve attacker-controlled package content. Python packages may execute build backends or installation-related code during installation, and malicious behavior can also execute when the resulting package is imported.
The use of
shell=Trueis unnecessary and increases the fragility of the command boundary. The dependency strings are currently hard-coded, so the reviewed code does not expose a direct user-controlled shell-injectio ...[truncated 1391 chars]- Remediation
View remediation
Remediation Suggestions
- Replace minimum-version constraints with exact, reviewed versions.
- Maintain a lock file generated by a dependency-management tool and commit it to source control.
- Require hashes for downloaded distributions, such as through a hash-locked requirements file and pip's
--require-hashesoption. - Remove unconditional
--upgrade; dependency upgrades should be explicit, reviewed changes. - Configure an approved package index explicitly and prevent unexpected fallback to untrusted indexes.
- Install dependencies in an isolated virtual environment using a non-privileged account.
- Invoke pip without a shell:
python subprocess.run( [sys.executable, "-m", "pip", "install", "--require-hashes", "-r", "requirements.lock"], check=True, capture_output=True, text=True, shell=False, )- Add automated dependency vulnerability, provenance, and integrity checks to the release process.
