mirror of
https://github.com/morluto/rea.git
synced 2026-11-12 17:59:08 +00:00
fix(audit): keep coverage unknown for nested ASARs in package hosts
A member of a PyInstaller or .NET host reaches the binary probe as a plain file. An ASAR among them has a NUL-bearing header, so the probe dropped it with no traversal and no omission, and source map checks could read not_observed with complete coverage. Ask the ASAR owner's signature probe, and record a match as a nested package that was not expanded, as inventory-classified ones already are.
This commit is contained in:
2 files changed
+48
-3
No files matched your search
@@ -1260,6 +1260,34 @@ describe("ReleaseExposureReader member allowances", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("ReleaseExposureReader nested packages in a host", () => {
|
||||
it("leaves coverage unknown for an ASAR a PyInstaller host carries", async () => {
|
||||
const root = await createTestTempDirectory("rea-release-exposure-nest-");
|
||||
await writeFile(
|
||||
join(root, "app.exe"),
|
||||
cArchiveExecutable({
|
||||
carrier: "pe",
|
||||
layout: "2.1",
|
||||
pythonVersion: 310,
|
||||
members: [
|
||||
{
|
||||
name: "resources",
|
||||
typeCode: "x",
|
||||
compress: true,
|
||||
payload: asarArchive([
|
||||
{ name: "app.js.map", bytes: Buffer.from("{}") },
|
||||
]),
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
const scanned = await inspect(root);
|
||||
expect(scanned.coverage).toBe("unknown");
|
||||
expect(scanned.extractable.formats).toContain("asar");
|
||||
expect(scanned.limitations.join("\n")).toContain("was not expanded");
|
||||
});
|
||||
});
|
||||
|
||||
describe("ReleaseExposureReader source-map count", () => {
|
||||
it.each([
|
||||
[
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
} from "./ArtifactFileOperation.js";
|
||||
import { decodeBinaryPlistText } from "./apple/BinaryPlistMaterializer.js";
|
||||
import { ArtifactEmbeddedFormatProbes } from "./ArtifactEmbeddedFormatProbes.js";
|
||||
import { createAsarHeaderSignatureProbe } from "./AsarHeader.js";
|
||||
import { ArtifactTraversalObservation } from "./ArtifactTraversalObservation.js";
|
||||
import { classifyEmbeddedExecutablePackage } from "./inventory/classify.js";
|
||||
import { inventoryArtifact } from "./inventory/ArtifactInventory.js";
|
||||
@@ -546,13 +547,11 @@ const scanOccurrences = async (
|
||||
packageKind !== null &&
|
||||
!parentsWithChildren.has(occurrence.occurrence_id)
|
||||
) {
|
||||
state.formats.add(packageKind);
|
||||
noteUnexaminedPackage(state);
|
||||
noteNestedPackage(state, packageKind, location);
|
||||
if (!occurrence.encrypted) {
|
||||
state.readable += 1;
|
||||
pushSample(state.memberSamples, location);
|
||||
}
|
||||
pushLimitation(state, `Nested package ${location} was not expanded.`);
|
||||
continue;
|
||||
}
|
||||
await examineMember(state, {
|
||||
@@ -1491,6 +1490,10 @@ const examinePackagedBinary = async (
|
||||
notePeNotExamined(state, member.location);
|
||||
}
|
||||
}
|
||||
if (native === null && header !== null && holdsAsarHeader(header)) {
|
||||
noteNestedPackage(state, "asar", member.location);
|
||||
return true;
|
||||
}
|
||||
if (native !== null) state.packagedNative += 1;
|
||||
else await examineProbedText(state, member, probe);
|
||||
if (native !== "pe") return true;
|
||||
@@ -1841,6 +1844,20 @@ const noteUnexaminedPackage = (state: ScanState): void => {
|
||||
state.coverageUnknown = true;
|
||||
};
|
||||
|
||||
const noteNestedPackage = (
|
||||
state: ScanState,
|
||||
format: PackageFormat,
|
||||
location: string,
|
||||
): void => {
|
||||
state.formats.add(format);
|
||||
noteUnexaminedPackage(state);
|
||||
pushLimitation(state, `Nested package ${location} was not expanded.`);
|
||||
};
|
||||
|
||||
/** The ASAR owner's signature test. A match does not establish a valid archive. */
|
||||
const holdsAsarHeader = (bytes: Buffer): boolean =>
|
||||
createAsarHeaderSignatureProbe().write(bytes).state === "matched";
|
||||
|
||||
const readListedEntry = async (
|
||||
container: OpenContainer | undefined,
|
||||
entry: ArtifactEntry,
|
||||
|
||||
Reference in new issue
Block a user