What's new

When two siblings share a PIN by accident

A parent got in touch to say the PIN in Achievabee "appears to be shared" between their two children. It was worth checking properly, because if PINs were shared then every kid in a household could open every other kid's account.

They were not shared. Every layer of the app was already per-child: each kid has their own PIN, stored separately, checked against their own record. Nothing was pooling them.

The two children had simply chosen the same number.

Why that is still a problem

The app cannot tell the difference between "these two PINs happen to match" and "these two children share a PIN". Neither can the children.

On the device picker, both kids see both tiles. If they know a number that works, they can tap the other child's tile, type it, and be inside their sibling's account looking at their points and their rewards.

Nothing was broken. The app had just never said the numbers should differ, so in two out of two families they did not.

That second part is the bit I keep thinking about. It was not one family being careless. It was every family we could measure, because the app asked a parent to pick a number twice and gave no reason to pick differently. A default that produces the same wrong outcome for everyone is a design fault, not user error.

What happens now

Duplicates are still possible, and that is deliberate. A parent with two young children might genuinely want one number both can remember, and the app should not lecture them about it.

So the two paths differ:

  • A parent setting a PIN that matches a sibling's is told, and can go ahead anyway.
  • A child changing their own PIN cannot pick one a sibling is using. They are asked for a different number, without being told whose it matched.

The asymmetry is the whole point. A duplicate should be a decision a parent made, never something a kid arranged.

The part that surprised me

The obvious fix is a database rule saying two children in a household cannot have the same PIN. That does not work here, for a reason that is a good thing.

PINs are not stored. What is stored is a scrambled version, and the scrambling deliberately includes a random ingredient that differs for every child. So the same PIN, entered for two children, produces two completely different stored values.

That is exactly what you want: someone reading the database directly cannot tell which children share a number, and cannot work out the number itself. It also means the database cannot spot the duplicate either, and the check has to be done deliberately, by testing a candidate against each sibling in turn.

A property that makes the data safer made the bug harder to catch. That felt worth writing down rather than quietly working around.