Back to the blog
Security

Attackers Pulled Data on 8.8 Million People From Denmark's National Register With One Customer's Legal Access. The Invoice Caught It.

October 7, 2026 6 min read

On Monday, October 5, Denmark's Ministry of Research, Education and Digitalisation (Forsknings-, Uddannelses- og Digitaliseringsministeriet) announced that unauthorized people had obtained names, addresses, CPR numbers and other data ("navne, adresser, CPR-numre mv.") on about 8.8 million people registered in the Central Person Register (Det Centrale Personregister). The CPR number is Denmark's national identification number. It is used for taxes, healthcare, banking and, in a lot of offices, as proof that you are who you say you are.

That last use is the part builders should care about.

What happened

The attackers did not break into the register. They misused the lawful access of a small private Danish company that is allowed to look people up in the CPR, and the ministry says they stayed within what private companies may see. Section 38 of the CPR Act lists it: current name and address with the moving date, occupation, marketing and credit-warning flags, death, disappearance, emigration, contact address and guardianship. People with name and address protection were not affected.

The harvest ran for about ten days in September. At a briefing on Tuesday, Mikkel Leihardt, head of department (afdelingschef) at the ministry, said there had been "godt over 14 millioner" (well over 14 million) attempted CPR lookups and 8.8 million returns, TV 2 reported. Divided over the "about ten days" the minister gave TV 2, that is 1.4 million lookups a day, about 16 per second around the clock (14 million / 10 days / 86,400 seconds), from one small customer.

Nobody noticed in September. The CPR administration became aware on the evening of Friday, October 2, during invoicing: every lookup is billed, and the amount was, in Leihardt's words, "very, very large." DR reported that neither automatic alarms nor spot checks caught it. Jacob Herbst, who chairs Denmark's Cybersecurity Council, told DR that was "quite shocking."

The company's access was cut. Datatilsynet, the Danish Data Protection Agency, received the notification on Sunday. The National Unit for Special Crime (NSK) says it secured evidence at the company on Saturday evening, is in contact with foreign police, and has charged no one.

Why 8.8 million in a country of 6 million

Denmark had 6,032,304 residents on August 1, 2026, according to Statistics Denmark (StatBank table FOLK1AM, "Population at the first day of the month"). The CPR holds about 11 million records because it keeps people who have died or moved abroad, and the ministry states that the 8.8 million cover the living, the emigrated and the dead. Roughly four in five records in the register came back.

The gap between 14 million attempts and 8.8 million returns has an official explanation: you can look up CPR numbers that do not exist. A CPR number is a six-digit date of birth followed by a four-digit sequence. I would not read too much into that yet, but a space that small and that structured can be walked.

The design flaw is older than the breach

A CPR number was never a secret. The Confederation of Danish Industry (DI) said it plainly this week: the number sits on the health card, on payslips and in countless customer files, and many businesses still use it like a password. DI draws the line every product spec should draw. Identification is who a person claims to be, and the CPR number is still fine for that. Authentication is proof that the claim is true, and "name, address and CPR number no longer meet that requirement for the vast majority of Danes."

The authorities now say the same. On October 6, the Danish Resilience Agency (SAMSIK) asked authorities and companies to stop releasing sensitive information on the basis of CPR data alone. Its director, Laila Reenberg, said on Tuesday that you cannot use the number to authorize things. Danish pharmacies announced that saying your CPR number will normally no longer be enough to collect medicine.

And a national ID number cannot be rotated at scale. The CPR office issues a new number for errors or in special cases of identity misuse. The minister, Christina Egelund, said on Monday it was too early to say whether anyone would get one. A leaked password gets reset in an afternoon. A leaked national ID stays leaked.

Never use these as a secret

The rule: an identifier goes in the username column, never in the secret column.

National ID numbers are the obvious case. Company identifiers are the one French builders forget: INSEE has published the Sirene database free to everyone since January 2017. A B2B onboarding that accepts "your SIREN and your work email" as proof that someone represents a company is the CPR mistake at small scale.

Email addresses, phone numbers, dates of birth and postal addresses belong in the same bucket. Receiving a code at an address registered earlier is a factor. Knowing the address is nothing.

What changes for authentication and KYC

Most KYC flows check a name, an ID number and an address against a register. After this week, a perfect match proves that the person exists. It does not prove that the person typing is that person, because a perfect match is now exactly what a fraudster can produce for 8.8 million people.

SAMSIK's replacements are not exotic: an eID login (MitID in Denmark), a one-time code to a phone or email already on file, questions rooted in the relationship such as the last invoice number, a callback on the number you already have, in-person ID for financial changes, and manual review or a waiting period when money is involved. The government site sikkerdigital.dk lists the flows that need them: access to personal data, contact detail changes, new subscriptions, credit purchases, new SIM cards, password resets and payment changes.

DI adds the one I would put first: the IT helpdesk. Your own employees' CPR numbers are very likely in the haul. A helpdesk that resets a password or a second factor because the caller knows a name and a CPR number is an open door.

The GDPR clock starts when you notice

Article 33 of the GDPR gives a controller 72 hours from becoming aware of a breach to notify the authority. Friday evening to Sunday fits. Article 34 says that when a breach is likely to result in a high risk, the controller shall communicate it to the people affected without undue delay, and that where this would involve disproportionate effort, there shall instead be a public communication. At this scale, that is the only realistic route. Denmark went public on Monday morning. Asked why that took more than two days, Leihardt said they first had to stop the access and bring in the right authorities.

On paper, the timeline holds. But the clock starts at awareness, and here awareness came from a billing run, days after the data had left. A deadline measured from detection does nothing for the time before it. Your monitoring sets the real deadline.

What I would do on Monday

If you serve lookups to other systems (a data API, a B2B integration, an MCP server that exposes records to agents), put a per-credential baseline on volume and on misses. A client with valid keys that suddenly makes 16 calls a second, a third of them returning nothing, should page someone within the hour, not surface on a monthly invoice.

If you run a support desk or a reset flow, list every place where knowing an identifier unlocks an action, and replace it with something the attacker did not get.

And collect less. If you do not need the national ID number, do not store it. DI and Dansk Erhverv agree: the fewer places it lives, the less there is to lose.

I build a LegalTech product where client documents are worth far more than the accounts that open them, and the rule I hold there is the one Denmark is now applying to a whole country: nothing a stranger can look up is allowed to open anything. The numbers are out and will stay out. The flows that trusted them are what has to change.

Sources

A project like this one?

I design and deploy products like this. Let's talk.

Let's talk