glsec

Rules / GL079

GL079 Dependency confusion via extra package index (pip --extra-index-url)

Severity: warn
OWASP: CICD-SEC-3 – Dependency Chain Abuse

Risk

Adding a public package index alongside a private one is the classic dependency-confusion foothold. pip resolves the highest version across all configured indexes, so an attacker who publishes a higher-versioned package of the same name on the public index (pypi.org) gets it pulled into the build instead of your private package.

What glsec checks

GL079 flags a pip install (pip, pip3, or python -m pip install) that passes --extra-index-url in any script:, before_script:, after_script:, run:-step, or hooks:pre_get_sources_script line:

build:
  script:
    - pip install internal-lib --extra-index-url https://pypi.org/simple   # flagged

Commented lines (starting with #) are ignored.

Trigger example

build:
  script:
    - pip install internal-lib --extra-index-url https://pypi.org/simple

Safe alternative

Use a single trusted --index-url (not --extra-index-url) so resolution cannot fall through to a public index, and pin dependencies with hashes or a lockfile:

build:
  script:
    - pip install --index-url https://pypi.internal.example.com/simple -r requirements.txt

For a private mirror that must proxy PyPI, configure the proxy on the index host so a single --index-url still resolves everything, rather than layering a second public index into the client.

Scope and false-positive risk

--extra-index-url has legitimate uses, but its presence is the risk surface, so this is the higher-signal half of dependency-confusion detection. The npm/yarn/pnpm --registry variant (pointing back at the public registry while a scoped private registry is in use) is far more FP-prone — most projects legitimately use the public registry — and is intentionally not covered here.

Documentation for glsec 1.23.0. Source of this page · Rule implementation