fix(Extract-NTHashes): remove mismatched blob after checksum failure
On upload checksum mismatch, the script warned and preserved the local encrypted file but left the already-uploaded, corrupt blob live in remote storage under its normal name - discoverable only via an easy-to-miss console warning, and fetchable as if it were good data by any downstream consumer. Added Invoke-S3DeleteFile (SigV4-signed, mirrors the existing Put/Get helpers) and now delete the mismatched blob from S3 (AWS Tools or native HTTP path) or Azure Blob Storage right after detecting the mismatch. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -93,6 +93,23 @@ function Invoke-S3GetToFile([string]$endpointUrl, [string]$bucket, [string]$key,
|
||||
} finally { if ($req) { $req.Dispose() }; $client.Dispose() }
|
||||
}
|
||||
|
||||
function Invoke-S3DeleteFile([string]$endpointUrl, [string]$bucket, [string]$key, [string]$region, [string]$ak, [string]$sk, [bool]$forcePathStyle) {
|
||||
$uri = BuildS3Uri -endpointUrl $endpointUrl -bucket $bucket -key $key -forcePathStyle $forcePathStyle
|
||||
$payloadHash = (Get-HashHex (Get-Bytes ''))
|
||||
Add-Type -AssemblyName System.Net.Http -ErrorAction SilentlyContinue
|
||||
$client = [System.Net.Http.HttpClient]::new()
|
||||
try {
|
||||
$req = [System.Net.Http.HttpRequestMessage]::new([System.Net.Http.HttpMethod]::Delete, $uri)
|
||||
$hdrs = BuildAuthHeaders -method 'DELETE' -uri $uri -region $region -accessKey $ak -secretKey $sk -payloadHash $payloadHash
|
||||
$req.Headers.TryAddWithoutValidation('x-amz-date', $hdrs['x-amz-date']) | Out-Null
|
||||
$req.Headers.TryAddWithoutValidation('Authorization', $hdrs['Authorization']) | Out-Null
|
||||
$req.Headers.TryAddWithoutValidation('x-amz-content-sha256', $hdrs['x-amz-content-sha256']) | Out-Null
|
||||
$resp = $client.SendAsync($req).Result
|
||||
# S3 DELETE is idempotent and returns 204 even if the key never existed; anything else is a real failure.
|
||||
if (-not $resp.IsSuccessStatusCode) { throw "S3 DELETE failed: $([int]$resp.StatusCode) $($resp.ReasonPhrase)" }
|
||||
} finally { if ($req) { $req.Dispose() }; $client.Dispose() }
|
||||
}
|
||||
|
||||
function Protect-FileWithAES {
|
||||
param (
|
||||
[Parameter(Mandatory = $true)]
|
||||
@@ -355,6 +372,25 @@ try {
|
||||
if ($tempDownloadPath -and (Test-Path $tempDownloadPath)) {
|
||||
Remove-Item -Path $tempDownloadPath -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
# A checksum mismatch means the blob already sitting in remote storage under $blobName
|
||||
# is corrupt/incomplete. Leaving it live under its normal name would let a downstream
|
||||
# consumer silently fetch bad data, so remove it rather than only warning locally.
|
||||
try {
|
||||
if ($storageProvider -ieq 'S3') {
|
||||
if ($usedAwsTools -and $s3Client) {
|
||||
$delReq = New-Object Amazon.S3.Model.DeleteObjectRequest -Property @{ BucketName = $s3BucketName; Key = $blobName }
|
||||
$null = $s3Client.DeleteObject($delReq)
|
||||
} else {
|
||||
Invoke-S3DeleteFile -endpointUrl $s3EndpointUrl -bucket $s3BucketName -key $blobName -region $s3Region -ak $s3AccessKeyId -sk $s3SecretAccessKey -forcePathStyle:$s3ForcePathStyle
|
||||
}
|
||||
} else {
|
||||
Remove-AzStorageBlob -Blob $blobName -Container $containerName -Context $storageContext -Force -ErrorAction Stop
|
||||
}
|
||||
Write-Warning "Removed the mismatched blob '$blobName' from remote storage."
|
||||
} catch {
|
||||
Write-Warning "Could not remove the mismatched blob '$blobName' from remote storage - remove it manually: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
# Always delete plaintext hashes and compressed archive regardless of outcome.
|
||||
|
||||
Reference in New Issue
Block a user