Background
In 2020, the UK Labour Party procured a voting platform called Anonyvoter without tender, without audit, without any of the security controls that would be considered basic for a system determining who gets to run the country.
The platform was built by a small IT business in Croydon — Henson IT Solutions — where the author was working as an apprentice under Mark Henson's direction. Maddie Henson, Mark's wife, was a Labour Councillor. David Evans, newly appointed Labour General Secretary, procured Anonyvoter from them, and was first publicly reported on around September 2020. Concerns were raised immediately regarding the accuracy of candidate selections conducted using the platform.
The analysis began in March 2026 when the author returned to the Anonyvoter codebase and examined it systematically for security and integrity risks.
Full technical paper: Security Assessment of the Anonyvoter Voting Platform: Source Code Analysis and Formal Verification
The System
Anonyvoter is an ASP.NET Web Forms application with SQL Server backend. It had no audit logging, no encryption at rest, and every sensitive value stored as plaintext. The vendor controlled all infrastructure: hosting, database, email, domain. There was no separation of duties. There was no independent oversight.
The system was designed to allow vote manipulation:
- ●Voter weights* — The vendor could set
fldVoterWeightin the database to make a single vote count as multiple votes, with no visible indication to organisers or participants - ●Phantom voters* — Attacker-controlled email addresses could be added to distribution groups, receiving legitimate ballot links that produce indistinguishable votes
- ●Voter suppression* — Targeted voters could be removed from the voter list before or during a poll, with no audit record
- ●Ballot code exposure* — The organiser dashboard displayed every voter's ballot code in real time, allowing votes to be cast on behalf of non-voting members
- ●Poll restart* — All cast votes could be deleted and the poll restarted with a replacement voter list, leaving no trace of the original state
- ●No logging* — None of these actions were logged, rate-limited, or visible to participants
Critical Vulnerabilities
Plaintext Password Fallback
CheckPassword() compares the stored value against the plaintext input before checking the hash. Anyone with direct write access to the password field can insert a known plaintext string for a target account. On the next login attempt, authentication succeeds permanently, with no indication to the account holder. Combined with the vendor's database access, this grants silent login access to any organiser account.
No Brute-Force Protection
The login page has no rate limiting, no account lockout, no CAPTCHA, and no failed-attempt counter. Unlimited password guesses can be submitted against any account without throttling or detection.
Open Redirect on Login
The redirect query parameter is accepted without validation. A voter receiving a link with a malicious redirect URL will authenticate on a genuine page and be silently forwarded to an attacker-controlled site.
No CSRF Protection
No anti-forgery token is issued or validated on any page. The ballot-wipe-and-reissue flow executes on a plain HTTP GET request — an attacker embedding an <img> tag on a page the organiser visits can trigger a full poll reset in the background. Every existing vote is wiped, the distribution list is re-read, and new ballot codes are dispatched to whoever is currently in the voter list.
Broken Password Hashing
SHA-256 output is cast from binary bytes to ASCII, collapsing all bytes with values 128-255 to ?. No salt. Non-standard encoding that cannot be verified by any tool. The net result is a hash function with substantially less entropy than the raw password.
Test Mode Redirects All Email to Vendor
When the live application setting is "N", every outgoing email — including ballot links for real voters — is redirected to the vendor's personal address. If this setting is left as "N" in production, or changed by whoever controls the server, the vendor receives all ballot codes for every active poll.
Modulo Bias in Ballot Code Generation
GetNonZeroBytes excludes zero, producing values 1-255 rather than 0-256. Against a 62-character alphabet, the first 7 characters (a through g) are approximately 25% more likely per position than the remainder.
Fire-and-Forget Email Dispatch
Ballot emails are dispatched in a Task.Run with an empty catch block. No dead-letter queue, no automatic retry, no exponential backoff, and no alerting. A voter whose ballot email is silently dropped has no visible recourse and no way to know that a ballot was issued to them.
Structural Deficiencies
God Class
Utils.cs contains 15 classes in a single file of approximately 4,900 lines, handling authentication, password hashing, random code generation, email dispatch, database operations, poll lifecycle management, voter list management, PDF generation, and Stripe billing. There is no separation of concerns and no unit testability.
Single Vendor Controls All Infrastructure
Henson IT Solutions controls application hosting, SQL Server database, AWS SES sending account, and the domain. The vendor has database admin access. No contractual audit rights, independent oversight, or separation of duties exists.
No Audit Logging
No server-side log records changes to the voter list, poll start/stop/cancel events, candidate list modifications during a live poll, results CSV downloads, or individual ballot code accesses.
Live Poll Modification Without Version Control
The organiser can modify the poll title, candidate list, vote type, and other parameters while the poll is in progress. There is no version lock, no change log, no voter notification.
Per-Voter Data Visible During Live Poll
The organiser dashboard displays in real-time each voter's email address, whether they have voted, their ballot code, and whether they were added after the poll started.
No Encryption at Rest
No field-level or database-level encryption exists for any data. Ballot tokens, observer access tokens, cast vote choices, pre-vote voter identity links, full voter rolls, and organiser credentials — all stored as plaintext SQL columns.
Attack Scenarios
Phantom Voter Injection
The attacker adds attacker-controlled email addresses to the distribution group. Those addresses receive legitimate ballot emails. The attacker votes using those ballot links. The ballot is indistinguishable from a legitimate vote in the results.
Voter Suppression
Targeted voters are removed from the distribution group before the poll starts. The voter list editor treats the submitted list as authoritative — any address absent from the new submission is deleted. Those voters are never emailed and cannot vote.
Email-Swap Revote
The organiser replaces the voter list while a poll is running, then re-triggers the poll-start URL. Every existing ballot record is deleted — including votes already cast — and new ballot codes are generated for the replacement addresses. No audit record remains.
Clean Voter Swap via NYS/CAN Intermediate State
This variant achieves the same outcome with no visible signal at any point. The complete operation requires four requests with an active organiser session. This sequence was executed against a locally deployed instance of Anonyvoter on 4 May 2026 and confirmed reproducible.
Vote Re-identification
The platform's vote anonymisation mechanism is reversible by anyone with database access. Full de-anonymisation of every vote is achievable via a single SQL query.
Documented Incidents
Ilford South, October 2022
Sam Tarry, the sitting Labour MP, was deselected following a selection using Anonyvoter. Tarry reported winning 57% of in-person votes while receiving only 35% of Anonyvoter votes — a 22 percentage-point discrepancy. No factor has been identified that would account for a differential of this magnitude.
Tarry filed an official complaint with the Labour Party alleging vote rigging and threatened legal action, stating: "What's gone on in Ilford South, and allegedly in other selections too, is unlike anything I have seen in 20 years in the Labour Party." The Labour Party stated it had full confidence in the integrity of the selection and declined to investigate.
Merthyr Tydfil and Upper Cynon, 2023
Beth Winter, the sitting Labour MP, was deselected in favour of another sitting Labour MP, Gerald Jones. Winter reported winning most in-person and postal votes before Anonyvoter was applied, and pressed the Welsh Labour executive for an independent inquiry.
Hamilton and Clyde Valley, July 2024
The selection of Imogen Walker (wife of Morgan McSweeney, founder of Labour Together) as the Labour candidate for the new constituency of Hamilton and Clyde Valley represents the most direct organisational connection to the platform's procurement chain. Walker narrowly won against local contender Gavin Keatt by 62 votes to 55, with reports indicating Keatt won the hustings but Walker took the nomination "by winning decisively with online votes."
Croydon East, 2023–2026
The 2023 parliamentary candidate selection for Croydon East resulted in a Metropolitan Police cyber crime investigation after evidence emerged that the constituency's membership database had been tampered with: 71 members had their home address changed, 26 had their phone number changed, and 40 had been assigned new email addresses.
In April 2026, four individuals were charged with conspiracy and with offences contrary to the Computer Misuse Act 1990. Mark Henson, co-creator of Anonyvoter, was serving as interim treasurer of the Croydon East CLP at the time.
Risk by Access Level
Organiser-level access (available through the web application):
- ●Add phantom voters or remove targeted members
- ●Cast votes on behalf of non-participating members
- ●Modify candidates or poll title mid-poll
- ●Retain access indefinitely: no brute-force protection, no bound on session reuse
- ●None of these actions are logged, rate-limited, or visible to participants
Vendor and database-level access (requires direct SQL or server access):
- ●Set voter weights to make any vote count as multiple votes
- ●Redirect all ballot emails to the vendor
- ●Access any organiser account via plaintext password injection
This disclosure is published under the Public Interest Disclosure Act 1998.
Related: The UKRIO Deception: How Westminster Enabled Palantir Approvals on the Public's Behalf