aquasecurity/trivy

Bug: `index out of range [0]` panic in dependency parsers and the OS detector from unchecked `strings.Fields(...)[0]`

开放

#10,976 创建于 2026年7月20日

 (8 条评论) (0 个反应) (0 位负责人)Go (371 个派生)batch import
good first issuehelp wanted

仓库指标

星标
 (35,000 个星标)
PR 合并指标
 (平均合并 5天 2小时) (30 天内合并 53 个 PR)

描述

Description

The same unsafe pattern is repeated across several parsers and the Amazon detector: a string is normalized (operators replaced with spaces, or split on delimiters) and then strings.Fields(...)[0] (or ss[0]) is taken without checking that the slice is non-empty. If the string reduces to only whitespace/delimiters after normalization, strings.Fields returns an empty slice and indexing [0] panics with runtime error: index out of range [0] with length 0. The panic aborts the entire scan, not just the parsing of the offending file.

In every case listed below the input string is invalid for its format (it is not the kind of output poetry/cocoapods/mix/bundler actually produces), yet it remains syntactically valid for its container (valid TOML/YAML/lock-file line) and therefore reaches the parser unimpeded. Trivy scans arbitrary files, including hand-edited or untrusted ones, so on a malformed entry it seems reasonable to degrade gracefully — skip the entry or return a parse error — rather than crash and abort the whole scan.

Affected locations

Every row below was reproduced by running the corresponding parser/detector on the listed input.

File:line Access Trigger (invalid but parseable input) Status
pkg/detector/ospkg/amazon/amazon.go:106 (IsSupportedVersion), then :45 (Detect) strings.Fields(osVer)[0] an image whose /etc/system-release contains the line Amazon Linux with no version 🔴 unguarded — the most realistic case
pkg/dependency/parser/python/pyproject/pyproject.go:78 strings.Fields(dep)[0] pyproject.toml with dependencies = [""] (also " ", "<", "===") — invalid PEP 508, valid TOML 🔴 unguarded
pkg/dependency/parser/swift/cocoapods/parse.go:70 strings.Fields(s)[0] Podfile.lock with an empty/whitespace dependency string — invalid CocoaPods, valid YAML 🔴 unguarded
pkg/dependency/parser/hex/mix/parse.go:49 ss[0] inside the if len(ss) < 8 branch (which includes 0) mix.lock line like "x": (empty body) — invalid mix.lock 🔴 unguarded
pkg/dependency/parser/ruby/bundler/parse.go:69 s[0] in the countLeadingSpace(line) == 6 branch Gemfile.lock line of exactly 6 spaces — invalid Gemfile.lock 🔴 unguarded
pkg/dependency/parser/conda/environment/parse.go:107 parts[0] environment.yml with a - "=" line 🟢 fixed in #10955 (guard at :104)

How realistic is such input

The cases differ noticeably in reachability, which is worth taking into account when prioritising.

Amazon (amazon.go:106) — realistic, and it needs no hand-editing of any file. The input here does not come from a project manifest but from the scanned artifact itself. The amazonlinux analyzer builds OS.Name as strings.Join(fields[2:], " "), so an /etc/system-release consisting of the single line Amazon Linux (no version) yields OS.Family == amazon and OS.Name == "". The OS.Detected() gate only checks Family != "", so an empty Name passes it and IsSupportedVersion panics before Detect is even reached. Official Amazon Linux images do not contain such a file, but its content is fully controlled by whoever builds the image — so when scanning a third-party image from someone else's registry, this is an externally controlled scanner crash.

The other four are synthetic. Podfile.lock, mix.lock and Gemfile.lock are generated by tooling (pod install, mix deps.get, bundle install), and none of them will ever emit an empty dependency string, or "x": with an empty body, or a line of exactly six spaces. Getting such input requires editing the file by hand or crafting it deliberately, so the chance of hitting it in a real project is close to zero.

pyproject.toml sits in between: unlike lock files it is written by a human rather than generated, so an accidentally left-over empty string in the list (dependencies = ["flask", ""]) is a fairly plausible typo — and it takes down the whole scan.

Reproduction

Amazon (main case):

mkdir -p rootfs/etc && echo 'Amazon Linux' > rootfs/etc/system-release
trivy rootfs rootfs
panic: runtime error: index out of range [0] with length 0
...
github.com/aquasecurity/trivy/pkg/detector/ospkg/amazon.(*Scanner).IsSupportedVersion
	pkg/detector/ospkg/amazon/amazon.go:106
github.com/aquasecurity/trivy/pkg/scan/ospkg.(*scanner).Scan
	pkg/scan/ospkg/scan.go:67

pyproject (synthetic example):

  1. Create a directory with pyproject.toml (hand-crafted; poetry/pip would never emit this):
[project]
name = "test"
version = "1.0.0"
dependencies = ["flask>=1.0", ""]
  1. Run trivy fs . — Trivy panics with runtime error: index out of range [0] with length 0 and the scan aborts.

The same reproduces for cocoapods, mix, and bundler with the corresponding invalid lock files (see the table).

Desired behaviour

Trivy skips the malformed entry (or returns a parse error for that specific file) and keeps scanning without panicking. The correct pattern already exists in the code — a length check before indexing (e.g. bundler/parse.go:133); it should be applied systematically to all the locations above.

Notes

  • There are no user reports for these locations — they were all found by reading the code.
  • The conda instance is already being fixed by PR #10955; this issue tracks the remaining (systemic) locations.
  • Original report: discussion #10961.

贡献者指南