Home / Docs / SG Meter / Security model

SG Meter · security model

SG Meter's security model: what a reader can do to it, and why that is allowed

Everything the meter knows is in the reader's browser, so the reader controls it completely. This page lists what that lets them do, what it costs the site, and what it costs them. The short version: every way of cheating changes a number only the cheater can see, and costs the site a payment it was never going to get.

What is being protected, and from whom

Not money. The meter never blocks a page, so there is nothing behind it to steal: a reader who never pays reads exactly what a reader who pays reads. What it protects is narrower: the reader's own history (what they read, what they declined and why) from other people, and the site's honesty about what it records. The first question of who are you protecting against applies, and the answer here is "a reader's flatmate, and our own mistakes", not "a determined attacker", because a determined attacker gains nothing. Who might try anyway, and how many of them there are, is in who will game the reading meter.

Known gaps, all accepted

#What a reader can doEffortWhat it costs the siteWhat it costs the reader
1Edit their balance in the browser's developer tools (Application → Local Storage)A minute, for someone who knows devtools existNothing it would otherwise have hadNothing
2Open a private window or another browser and start again at £5.00One keystrokeNothingTheir history and picks, which stay behind
3Open the topped-up page with any session_id and get £5 of credit, once per idRead this page, type a URLNothing: no money moves, and the credit is only on their screenNothing
4Replay the same topped-up URLnoneBlocked: each id is credited once per browser (but a new id is trivial, see 3)none
5Clear site data to wipe a negative balanceTwo clicksNothing; there was never a debtTheir history
6Read as an agent: fetch the markdown twin or the newsroom wireNone; it is the intended route for agentsUnmetered by design, for nownone
7Someone else on a shared computer opens the account or newsroom and sees what was read and declined, and the reader's personasSit down at itnonePrivacy. Mitigations: "Start again" clears it; a private window keeps nothing
8A script injected into the site (XSS) reads the historyNeeds a hole in the site firstReputationPrivacy. Mitigations: the meter sets page data only as text; the only third-party code on this origin is the in-browser Python on the try page, loaded from a pinned version, so that page shares the same storage and the same trust
9Card testing, fraud or chargebacks against the Stripe linkOrdinary payment fraudFees and disputes, held by Stripe's own controls (Radar)none

Why the topped-up page is unprotected

Because protecting it would need a server, and the one thing a server would protect is a number on a reader's own screen that unlocks nothing. Stripe's recommended way to know a payment happened is a webhook from Stripe to a server you run, and the honest alternative to building one is to say plainly that the return page trusts its URL. So it does, and here it is said. What we did do is keep the default route the real one: every top-up button goes to the payment page, the return URL is not linked as a way to get credit, and the page adds nothing when opened without a reference.

What would change this

← SG Meter