5 Commits
Author SHA1 Message Date
09f78aed19 fix: drop newline-bearing member names in arch ParsePackage (#38102)
The arch parser keeps tar member names verbatim. The index writer joins
those values one per line into the pacman database. So a member name
with a newline adds lines to that package's own `files` entry, which
libalpm reads as further fields.

The scope is one package record. An uploader cannot forge entries for
another package, and can set the same fields in `.PKGINFO` anyway. This
is input validation, not a privilege boundary.

`ParsePackage` now drops names that contain CR or LF. `joinFields` drops
such values again when writing the index, which also covers packages
that are already stored. Real packages never carry newlines in file
paths, so well-formed uploads are unaffected.

---------

Co-authored-by: silverwind <me@silverwind.io>
2026-08-07 20:47:33 +00:00
0c67849e68 fix(packages): validate debian distribution and component names (#38116)
**Newline injection into the Debian Release and Packages indices**

The `distribution` and `component` come straight from the request path
and are written line by line into the generated `Release` and `Packages`
files (the `Suite`/`Codename`/`Components` lines and the `Filename:
pool/<distribution>/<component>/...` line), but `UploadPackageFile` only
checked they were non-empty. `ctx.PathParam` url-decodes the segment, so
an encoded newline such as `main%0AInjected-Field: x` is accepted,
stored and then re-emitted for that distribution, which lets an
authenticated uploader forge extra fields in the index apt consumes.
Restricted both values to a conservative name pattern in the handler,
since that is the layer that accepts them; this should also keep the
pool paths well formed.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-06-29 06:50:22 +00:00
0eba0e371f fix(packages): validate module version in goproxy ParsePackage (#38104)
**Unvalidated version in goproxy ParsePackage**
The module version is read straight from the zip directory path and
never checked, so a crafted upload can leave a newline in it;
`EnumeratePackageVersions` then writes each stored version on its own
line for the `@v/list` endpoint, letting a module advertise fabricated
versions to `go` clients. Validated the parsed version with
`semver.IsValid` inside the parser, matching the version checks the
other package parsers already do.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2026-06-15 19:14:14 +02:00
988f0ea54a fix: validate gem name in rubygems parseMetadataFile (#38061)
The registry writes the stored gem name straight into its line-based
compact index, both the shared `/versions` listing (one `GEMNAME
versions md5` line per gem) and the per-package `info/{name}` file. The
parser only rejected an empty name or one containing a slash, so a
`.gem` whose gemspec `name` carries a newline was accepted and persisted
as the package name, letting an authenticated uploader forge extra lines
in the shared index and so spoof additional gem names, versions and
checksums to clients. The name is now checked against the upstream
RubyGems name pattern in the parser, which is the layer that already
validates the version.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-06-10 18:03:06 +00:00
7134c1f845 fix: bound debian ParseControlFile to a single control stanza (#38044)
**Packages-index stanza injection via Debian control file**

A `.deb` whose `control` file appends extra paragraphs after a blank
line was still accepted, and `ParseControlFile` stored the whole
multi-stanza blob in `p.Control`. That blob is re-emitted verbatim into
the generated `Packages` index, so the embedded blank line splits it
into separate stanzas and an uploader can smuggle a package entry with
an attacker-chosen `Filename` into the shared index. A binary control
file only holds one stanza, so parsing now stops at the blank line that
terminates it; well-formed packages are unaffected and the new subtest
covers the trailing-stanza case.

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2026-06-09 20:27:57 -07:00