fix(demo): print the attack-case fields that were actually observed
Quality gates / quality (push) Canceled after 0s
Quality gates / quality (push) Canceled after 0s
The RC security card rendered `http undefined · worker 12` for the flood case, which records no status, and repeated its bare status for the malformed case, which records no provider call. Both read as a broken card rather than the measurement it is. Build each row from the observed fields that exist and leave the rest out.
This commit is contained in:
1 parent
0bf8230280
commit
1bbcc10a35
2 files changed
+17
-5
No files matched your search
@@ -1195,11 +1195,18 @@ const securityReport = securityRun.report;
|
|||||||
if (securityReport.cases.length < 8) throw new Error('the RC attack suite must run every named abuse class');
|
if (securityReport.cases.length < 8) throw new Error('the RC attack suite must run every named abuse class');
|
||||||
await tap('[data-view="home"]', 450);
|
await tap('[data-view="home"]', 450);
|
||||||
const caseDetail = (item) => {
|
const caseDetail = (item) => {
|
||||||
const observed = item.observed || {};
|
const observed = item.observed === null || typeof item.observed !== 'object' ? {} : item.observed;
|
||||||
if ('providerCalls' in observed) return `http ${observed.status} · worker ${observed.providerCalls}`;
|
// Print each observed field the case actually recorded. A case with no `status` used to render
|
||||||
if ('refused' in observed) return `refused ${observed.refused}`;
|
// `http undefined` on camera, and one with no `providerCalls` rendered its status twice — both read
|
||||||
if ('imageBytesInLog' in observed) return `image bytes ${observed.imageBytesInLog}`;
|
// as a broken demo instead of the measurement it is.
|
||||||
return item.status;
|
const parts = [];
|
||||||
|
if ('status' in observed) parts.push(`http ${observed.status}`);
|
||||||
|
if ('refused' in observed) parts.push(`refused ${observed.refused}`);
|
||||||
|
if ('providerCalls' in observed) parts.push(`worker ${observed.providerCalls}`);
|
||||||
|
if ('providerTextLeaked' in observed) parts.push(`text leaked ${observed.providerTextLeaked}`);
|
||||||
|
if ('repeatedAnswerIdentical' in observed) parts.push(`identical ${observed.repeatedAnswerIdentical}`);
|
||||||
|
if ('imageBytesInLog' in observed) parts.push(`image bytes ${observed.imageBytesInLog}`);
|
||||||
|
return parts.length ? parts.join(' · ') : item.status;
|
||||||
};
|
};
|
||||||
const securityRows = [
|
const securityRows = [
|
||||||
['command', 'node scripts/security_attack_suite.mjs'],
|
['command', 'node scripts/security_attack_suite.mjs'],
|
||||||
|
|||||||
@@ -535,4 +535,9 @@ test('release demo runs the RC attack suite on camera and prints the verdict it
|
|||||||
assert.match(demo, /securityCardProof/);
|
assert.match(demo, /securityCardProof/);
|
||||||
// The finding must name where the fix lives instead of implying the boundary is already safe.
|
// The finding must name where the fix lives instead of implying the boundary is already safe.
|
||||||
assert.match(demo, /Refusing bytes by their content is the fix in review, not a claim this video makes/);
|
assert.match(demo, /Refusing bytes by their content is the fix in review, not a claim this video makes/);
|
||||||
|
// Each case row prints the fields it actually observed. A guarantee that the card never renders
|
||||||
|
// `http undefined` (a case with no status) or the bare status again (a case with no provider calls).
|
||||||
|
assert.match(demo, /'refused' in observed/);
|
||||||
|
assert.match(demo, /'providerTextLeaked' in observed/);
|
||||||
|
assert.doesNotMatch(demo, /http \$\{observed\.status\} · worker \$\{observed\.providerCalls\}`/);
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user