feat: the rating badge, served from our domain and regenerated from the record
Christian: 'I want them to put the BigTech.Sucks rating badge on their site. It should be marketing for them.' A sticker anyone can copy is worthless, so it is not a sticker. - badge/<product>.svg is generated from the assessment row on every build. Score, grade and date are never typed by a human. - Served from bigtech.sucks. A copy pasted onto a vendor's own server is not a badge and its link will not resolve. The domain is the signature. - Regenerated every build, so improving earns a better badge without asking and regressing loses it without warning. - The SVG carries the record id, version and method in a comment, so a real badge can be traced back to one assessment. badges.html publishes the rules: free forever, only rated products, no badge as a favour, and misuse called out publicly. Free matters, because charging for it would make it worthless to both sides: marketing for the vendor, receipts for their customer. Also rewrote the write pass to emit report + badge per assessment in one loop, so they can never drift apart.
This commit is contained in:
parent
aafce7773b
commit
21208d50ab
10 changed files with 246 additions and 51 deletions
|
|
@ -65,6 +65,7 @@ footer{margin-top:5rem;padding-top:1.5rem;border-top:1px solid var(--rule);color
|
||||||
const NAV = `<nav>
|
const NAV = `<nav>
|
||||||
<a href="/">The list</a>
|
<a href="/">The list</a>
|
||||||
<a href="/method.html">Method</a>
|
<a href="/method.html">Method</a>
|
||||||
|
<a href="/badges.html">Badge</a>
|
||||||
<a href="/oath.html">The Oath</a>
|
<a href="/oath.html">The Oath</a>
|
||||||
<a href="/game.html">Game</a>
|
<a href="/game.html">Game</a>
|
||||||
<a href="https://forge.binaryranch.com/bunkhouse/bigtech-sucks">Source</a>
|
<a href="https://forge.binaryranch.com/bunkhouse/bigtech-sucks">Source</a>
|
||||||
|
|
@ -356,17 +357,100 @@ rated next. If you leave a contact we will tell you when it ships.</p>
|
||||||
return page('The software rating list — BigTech.sucks', body);
|
return page('The software rating list — BigTech.sucks', body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------ badges
|
||||||
|
// A badge is not a sticker. It is a live reference to our record.
|
||||||
|
// It is served from our domain, so a self-issued copy is not a badge and the
|
||||||
|
// link will not resolve. It is regenerated on every build, so a vendor who
|
||||||
|
// improves earns a better badge without asking, and a vendor who regresses
|
||||||
|
// loses it without warning.
|
||||||
|
function renderBadgeSvg(p, a) {
|
||||||
|
const score = String(a.weighted_total);
|
||||||
|
const grade = String(a.grade);
|
||||||
|
const date = String(a.assessed_on);
|
||||||
|
return `<svg xmlns="http://www.w3.org/2000/svg" width="260" height="56" viewBox="0 0 260 56" role="img" aria-label="bigtech.sucks rating: ${esc(score)} out of 100, grade ${esc(grade)}, assessed ${esc(date)}">
|
||||||
|
<!-- record: ${esc(a.id)} | ${esc(a.version)} | method ${esc(a.method_version)} -->
|
||||||
|
<rect x="0.5" y="0.5" width="259" height="55" rx="5" fill="#0d0f0e" stroke="#2a2d2a"/>
|
||||||
|
<text x="14" y="23" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="10" letter-spacing="1.6" fill="#8a8272">BIGTECH.SUCKS</text>
|
||||||
|
<text x="14" y="39" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="8.5" letter-spacing="0.6" fill="#5f5a50">RATED ${esc(date)}</text>
|
||||||
|
<line x1="150" y1="12" x2="150" y2="44" stroke="#2a2d2a"/>
|
||||||
|
<text x="246" y="33" text-anchor="end" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="23" fill="#d9a441">${esc(score)}</text>
|
||||||
|
<text x="246" y="45" text-anchor="end" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="8.5" letter-spacing="1.2" fill="#8a8272">GRADE ${esc(grade)}</text>
|
||||||
|
</svg>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderBadges() {
|
||||||
|
const rated = cat.products
|
||||||
|
.filter((p) => p.weighted_total !== null)
|
||||||
|
.sort((a, b) => b.weighted_total - a.weighted_total);
|
||||||
|
|
||||||
|
const examples = rated.map((p) => {
|
||||||
|
const a = cat.assessments.find((x) => x.product_id === p.id);
|
||||||
|
return `
|
||||||
|
<div style="margin:1.5rem 0;padding:1rem;border:1px solid var(--rule);background:#111413">
|
||||||
|
<div style="display:flex;align-items:center;gap:1.25rem;flex-wrap:wrap">
|
||||||
|
<img src="/badge/${esc(p.id)}.svg" width="260" height="56" alt="${esc(p.name)} rating">
|
||||||
|
<div>
|
||||||
|
<div style="font-size:.9rem">${esc(p.name)} · <strong>${p.weighted_total}</strong> · grade ${esc(p.grade)}</div>
|
||||||
|
<div class="tier">assessed ${esc(a?.assessed_on ?? '')} · weakest: ${esc(p.weakest_dimension ?? '')}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<pre style="margin:1rem 0 0"><a href="https://bigtech.sucks/report/${esc(p.id)}.html">
|
||||||
|
<img src="https://bigtech.sucks/badge/${esc(p.id)}.svg"
|
||||||
|
width="260" height="56"
|
||||||
|
alt="${esc(p.name)}: bigtech.sucks rating ${p.weighted_total}/100">
|
||||||
|
</a></pre>
|
||||||
|
</div>`;
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
const body = `
|
||||||
|
<h1>The rating badge</h1>
|
||||||
|
<p class="sub">Put it in your footer. It is not a sticker, and that is the point.</p>
|
||||||
|
|
||||||
|
<p class="lede">If you have been rated by us, you may display the badge. It is served from our
|
||||||
|
domain and regenerated from the database, so it is not a picture you copy. It is a live reference
|
||||||
|
to a record you do not control.</p>
|
||||||
|
|
||||||
|
<h2>How it works</h2>
|
||||||
|
<table>
|
||||||
|
<tr><th>The badge is</th><th>Which means</th></tr>
|
||||||
|
<tr><td>Served from <code>bigtech.sucks</code></td><td>A copy pasted onto your own server is not a badge and its link will not resolve.</td></tr>
|
||||||
|
<tr><td>Generated from the record</td><td>The score and date are not typed by anyone. They come out of the database.</td></tr>
|
||||||
|
<tr><td>Regenerated every build</td><td>Improve and your badge improves without asking. Regress and it regresses without warning.</td></tr>
|
||||||
|
<tr><td>Linked to the report</td><td>Anyone who clicks it lands on your evidence trail, not a marketing page.</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>The rules, published plainly</h2>
|
||||||
|
<p class="note">Only a rated product may display a badge. There is no badge for an unrated product,
|
||||||
|
and we will not issue one as a favour. If a badge is used on a product that is not rated, or is
|
||||||
|
altered to show a score we did not publish, we will say so publicly.</p>
|
||||||
|
<p class="note">A badge is free. It always will be. It is marketing for you and it is receipts
|
||||||
|
for your customer, and charging for it would make it worthless to both.</p>
|
||||||
|
|
||||||
|
<h2>Available badges</h2>
|
||||||
|
${examples || '<p class="note">Nothing rated yet, so no badges exist. That is the correct state.</p>'}
|
||||||
|
|
||||||
|
<h2>Why you would want this</h2>
|
||||||
|
<p class="note">Because every competitor who cannot show one is leaving a question on the table.
|
||||||
|
A privacy claim in your own copy is a claim. A badge that links to a re-runnable audit is evidence,
|
||||||
|
and it costs you nothing but the honesty of being measured.</p>`;
|
||||||
|
|
||||||
|
return page('The rating badge — BigTech.sucks', body);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------ write
|
// ------------------------------------------------------------------ write
|
||||||
mkdirSync(join(PUB, 'report'), { recursive: true });
|
mkdirSync(join(PUB, 'report'), { recursive: true });
|
||||||
|
mkdirSync(join(PUB, 'badge'), { recursive: true });
|
||||||
|
|
||||||
let written = 0;
|
let written = 0;
|
||||||
for (const a of cat.assessments) {
|
for (const a of cat.assessments) {
|
||||||
const product = cat.products.find((p) => p.id === a.product_id);
|
const product = cat.products.find((p) => p.id === a.product_id);
|
||||||
if (!product) continue;
|
if (!product) continue;
|
||||||
writeFileSync(join(PUB, 'report', `${a.product_id}.html`), renderReport(a));
|
writeFileSync(join(PUB, 'report', `${a.product_id}.html`), renderReport(a));
|
||||||
|
writeFileSync(join(PUB, 'badge', `${a.product_id}.svg`), renderBadgeSvg(product, a));
|
||||||
written++;
|
written++;
|
||||||
}
|
}
|
||||||
|
writeFileSync(join(PUB, 'badges.html'), renderBadges());
|
||||||
writeFileSync(join(PUB, 'method.html'), renderMethod());
|
writeFileSync(join(PUB, 'method.html'), renderMethod());
|
||||||
writeFileSync(join(PUB, 'index.html'), renderList());
|
writeFileSync(join(PUB, 'index.html'), renderList());
|
||||||
|
|
||||||
console.log(`rendered ${written} report page(s) + the list (index.html) + method.html into packages/web/public/`);
|
console.log(`rendered ${written} report(s) + ${written} badge(s) + list + method + badges page into packages/web/public/`);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"generated_at": "2026-10-29T22:21:27.412Z",
|
"generated_at": "2026-10-29T22:24:16.522Z",
|
||||||
"method_version": "btr-0.1",
|
"method_version": "btr-0.1",
|
||||||
"dimensions": [
|
"dimensions": [
|
||||||
{
|
{
|
||||||
|
|
@ -3159,7 +3159,7 @@
|
||||||
],
|
],
|
||||||
"evidence": [
|
"evidence": [
|
||||||
{
|
{
|
||||||
"id": 66,
|
"id": 77,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "local_data_exposure",
|
"dimension_id": "local_data_exposure",
|
||||||
"claim": "Attachments are stored unencrypted on the filesystem; the SQLCipher key is held by the OS keyring.",
|
"claim": "Attachments are stored unencrypted on the filesystem; the SQLCipher key is held by the OS keyring.",
|
||||||
|
|
@ -3170,7 +3170,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 67,
|
"id": 78,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "telemetry_egress",
|
"dimension_id": "telemetry_egress",
|
||||||
"claim": "Electron media permission defaults to false and audio is denied unless the user has enabled mediaPermissions.",
|
"claim": "Electron media permission defaults to false and audio is denied unless the user has enabled mediaPermissions.",
|
||||||
|
|
@ -3181,7 +3181,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 68,
|
"id": 79,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "telemetry_egress",
|
"dimension_id": "telemetry_egress",
|
||||||
"claim": "Zero analytics, tracker or crash-upload dependencies across 224 packages.",
|
"claim": "Zero analytics, tracker or crash-upload dependencies across 224 packages.",
|
||||||
|
|
@ -3192,7 +3192,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 69,
|
"id": 80,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "telemetry_egress",
|
"dimension_id": "telemetry_egress",
|
||||||
"claim": "Only two audio capture call sites exist and both are reachable only from an explicit UI action.",
|
"claim": "Only two audio capture call sites exist and both are reachable only from an explicit UI action.",
|
||||||
|
|
@ -3203,7 +3203,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 70,
|
"id": 81,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "verifiability",
|
"dimension_id": "verifiability",
|
||||||
"claim": "Signal states reproducible builds for macOS and Windows are not available, and the Linux build is experimental.",
|
"claim": "Signal states reproducible builds for macOS and Windows are not available, and the Linux build is experimental.",
|
||||||
|
|
@ -3214,7 +3214,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 71,
|
"id": 82,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "server_retention",
|
"dimension_id": "server_retention",
|
||||||
"claim": "Grand jury subpoena response returned two timestamps and nothing else.",
|
"claim": "Grand jury subpoena response returned two timestamps and nothing else.",
|
||||||
|
|
@ -3225,7 +3225,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 72,
|
"id": 83,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "ownership_jurisdiction",
|
"dimension_id": "ownership_jurisdiction",
|
||||||
"claim": "Signal Technology Foundation is a 501(c)(3) with EIN 82-4506840.",
|
"claim": "Signal Technology Foundation is a 501(c)(3) with EIN 82-4506840.",
|
||||||
|
|
@ -3236,7 +3236,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 73,
|
"id": 84,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "incident_record",
|
"dimension_id": "incident_record",
|
||||||
"claim": "FBI and CISA PSA260626: Russian intelligence compromised individual Signal accounts via phishing and Backup Recovery Key theft, but NOT the encryption or the application itself.",
|
"claim": "FBI and CISA PSA260626: Russian intelligence compromised individual Signal accounts via phishing and Backup Recovery Key theft, but NOT the encryption or the application itself.",
|
||||||
|
|
@ -3247,7 +3247,7 @@
|
||||||
"observed_at": "2026-10-29T15:26:00-05:00"
|
"observed_at": "2026-10-29T15:26:00-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 74,
|
"id": 85,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "incident_record",
|
"dimension_id": "incident_record",
|
||||||
"claim": "Signal statement, 28 April 2026: \"Signal was not hacked, in that our encryption, infrastructure, and the integrity of the app code was not compromised.\" Additional linkage confirmations shipped 13 May 2026.",
|
"claim": "Signal statement, 28 April 2026: \"Signal was not hacked, in that our encryption, infrastructure, and the integrity of the app code was not compromised.\" Additional linkage confirmations shipped 13 May 2026.",
|
||||||
|
|
@ -3258,7 +3258,7 @@
|
||||||
"observed_at": "2026-10-29T15:26:00-05:00"
|
"observed_at": "2026-10-29T15:26:00-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 75,
|
"id": 86,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "ownership_jurisdiction",
|
"dimension_id": "ownership_jurisdiction",
|
||||||
"claim": "Open Technology Fund funded Open Whisper Systems $2,955,000 across 2013 to 2016, itemised on OTF own project page. This is the factual core under the \"US government funded Signal\" claim, and it is already reflected in the two points docked on this dimension.",
|
"claim": "Open Technology Fund funded Open Whisper Systems $2,955,000 across 2013 to 2016, itemised on OTF own project page. This is the factual core under the \"US government funded Signal\" claim, and it is already reflected in the two points docked on this dimension.",
|
||||||
|
|
@ -3269,7 +3269,7 @@
|
||||||
"observed_at": "2026-10-29T15:26:00-05:00"
|
"observed_at": "2026-10-29T15:26:00-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 76,
|
"id": 87,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "user_control_exit",
|
"dimension_id": "user_control_exit",
|
||||||
"claim": "Signal publicly committed to leaving the UK (2023, Online Safety Act) and Sweden (Feb 2025) rather than weaken encryption. A vendor that threatens to lose a market is behaving incompatibly with a secret backdoor.",
|
"claim": "Signal publicly committed to leaving the UK (2023, Online Safety Act) and Sweden (Feb 2025) rather than weaken encryption. A vendor that threatens to lose a market is behaving incompatibly with a secret backdoor.",
|
||||||
|
|
@ -3282,7 +3282,7 @@
|
||||||
],
|
],
|
||||||
"findings": [
|
"findings": [
|
||||||
{
|
{
|
||||||
"id": 29,
|
"id": 33,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"severity": "high",
|
"severity": "high",
|
||||||
"title": "Received attachments are stored unencrypted on disk",
|
"title": "Received attachments are stored unencrypted on disk",
|
||||||
|
|
@ -3291,7 +3291,7 @@
|
||||||
"cve": "CVE-2023-24069"
|
"cve": "CVE-2023-24069"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 30,
|
"id": 34,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"severity": "medium",
|
"severity": "medium",
|
||||||
"title": "No verified reproducible build for the Linux package",
|
"title": "No verified reproducible build for the Linux package",
|
||||||
|
|
@ -3300,7 +3300,7 @@
|
||||||
"cve": null
|
"cve": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 31,
|
"id": 35,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"severity": "medium",
|
"severity": "medium",
|
||||||
"title": "Local database key is held in the OS keyring",
|
"title": "Local database key is held in the OS keyring",
|
||||||
|
|
@ -3309,7 +3309,7 @@
|
||||||
"cve": null
|
"cve": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 32,
|
"id": 36,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"severity": "low",
|
"severity": "low",
|
||||||
"title": "Registration requires a phone number",
|
"title": "Registration requires a phone number",
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ export interface CatalogDimension {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const catalog = {
|
export const catalog = {
|
||||||
"generated_at": "2026-10-29T22:21:27.412Z",
|
"generated_at": "2026-10-29T22:24:16.522Z",
|
||||||
"method_version": "btr-0.1",
|
"method_version": "btr-0.1",
|
||||||
"dimensions": [
|
"dimensions": [
|
||||||
{
|
{
|
||||||
|
|
@ -3199,7 +3199,7 @@ export const catalog = {
|
||||||
],
|
],
|
||||||
"evidence": [
|
"evidence": [
|
||||||
{
|
{
|
||||||
"id": 66,
|
"id": 77,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "local_data_exposure",
|
"dimension_id": "local_data_exposure",
|
||||||
"claim": "Attachments are stored unencrypted on the filesystem; the SQLCipher key is held by the OS keyring.",
|
"claim": "Attachments are stored unencrypted on the filesystem; the SQLCipher key is held by the OS keyring.",
|
||||||
|
|
@ -3210,7 +3210,7 @@ export const catalog = {
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 67,
|
"id": 78,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "telemetry_egress",
|
"dimension_id": "telemetry_egress",
|
||||||
"claim": "Electron media permission defaults to false and audio is denied unless the user has enabled mediaPermissions.",
|
"claim": "Electron media permission defaults to false and audio is denied unless the user has enabled mediaPermissions.",
|
||||||
|
|
@ -3221,7 +3221,7 @@ export const catalog = {
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 68,
|
"id": 79,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "telemetry_egress",
|
"dimension_id": "telemetry_egress",
|
||||||
"claim": "Zero analytics, tracker or crash-upload dependencies across 224 packages.",
|
"claim": "Zero analytics, tracker or crash-upload dependencies across 224 packages.",
|
||||||
|
|
@ -3232,7 +3232,7 @@ export const catalog = {
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 69,
|
"id": 80,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "telemetry_egress",
|
"dimension_id": "telemetry_egress",
|
||||||
"claim": "Only two audio capture call sites exist and both are reachable only from an explicit UI action.",
|
"claim": "Only two audio capture call sites exist and both are reachable only from an explicit UI action.",
|
||||||
|
|
@ -3243,7 +3243,7 @@ export const catalog = {
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 70,
|
"id": 81,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "verifiability",
|
"dimension_id": "verifiability",
|
||||||
"claim": "Signal states reproducible builds for macOS and Windows are not available, and the Linux build is experimental.",
|
"claim": "Signal states reproducible builds for macOS and Windows are not available, and the Linux build is experimental.",
|
||||||
|
|
@ -3254,7 +3254,7 @@ export const catalog = {
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 71,
|
"id": 82,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "server_retention",
|
"dimension_id": "server_retention",
|
||||||
"claim": "Grand jury subpoena response returned two timestamps and nothing else.",
|
"claim": "Grand jury subpoena response returned two timestamps and nothing else.",
|
||||||
|
|
@ -3265,7 +3265,7 @@ export const catalog = {
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 72,
|
"id": 83,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "ownership_jurisdiction",
|
"dimension_id": "ownership_jurisdiction",
|
||||||
"claim": "Signal Technology Foundation is a 501(c)(3) with EIN 82-4506840.",
|
"claim": "Signal Technology Foundation is a 501(c)(3) with EIN 82-4506840.",
|
||||||
|
|
@ -3276,7 +3276,7 @@ export const catalog = {
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 73,
|
"id": 84,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "incident_record",
|
"dimension_id": "incident_record",
|
||||||
"claim": "FBI and CISA PSA260626: Russian intelligence compromised individual Signal accounts via phishing and Backup Recovery Key theft, but NOT the encryption or the application itself.",
|
"claim": "FBI and CISA PSA260626: Russian intelligence compromised individual Signal accounts via phishing and Backup Recovery Key theft, but NOT the encryption or the application itself.",
|
||||||
|
|
@ -3287,7 +3287,7 @@ export const catalog = {
|
||||||
"observed_at": "2026-10-29T15:26:00-05:00"
|
"observed_at": "2026-10-29T15:26:00-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 74,
|
"id": 85,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "incident_record",
|
"dimension_id": "incident_record",
|
||||||
"claim": "Signal statement, 28 April 2026: \"Signal was not hacked, in that our encryption, infrastructure, and the integrity of the app code was not compromised.\" Additional linkage confirmations shipped 13 May 2026.",
|
"claim": "Signal statement, 28 April 2026: \"Signal was not hacked, in that our encryption, infrastructure, and the integrity of the app code was not compromised.\" Additional linkage confirmations shipped 13 May 2026.",
|
||||||
|
|
@ -3298,7 +3298,7 @@ export const catalog = {
|
||||||
"observed_at": "2026-10-29T15:26:00-05:00"
|
"observed_at": "2026-10-29T15:26:00-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 75,
|
"id": 86,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "ownership_jurisdiction",
|
"dimension_id": "ownership_jurisdiction",
|
||||||
"claim": "Open Technology Fund funded Open Whisper Systems $2,955,000 across 2013 to 2016, itemised on OTF own project page. This is the factual core under the \"US government funded Signal\" claim, and it is already reflected in the two points docked on this dimension.",
|
"claim": "Open Technology Fund funded Open Whisper Systems $2,955,000 across 2013 to 2016, itemised on OTF own project page. This is the factual core under the \"US government funded Signal\" claim, and it is already reflected in the two points docked on this dimension.",
|
||||||
|
|
@ -3309,7 +3309,7 @@ export const catalog = {
|
||||||
"observed_at": "2026-10-29T15:26:00-05:00"
|
"observed_at": "2026-10-29T15:26:00-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 76,
|
"id": 87,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "user_control_exit",
|
"dimension_id": "user_control_exit",
|
||||||
"claim": "Signal publicly committed to leaving the UK (2023, Online Safety Act) and Sweden (Feb 2025) rather than weaken encryption. A vendor that threatens to lose a market is behaving incompatibly with a secret backdoor.",
|
"claim": "Signal publicly committed to leaving the UK (2023, Online Safety Act) and Sweden (Feb 2025) rather than weaken encryption. A vendor that threatens to lose a market is behaving incompatibly with a secret backdoor.",
|
||||||
|
|
@ -3322,7 +3322,7 @@ export const catalog = {
|
||||||
],
|
],
|
||||||
"findings": [
|
"findings": [
|
||||||
{
|
{
|
||||||
"id": 29,
|
"id": 33,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"severity": "high",
|
"severity": "high",
|
||||||
"title": "Received attachments are stored unencrypted on disk",
|
"title": "Received attachments are stored unencrypted on disk",
|
||||||
|
|
@ -3331,7 +3331,7 @@ export const catalog = {
|
||||||
"cve": "CVE-2023-24069"
|
"cve": "CVE-2023-24069"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 30,
|
"id": 34,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"severity": "medium",
|
"severity": "medium",
|
||||||
"title": "No verified reproducible build for the Linux package",
|
"title": "No verified reproducible build for the Linux package",
|
||||||
|
|
@ -3340,7 +3340,7 @@ export const catalog = {
|
||||||
"cve": null
|
"cve": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 31,
|
"id": 35,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"severity": "medium",
|
"severity": "medium",
|
||||||
"title": "Local database key is held in the OS keyring",
|
"title": "Local database key is held in the OS keyring",
|
||||||
|
|
@ -3349,7 +3349,7 @@ export const catalog = {
|
||||||
"cve": null
|
"cve": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 32,
|
"id": 36,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"severity": "low",
|
"severity": "low",
|
||||||
"title": "Registration requires a phone number",
|
"title": "Registration requires a phone number",
|
||||||
|
|
|
||||||
9
packages/web/public/badge/signal-desktop.svg
Normal file
9
packages/web/public/badge/signal-desktop.svg
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="260" height="56" viewBox="0 0 260 56" role="img" aria-label="bigtech.sucks rating: 76.4 out of 100, grade B, assessed 2026-10-29">
|
||||||
|
<!-- record: A-2026-10-29-SIGNAL-DESKTOP | 8.36.0-alpha.1 | method btr-0.1 -->
|
||||||
|
<rect x="0.5" y="0.5" width="259" height="55" rx="5" fill="#0d0f0e" stroke="#2a2d2a"/>
|
||||||
|
<text x="14" y="23" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="10" letter-spacing="1.6" fill="#8a8272">BIGTECH.SUCKS</text>
|
||||||
|
<text x="14" y="39" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="8.5" letter-spacing="0.6" fill="#5f5a50">RATED 2026-10-29</text>
|
||||||
|
<line x1="150" y1="12" x2="150" y2="44" stroke="#2a2d2a"/>
|
||||||
|
<text x="246" y="33" text-anchor="end" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="23" fill="#d9a441">76.4</text>
|
||||||
|
<text x="246" y="45" text-anchor="end" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="8.5" letter-spacing="1.2" fill="#8a8272">GRADE B</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1 KiB |
99
packages/web/public/badges.html
Normal file
99
packages/web/public/badges.html
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en"><head><meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
|
<title>The rating badge — BigTech.sucks</title>
|
||||||
|
<style>
|
||||||
|
:root{--ink:#0d0f0e;--bone:#e8e2d4;--dim:#8a8272;--amber:#d9a441;--good:#7fae7a;--bad:#c9563f;--rule:#2a2d2a}
|
||||||
|
*{box-sizing:border-box}
|
||||||
|
body{margin:0;padding:3rem 1.25rem 7rem;background:var(--ink);color:var(--bone);
|
||||||
|
font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;font-size:15px;line-height:1.7;
|
||||||
|
-webkit-font-smoothing:antialiased}
|
||||||
|
.wrap{max-width:58rem;margin:0 auto}
|
||||||
|
nav{font-size:.72rem;letter-spacing:.18em;text-transform:uppercase;color:var(--dim);margin-bottom:3rem;display:flex;gap:1.5rem;flex-wrap:wrap}
|
||||||
|
nav a{color:var(--dim);text-decoration:none;border-bottom:1px solid transparent}
|
||||||
|
nav a:hover{color:var(--amber);border-bottom-color:var(--amber)}
|
||||||
|
h1{font-size:clamp(1.3rem,3.6vw,2.1rem);font-weight:400;line-height:1.2;margin:0 0 .6rem;letter-spacing:-.01em}
|
||||||
|
h2{font-size:.78rem;letter-spacing:.22em;text-transform:uppercase;color:var(--dim);font-weight:400;
|
||||||
|
margin:3.5rem 0 1rem;padding-bottom:.5rem;border-bottom:1px solid var(--rule)}
|
||||||
|
.sub{color:var(--dim);font-size:.85rem;margin:0 0 2.5rem}
|
||||||
|
.score{display:flex;align-items:baseline;gap:1rem;flex-wrap:wrap;margin:0 0 .5rem}
|
||||||
|
.score .n{font-size:clamp(2.6rem,9vw,4.4rem);line-height:1;color:var(--amber);letter-spacing:-.03em}
|
||||||
|
.score .g{font-size:1rem;color:var(--dim);letter-spacing:.2em}
|
||||||
|
.lede{font-size:1.02rem;margin:1.5rem 0 0;padding-left:1rem;border-left:2px solid var(--amber);color:var(--bone)}
|
||||||
|
table{width:100%;border-collapse:collapse;font-size:.84rem;margin:0}
|
||||||
|
th{text-align:left;color:var(--dim);font-weight:400;font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;
|
||||||
|
padding:.5rem .6rem;border-bottom:1px solid var(--rule)}
|
||||||
|
td{padding:.55rem .6rem;border-bottom:1px solid #1b1e1b;vertical-align:top}
|
||||||
|
td.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
|
||||||
|
.bar{display:inline-block;height:7px;background:var(--amber);vertical-align:middle;border-radius:1px}
|
||||||
|
.bar.low{background:var(--bad)}
|
||||||
|
.weak td{background:rgba(201,86,63,.07)}
|
||||||
|
tr.cathead td{background:#151815;color:var(--dim);font-size:.7rem;letter-spacing:.18em;
|
||||||
|
text-transform:uppercase;padding:.9rem .6rem .45rem;border-bottom:1px solid var(--rule)}
|
||||||
|
.sev{font-size:.66rem;letter-spacing:.12em;text-transform:uppercase;padding:.1rem .4rem;border:1px solid var(--rule)}
|
||||||
|
.sev.high{border-color:var(--bad);color:var(--bad)}
|
||||||
|
.sev.medium{border-color:var(--amber);color:var(--amber)}
|
||||||
|
.sev.low,.sev.info{color:var(--dim)}
|
||||||
|
.tier{color:var(--dim);font-size:.72rem}
|
||||||
|
a{color:var(--amber);text-decoration:none;border-bottom:1px solid rgba(217,164,65,.35)}
|
||||||
|
a:hover{border-bottom-color:var(--amber)}
|
||||||
|
.note{color:var(--dim);font-size:.8rem;line-height:1.65;margin:1rem 0 0}
|
||||||
|
pre{overflow-x:auto;background:#111413;border:1px solid var(--rule);padding:1rem;font-size:.76rem;line-height:1.5;color:var(--bone)}
|
||||||
|
code{font-size:.86em;color:var(--bone)}
|
||||||
|
footer{margin-top:5rem;padding-top:1.5rem;border-top:1px solid var(--rule);color:var(--dim);font-size:.75rem}
|
||||||
|
</style></head>
|
||||||
|
<body><div class="wrap"><nav>
|
||||||
|
<a href="/">The list</a>
|
||||||
|
<a href="/method.html">Method</a>
|
||||||
|
<a href="/badges.html">Badge</a>
|
||||||
|
<a href="/oath.html">The Oath</a>
|
||||||
|
<a href="/game.html">Game</a>
|
||||||
|
<a href="https://forge.binaryranch.com/bunkhouse/bigtech-sucks">Source</a>
|
||||||
|
</nav>
|
||||||
|
<h1>The rating badge</h1>
|
||||||
|
<p class="sub">Put it in your footer. It is not a sticker, and that is the point.</p>
|
||||||
|
|
||||||
|
<p class="lede">If you have been rated by us, you may display the badge. It is served from our
|
||||||
|
domain and regenerated from the database, so it is not a picture you copy. It is a live reference
|
||||||
|
to a record you do not control.</p>
|
||||||
|
|
||||||
|
<h2>How it works</h2>
|
||||||
|
<table>
|
||||||
|
<tr><th>The badge is</th><th>Which means</th></tr>
|
||||||
|
<tr><td>Served from <code>bigtech.sucks</code></td><td>A copy pasted onto your own server is not a badge and its link will not resolve.</td></tr>
|
||||||
|
<tr><td>Generated from the record</td><td>The score and date are not typed by anyone. They come out of the database.</td></tr>
|
||||||
|
<tr><td>Regenerated every build</td><td>Improve and your badge improves without asking. Regress and it regresses without warning.</td></tr>
|
||||||
|
<tr><td>Linked to the report</td><td>Anyone who clicks it lands on your evidence trail, not a marketing page.</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>The rules, published plainly</h2>
|
||||||
|
<p class="note">Only a rated product may display a badge. There is no badge for an unrated product,
|
||||||
|
and we will not issue one as a favour. If a badge is used on a product that is not rated, or is
|
||||||
|
altered to show a score we did not publish, we will say so publicly.</p>
|
||||||
|
<p class="note">A badge is free. It always will be. It is marketing for you and it is receipts
|
||||||
|
for your customer, and charging for it would make it worthless to both.</p>
|
||||||
|
|
||||||
|
<h2>Available badges</h2>
|
||||||
|
|
||||||
|
<div style="margin:1.5rem 0;padding:1rem;border:1px solid var(--rule);background:#111413">
|
||||||
|
<div style="display:flex;align-items:center;gap:1.25rem;flex-wrap:wrap">
|
||||||
|
<img src="/badge/signal-desktop.svg" width="260" height="56" alt="Signal Desktop rating">
|
||||||
|
<div>
|
||||||
|
<div style="font-size:.9rem">Signal Desktop · <strong>76.4</strong> · grade B</div>
|
||||||
|
<div class="tier">assessed 2026-10-29 · weakest: local_data_exposure</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<pre style="margin:1rem 0 0"><a href="https://bigtech.sucks/report/signal-desktop.html">
|
||||||
|
<img src="https://bigtech.sucks/badge/signal-desktop.svg"
|
||||||
|
width="260" height="56"
|
||||||
|
alt="Signal Desktop: bigtech.sucks rating 76.4/100">
|
||||||
|
</a></pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Why you would want this</h2>
|
||||||
|
<p class="note">Because every competitor who cannot show one is leaving a question on the table.
|
||||||
|
A privacy claim in your own copy is a claim. A badge that links to a re-runnable audit is evidence,
|
||||||
|
and it costs you nothing but the honesty of being measured.</p>
|
||||||
|
<footer>Generated from <code>bigtech.db</code> on 2026-10-29.
|
||||||
|
Method btr-0.1. Every number recomputes from its evidence or the build fails.</footer>
|
||||||
|
</div></body></html>
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"generated_at": "2026-10-29T22:21:27.412Z",
|
"generated_at": "2026-10-29T22:24:16.522Z",
|
||||||
"method_version": "btr-0.1",
|
"method_version": "btr-0.1",
|
||||||
"dimensions": [
|
"dimensions": [
|
||||||
{
|
{
|
||||||
|
|
@ -3159,7 +3159,7 @@
|
||||||
],
|
],
|
||||||
"evidence": [
|
"evidence": [
|
||||||
{
|
{
|
||||||
"id": 66,
|
"id": 77,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "local_data_exposure",
|
"dimension_id": "local_data_exposure",
|
||||||
"claim": "Attachments are stored unencrypted on the filesystem; the SQLCipher key is held by the OS keyring.",
|
"claim": "Attachments are stored unencrypted on the filesystem; the SQLCipher key is held by the OS keyring.",
|
||||||
|
|
@ -3170,7 +3170,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 67,
|
"id": 78,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "telemetry_egress",
|
"dimension_id": "telemetry_egress",
|
||||||
"claim": "Electron media permission defaults to false and audio is denied unless the user has enabled mediaPermissions.",
|
"claim": "Electron media permission defaults to false and audio is denied unless the user has enabled mediaPermissions.",
|
||||||
|
|
@ -3181,7 +3181,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 68,
|
"id": 79,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "telemetry_egress",
|
"dimension_id": "telemetry_egress",
|
||||||
"claim": "Zero analytics, tracker or crash-upload dependencies across 224 packages.",
|
"claim": "Zero analytics, tracker or crash-upload dependencies across 224 packages.",
|
||||||
|
|
@ -3192,7 +3192,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 69,
|
"id": 80,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "telemetry_egress",
|
"dimension_id": "telemetry_egress",
|
||||||
"claim": "Only two audio capture call sites exist and both are reachable only from an explicit UI action.",
|
"claim": "Only two audio capture call sites exist and both are reachable only from an explicit UI action.",
|
||||||
|
|
@ -3203,7 +3203,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 70,
|
"id": 81,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "verifiability",
|
"dimension_id": "verifiability",
|
||||||
"claim": "Signal states reproducible builds for macOS and Windows are not available, and the Linux build is experimental.",
|
"claim": "Signal states reproducible builds for macOS and Windows are not available, and the Linux build is experimental.",
|
||||||
|
|
@ -3214,7 +3214,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 71,
|
"id": 82,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "server_retention",
|
"dimension_id": "server_retention",
|
||||||
"claim": "Grand jury subpoena response returned two timestamps and nothing else.",
|
"claim": "Grand jury subpoena response returned two timestamps and nothing else.",
|
||||||
|
|
@ -3225,7 +3225,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 72,
|
"id": 83,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "ownership_jurisdiction",
|
"dimension_id": "ownership_jurisdiction",
|
||||||
"claim": "Signal Technology Foundation is a 501(c)(3) with EIN 82-4506840.",
|
"claim": "Signal Technology Foundation is a 501(c)(3) with EIN 82-4506840.",
|
||||||
|
|
@ -3236,7 +3236,7 @@
|
||||||
"observed_at": "2026-10-29T13:13:56-05:00"
|
"observed_at": "2026-10-29T13:13:56-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 73,
|
"id": 84,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "incident_record",
|
"dimension_id": "incident_record",
|
||||||
"claim": "FBI and CISA PSA260626: Russian intelligence compromised individual Signal accounts via phishing and Backup Recovery Key theft, but NOT the encryption or the application itself.",
|
"claim": "FBI and CISA PSA260626: Russian intelligence compromised individual Signal accounts via phishing and Backup Recovery Key theft, but NOT the encryption or the application itself.",
|
||||||
|
|
@ -3247,7 +3247,7 @@
|
||||||
"observed_at": "2026-10-29T15:26:00-05:00"
|
"observed_at": "2026-10-29T15:26:00-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 74,
|
"id": 85,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "incident_record",
|
"dimension_id": "incident_record",
|
||||||
"claim": "Signal statement, 28 April 2026: \"Signal was not hacked, in that our encryption, infrastructure, and the integrity of the app code was not compromised.\" Additional linkage confirmations shipped 13 May 2026.",
|
"claim": "Signal statement, 28 April 2026: \"Signal was not hacked, in that our encryption, infrastructure, and the integrity of the app code was not compromised.\" Additional linkage confirmations shipped 13 May 2026.",
|
||||||
|
|
@ -3258,7 +3258,7 @@
|
||||||
"observed_at": "2026-10-29T15:26:00-05:00"
|
"observed_at": "2026-10-29T15:26:00-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 75,
|
"id": 86,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "ownership_jurisdiction",
|
"dimension_id": "ownership_jurisdiction",
|
||||||
"claim": "Open Technology Fund funded Open Whisper Systems $2,955,000 across 2013 to 2016, itemised on OTF own project page. This is the factual core under the \"US government funded Signal\" claim, and it is already reflected in the two points docked on this dimension.",
|
"claim": "Open Technology Fund funded Open Whisper Systems $2,955,000 across 2013 to 2016, itemised on OTF own project page. This is the factual core under the \"US government funded Signal\" claim, and it is already reflected in the two points docked on this dimension.",
|
||||||
|
|
@ -3269,7 +3269,7 @@
|
||||||
"observed_at": "2026-10-29T15:26:00-05:00"
|
"observed_at": "2026-10-29T15:26:00-05:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 76,
|
"id": 87,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"dimension_id": "user_control_exit",
|
"dimension_id": "user_control_exit",
|
||||||
"claim": "Signal publicly committed to leaving the UK (2023, Online Safety Act) and Sweden (Feb 2025) rather than weaken encryption. A vendor that threatens to lose a market is behaving incompatibly with a secret backdoor.",
|
"claim": "Signal publicly committed to leaving the UK (2023, Online Safety Act) and Sweden (Feb 2025) rather than weaken encryption. A vendor that threatens to lose a market is behaving incompatibly with a secret backdoor.",
|
||||||
|
|
@ -3282,7 +3282,7 @@
|
||||||
],
|
],
|
||||||
"findings": [
|
"findings": [
|
||||||
{
|
{
|
||||||
"id": 29,
|
"id": 33,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"severity": "high",
|
"severity": "high",
|
||||||
"title": "Received attachments are stored unencrypted on disk",
|
"title": "Received attachments are stored unencrypted on disk",
|
||||||
|
|
@ -3291,7 +3291,7 @@
|
||||||
"cve": "CVE-2023-24069"
|
"cve": "CVE-2023-24069"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 30,
|
"id": 34,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"severity": "medium",
|
"severity": "medium",
|
||||||
"title": "No verified reproducible build for the Linux package",
|
"title": "No verified reproducible build for the Linux package",
|
||||||
|
|
@ -3300,7 +3300,7 @@
|
||||||
"cve": null
|
"cve": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 31,
|
"id": 35,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"severity": "medium",
|
"severity": "medium",
|
||||||
"title": "Local database key is held in the OS keyring",
|
"title": "Local database key is held in the OS keyring",
|
||||||
|
|
@ -3309,7 +3309,7 @@
|
||||||
"cve": null
|
"cve": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": 32,
|
"id": 36,
|
||||||
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
"assessment_id": "A-2026-10-29-SIGNAL-DESKTOP",
|
||||||
"severity": "low",
|
"severity": "low",
|
||||||
"title": "Registration requires a phone number",
|
"title": "Registration requires a phone number",
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ footer{margin-top:5rem;padding-top:1.5rem;border-top:1px solid var(--rule);color
|
||||||
<body><div class="wrap"><nav>
|
<body><div class="wrap"><nav>
|
||||||
<a href="/">The list</a>
|
<a href="/">The list</a>
|
||||||
<a href="/method.html">Method</a>
|
<a href="/method.html">Method</a>
|
||||||
|
<a href="/badges.html">Badge</a>
|
||||||
<a href="/oath.html">The Oath</a>
|
<a href="/oath.html">The Oath</a>
|
||||||
<a href="/game.html">Game</a>
|
<a href="/game.html">Game</a>
|
||||||
<a href="https://forge.binaryranch.com/bunkhouse/bigtech-sucks">Source</a>
|
<a href="https://forge.binaryranch.com/bunkhouse/bigtech-sucks">Source</a>
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ footer{margin-top:5rem;padding-top:1.5rem;border-top:1px solid var(--rule);color
|
||||||
<body><div class="wrap"><nav>
|
<body><div class="wrap"><nav>
|
||||||
<a href="/">The list</a>
|
<a href="/">The list</a>
|
||||||
<a href="/method.html">Method</a>
|
<a href="/method.html">Method</a>
|
||||||
|
<a href="/badges.html">Badge</a>
|
||||||
<a href="/oath.html">The Oath</a>
|
<a href="/oath.html">The Oath</a>
|
||||||
<a href="/game.html">Game</a>
|
<a href="/game.html">Game</a>
|
||||||
<a href="https://forge.binaryranch.com/bunkhouse/bigtech-sucks">Source</a>
|
<a href="https://forge.binaryranch.com/bunkhouse/bigtech-sucks">Source</a>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"digest": "26267b38b11900741b6933e21ae8a604a6545f754198f80cc74ccf54a478148a",
|
"digest": "c71ec40b3fcf45f2ab25bea80b0f2d21745463f86ed5ca15d6347cfb1a5f1fcc",
|
||||||
"algorithm": "sha256",
|
"algorithm": "sha256",
|
||||||
"file": "catalog.json",
|
"file": "catalog.json",
|
||||||
"byte_length": 91034,
|
"byte_length": 91034,
|
||||||
"rebuilt_at": "2026-10-29T22:21:27.417Z",
|
"rebuilt_at": "2026-10-29T22:24:16.527Z",
|
||||||
"method_version": "btr-0.1",
|
"method_version": "btr-0.1",
|
||||||
"products": 137,
|
"products": 137,
|
||||||
"assessed": 1
|
"assessed": 1
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ footer{margin-top:5rem;padding-top:1.5rem;border-top:1px solid var(--rule);color
|
||||||
<body><div class="wrap"><nav>
|
<body><div class="wrap"><nav>
|
||||||
<a href="/">The list</a>
|
<a href="/">The list</a>
|
||||||
<a href="/method.html">Method</a>
|
<a href="/method.html">Method</a>
|
||||||
|
<a href="/badges.html">Badge</a>
|
||||||
<a href="/oath.html">The Oath</a>
|
<a href="/oath.html">The Oath</a>
|
||||||
<a href="/game.html">Game</a>
|
<a href="/game.html">Game</a>
|
||||||
<a href="https://forge.binaryranch.com/bunkhouse/bigtech-sucks">Source</a>
|
<a href="https://forge.binaryranch.com/bunkhouse/bigtech-sucks">Source</a>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue