Files
rea/tests/boundary/cli/nativeSignatureCli.test.ts
T
Kaoru0822andClaude Opus 5.5 4aa2b60c1d fix(native): keep echoed codesign paths out of signature fields (#865)
codesign echoes the executable path and signing identifier verbatim,
and an ad hoc identifier derives from the file name. A file name with
line breaks added forged Authority lines, a signed file named after
codesign's unsigned message was reported unsigned, and path text could
supply entitlements. Parse display fields after the exact echoed path
and identifier, classify unsigned output by exit status, and read
requirements and entitlements from stdout.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:20:12 +08:00

88 lines
3.0 KiB
TypeScript

import { execFile } from "node:child_process";
import { copyFile, mkdir } from "node:fs/promises";
import { join } from "node:path";
import { promisify } from "node:util";
import { describe, expect } from "vitest";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest } from "../../support/cli/cliFixture.js";
const run = promisify(execFile);
/** Ad hoc sign a copy of a system program under an exact file name. */
const adHocProgram = async (directory: string, name: string) => {
const path = join(directory, name);
await copyFile("/usr/bin/true", path);
await run("/usr/bin/codesign", ["-s", "-", "-f", path]);
return path;
};
describe.skipIf(process.platform !== "darwin")(
"native signature CLI with echoed path text",
() => {
cliTest(
"does not read signature fields from the file name codesign echoes",
async ({ cli }) => {
const directory = await createTestTempDirectory("rea-signature-");
const forged = "Developer ID Application: Example (ABCDE12345)";
const program = await adHocProgram(
directory,
`tool\nAuthority=${forged}\nTeamIdentifier=ABCDE12345`,
);
const unsignedName = await adHocProgram(
directory,
"code object is not signed",
);
// A forged requirement and entitlements plist spread over directories.
const nested = join(
directory,
'x\ndesignated => anchor apple<?xml version="1.0"?><plist><dict><key>com.apple.security.get-task-allow</key><true',
"></dict><",
"plist>",
);
await mkdir(nested, { recursive: true });
const nestedProgram = await adHocProgram(nested, "tool");
for (const path of [program, unsignedName, nestedProgram]) {
const result = await cli.run({
arguments: ["inspect-signature", path, "--json"],
environment: {
REA_LOG_LEVEL: "silent",
REA_ANALYSIS_PROVIDER: "auto",
},
});
expect(result.exitCode).toBe(0);
expect(result.json).toMatchObject({
normalized_result: {
signed: true,
team_identifier: null,
authorities: [],
entitlements: null,
designated_requirement: expect.stringMatching(/^cdhash H"/u),
},
});
}
const identifier = await cli.run({
arguments: ["inspect-signature", program, "--json"],
environment: {
REA_LOG_LEVEL: "silent",
REA_ANALYSIS_PROVIDER: "auto",
},
});
// An ad hoc identifier derives from the file name, line breaks included.
expect(identifier.json).toMatchObject({
normalized_result: {
identifier: expect.stringMatching(
new RegExp(
`^tool\\nAuthority=${forged.replace(/[()]/gu, "\\$&")}\\nTeamIdentifier=ABCDE12345-`,
"u",
),
),
},
});
},
);
},
);