Documentation
¶
Overview ¶
Package registry resolves image references against their registries and decides, from image configuration alone, which PHP release each platform of an image carries.
Only manifests and image configs are read; layers are never downloaded. A PHP version is claimed only when an image config carries the build environment of the official php image (github.com/docker-library/php), which images built FROM php inherit:
PHP_VERSION=X.Y.Z
PHP_URL=https://www.php.net/distributions/php-X.Y.Z.tar.xz (or .gz, .bz2;
older images: https://secure.php.net/get/php-X.Y.Z.tar.xz/from/this/mirror)
PHP_SHA256=<64 hex digits> (very old images: PHP_MD5=<32 hex digits>)
Anything else makes no claim: an image that installs PHP some other way may well contain PHP, but its config does not prove which release.
Index ¶
- func BaseOSFromName(n string) string
- func CleanText(s string, max int) string
- func NormalizePlatform(p string) string
- func PHPFromEnv(env []string) (string, []string)
- func PlatformMatches(want, have string) bool
- func Transient(kind string) bool
- type Assessment
- type Error
- type ErrorKind
- type Options
- type Platform
- type PlatformVerdict
- type Reference
- type Resolution
- type Resolver
- type Stats
- type Verdict
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BaseOSFromName ¶
BaseOSFromName normalizes an org.opencontainers.image.base.name value to family:release ("debian:bookworm-slim" becomes "debian:bookworm", "alpine:3.21" stays). It returns "" for anything that is not a plain repository:tag of an operating system image.
func CleanText ¶
CleanText makes registry- or file-provided text safe to put in a one-line message: control characters (including newlines) become spaces, runs of spaces collapse, and the result is cut to max bytes (on a rune boundary) with "..." appended when cut.
func NormalizePlatform ¶
NormalizePlatform makes platform strings comparable: "linux/arm64/v8" and "linux/arm64" are the same platform.
func PHPFromEnv ¶
PHPFromEnv decides the PHP version from an image config's environment. It returns "" unless the environment is the official php image's build environment (see the package documentation).
func PlatformMatches ¶
PlatformMatches reports whether an image platform satisfies a requested one. Both are os/arch[/variant]; linux/arm64 and linux/arm64/v8 are the same; a request without a variant matches every variant of its os/arch ("linux/arm" matches linux/arm/v6 and linux/arm/v7), so all of them are judged.
Types ¶
type Assessment ¶
type Assessment struct {
Verdict Verdict `json:"verdict"`
Reason string `json:"reason"`
// Platforms lists the platforms that prove a PHP version.
Platforms []PlatformVerdict `json:"platforms,omitempty"`
// VulnerablePlatforms lists the vulnerable ones ("linux/amd64 (PHP 8.3.35)").
VulnerablePlatforms []string `json:"vulnerable_platforms,omitempty"`
// WithoutPHP lists platforms whose config proves no PHP version.
WithoutPHP []string `json:"without_php,omitempty"`
}
Assessment is the verdict for a Resolution, with the per-platform reasons.
func Assess ¶
func Assess(res *Resolution) Assessment
Assess judges a Resolution by knowledge.Upstream, platform by platform.
func AssessPlatform ¶
func AssessPlatform(res *Resolution, platform string) Assessment
AssessPlatform judges res for one platform only, as a FROM --platform= does; an empty platform judges every platform.
type Error ¶
Error is a resolution failure.
type ErrorKind ¶
type ErrorKind int
ErrorKind classifies resolution failures.
const ( KindNetwork ErrorKind = iota // the registry could not be reached or failed KindNotFound // the tag, digest or repository does not exist KindDenied // authentication required or refused (Docker Hub also answers this for repositories that do not exist) KindRateLimited // HTTP 429 after retries KindInvalid // not a valid reference KindUnsupported // a manifest the scanner does not read (schema 1, artifacts) KindOffline // offline mode cannot resolve the reference KindTimeout // a timeout or deadline expired (or the call was cancelled) )
type Options ¶
type Options struct {
// Offline makes no network requests. Only a docker.io/library/php
// reference with an exact X.Y.Z tag and no digest resolves (the official
// tags are the PHP version); everything else returns an Error of kind
// KindOffline.
Offline bool
// Keychain supplies registry credentials (default authn.DefaultKeychain,
// which reads the Docker config and credential helpers).
Keychain authn.Keychain
// Transport is the base HTTP transport (default: go-containerregistry's
// remote.DefaultTransport with a 30 s response header timeout).
Transport http.RoundTripper
// Timeout bounds each Resolve and Tags call (default 2 minutes).
Timeout time.Duration
// Retries is how many times a request is retried after HTTP 429, 500, 502,
// 503, 504 or a transient network error (default 4; negative for none).
Retries int
// MinBackoff and MaxBackoff bound the exponential backoff between retries
// (defaults 1 s and 30 s). A Retry-After header longer than MaxRetryAfter
// (default 60 s) is not waited for: the request fails as rate limited.
MinBackoff, MaxBackoff, MaxRetryAfter time.Duration
// Concurrency is the most registry requests in flight (default 4).
Concurrency int
// Mirrors sends requests for a registry to another host
// ({"index.docker.io": "mirror.example.com"}). The reference keeps its
// name; only the host contacted changes. Tests point Docker Hub at an
// in-memory registry this way.
Mirrors map[string]string
// UserAgent is sent with every request (default "php2shell-scan").
UserAgent string
// Platforms, when set, restricts every Resolution to these platforms
// ("linux/amd64", "linux/arm64"; see PlatformMatches): images for other
// platforms are left out and listed in Resolution.OmittedPlatforms.
Platforms []string
// RequestTimeout bounds the wait for each response's headers (default
// 30 s) and, at twice that, for its body, whatever Transport is given. A
// registry host that times out is not contacted again by this Resolver:
// later requests to it fail at once (as KindTimeout).
RequestTimeout time.Duration
}
Options configure a Resolver.
type Platform ¶
type Platform struct {
// Platform is os/arch[/variant]; "" when unknown (offline resolution).
Platform string `json:"platform"`
Digest string `json:"digest,omitempty"`
Created time.Time `json:"created,omitempty"`
// PHPVersion is set only when the image config proves it (see the package
// documentation); Evidence says how.
PHPVersion string `json:"php_version,omitempty"`
Evidence []string `json:"evidence,omitempty"`
// BaseOS is the base operating system release the image is built on,
// normalized ("alpine:3.21", "debian:bookworm"), from the
// org.opencontainers.image.base.name annotation (BaseSource
// "annotation") or, failing that, from the first history entry the
// docker-library build leaves (BaseSource "history"); "" when unknown.
BaseOS string `json:"base_os,omitempty"`
BaseSource string `json:"base_source,omitempty"`
// ImageVersion is the org.opencontainers.image.version annotation; for
// the official php image it is the explicit tag ("8.3.20-fpm-alpine3.21").
ImageVersion string `json:"image_version,omitempty"`
}
Platform is one image of a Resolution.
type PlatformVerdict ¶
type PlatformVerdict struct {
Platform string `json:"platform"`
PHPVersion string `json:"php_version"`
Status knowledge.UpstreamStatus `json:"status"`
Reason string `json:"reason"`
}
PlatformVerdict is the judgement for one platform with a proven PHP version.
type Reference ¶
type Reference struct {
// Original is the reference as given.
Original string
// Registry is the registry host as go-containerregistry normalizes it
// ("index.docker.io" for Docker Hub).
Registry string
// Path is the repository path within the registry ("library/php").
Path string
// Tag is the tag as written, "" when there is none (for a reference
// without a digest that means "latest").
Tag string
// Digest is the digest as written, "" when there is none.
Digest string
}
Reference is a parsed image reference. Unlike name.ParseReference, it keeps both the tag and the digest of "repo:tag@sha256:...".
func ParseReference ¶
ParseReference parses an image reference string.
func (Reference) EffectiveTag ¶
EffectiveTag is the tag a pull by tag uses: Tag, or "latest".
func (Reference) IsOfficialPHP ¶
IsOfficialPHP reports whether the reference names Docker Hub's official php image (php, library/php, docker.io/library/php, index.docker.io/library/php).
func (Reference) Repository ¶
Repository is the repository name with Docker Hub shown as docker.io: "docker.io/library/php", "ghcr.io/org/app".
type Resolution ¶
type Resolution struct {
// Ref is the reference as given; Reference is its parsed form.
Ref string `json:"ref"`
Reference Reference `json:"-"`
// Digest is the digest of the manifest or index the reference points at.
Digest string `json:"digest,omitempty"`
MediaType string `json:"media_type,omitempty"`
// Index is true when the reference points at an image index (manifest
// list).
Index bool `json:"index,omitempty"`
// Empty is true when the reference exists but holds no images: an index
// whose only manifests are attestations, or none at all. Docker Hub
// publishes new tags this way before their builds finish.
Empty bool `json:"empty,omitempty"`
// Platforms lists every image the reference holds, in index order.
Platforms []Platform `json:"platforms,omitempty"`
// Offline is true when the result comes from offline rules.
Offline bool `json:"offline,omitempty"`
// OmittedPlatforms lists the platforms left out by a platform filter
// (Options.Platforms, FilterPlatforms).
OmittedPlatforms []string `json:"omitted_platforms,omitempty"`
}
Resolution is what a reference points at.
func FilterPlatforms ¶
func FilterPlatforms(res *Resolution, platforms []string) *Resolution
FilterPlatforms returns a copy of res holding only the images whose platform matches one of platforms (all of them when platforms is empty). The others are listed in OmittedPlatforms. An offline resolution (platform unknown) is returned unchanged.
type Resolver ¶
type Resolver struct {
// contains filtered or unexported fields
}
Resolver resolves references, caching every result for its lifetime (one scan): the same reference, and the same manifest digest, are fetched once. It is safe for concurrent use.
type Stats ¶
type Stats struct {
// ManifestGets are GET requests for manifests: the requests Docker Hub
// counts against pull rate limits.
ManifestGets int `json:"manifest_gets"`
// ManifestHeads are HEAD requests for manifests (not counted by Docker
// Hub).
ManifestHeads int `json:"manifest_heads"`
// BlobGets are GET requests for blobs. The resolver only ever fetches
// image configs, never layers.
BlobGets int `json:"blob_gets"`
// TagLists are tags/list requests (one per page).
TagLists int `json:"tag_lists"`
// Other counts everything else (token and ping requests).
Other int `json:"other"`
// Redirects counts requests that follow a redirect (blob CDNs).
Redirects int `json:"redirects"`
// Retries counts requests repeated after a 429, a 5xx or a network error.
Retries int `json:"retries"`
// RateLimitRemaining is the last "ratelimit-remaining" header Docker Hub
// sent ("95;w=21600"), if any.
RateLimitRemaining string `json:"rate_limit_remaining,omitempty"`
}
Stats counts the HTTP requests a Resolver made.
type Verdict ¶
type Verdict string
Verdict is what a Resolution proves about CVE-2026-109618/109619.
const ( // Vulnerable: at least one platform carries a PHP release without the fix. Vulnerable Verdict = "vulnerable" // Fixed: every platform that proves a PHP version carries the fix. Fixed Verdict = "fixed" // Unknown: PHP versions are proven but at least one cannot be judged (a // development or pre-release build), and none is vulnerable. Unknown Verdict = "unknown" // NoPHP: no platform's config proves a PHP version. Not a finding. NoPHP Verdict = "no-php-evidence" // NoImages: the reference exists but holds no images (an empty index). NoImages Verdict = "no-images" // Unresolved: the reference could not be resolved. Unresolved Verdict = "unresolved" )
Directories
¶
| Path | Synopsis |
|---|---|
|
Package registrytest runs an in-memory OCI registry for tests and builds images that look like the official php image and images derived from it.
|
Package registrytest runs an in-memory OCI registry for tests and builds images that look like the official php image and images derived from it. |