Add install preflight safeguards (T-303)
This commit is contained in:
@@ -34,9 +34,10 @@ var packageIDPattern = regexp.MustCompile(`^[a-z0-9-]+$`)
|
||||
type PackageStage string
|
||||
|
||||
const (
|
||||
PackageStageVerify PackageStage = "verify"
|
||||
PackageStageManifest PackageStage = "manifest"
|
||||
PackageStageExtract PackageStage = "extract"
|
||||
PackageStageVerify PackageStage = "verify"
|
||||
PackageStageManifest PackageStage = "manifest"
|
||||
PackageStagePreflight PackageStage = "preflight"
|
||||
PackageStageExtract PackageStage = "extract"
|
||||
)
|
||||
|
||||
// PackageError preserves the underlying safe failure while making the package
|
||||
@@ -74,6 +75,20 @@ type PackageExpectation struct {
|
||||
App AppExpectation
|
||||
}
|
||||
|
||||
// VerifiedPackage describes the payload plan after the download, ZIP layout,
|
||||
// and app manifest have all been verified. It intentionally contains no ZIP
|
||||
// handles or destination paths, so callers cannot bypass safe extraction.
|
||||
type VerifiedPackage struct {
|
||||
PayloadBytes int64
|
||||
PayloadFiles int
|
||||
Entrypoint string
|
||||
}
|
||||
|
||||
// PreExtractCheck runs after package verification but before the extraction
|
||||
// destination is created. It lets application code enforce environment
|
||||
// preconditions without introducing application or platform dependencies here.
|
||||
type PreExtractCheck func(VerifiedPackage) error
|
||||
|
||||
type packageAppManifest struct {
|
||||
SchemaVersion int `json:"schema_version"`
|
||||
ID string `json:"id"`
|
||||
@@ -116,6 +131,18 @@ func (extractor Extractor) ExtractVerifiedFile(
|
||||
zipPath string,
|
||||
destination string,
|
||||
expectation PackageExpectation,
|
||||
) (ExtractResult, error) {
|
||||
return extractor.ExtractVerifiedFileWithCheck(zipPath, destination, expectation, nil)
|
||||
}
|
||||
|
||||
// ExtractVerifiedFileWithCheck preserves one file handle from Catalog
|
||||
// size/SHA-256 verification through ZIP scanning, manifest comparison, an
|
||||
// optional environment precheck, and safe extraction.
|
||||
func (extractor Extractor) ExtractVerifiedFileWithCheck(
|
||||
zipPath string,
|
||||
destination string,
|
||||
expectation PackageExpectation,
|
||||
beforeExtract PreExtractCheck,
|
||||
) (ExtractResult, error) {
|
||||
expectedHash, err := expectation.validate()
|
||||
if err != nil {
|
||||
@@ -157,6 +184,15 @@ func (extractor Extractor) ExtractVerifiedFile(
|
||||
if err := manifest.matches(expectation.App); err != nil {
|
||||
return ExtractResult{}, packageError(PackageStageManifest, err)
|
||||
}
|
||||
if beforeExtract != nil {
|
||||
verified, err := verifiedPackageFromPlan(plan, normalizedEntrypoint)
|
||||
if err != nil {
|
||||
return ExtractResult{}, packageError(PackageStageVerify, err)
|
||||
}
|
||||
if err := beforeExtract(verified); err != nil {
|
||||
return ExtractResult{}, packageError(PackageStagePreflight, err)
|
||||
}
|
||||
}
|
||||
result, err := extractor.extractPlan(destination, normalizedEntrypoint, plan)
|
||||
if err != nil {
|
||||
return ExtractResult{}, packageError(PackageStageExtract, err)
|
||||
|
||||
Reference in New Issue
Block a user