- A GitHub advisory says a wger trainer with no gym assigned could read private records of other users who also have no gym, because two empty values compare as equal.
- It matters because no gym is the default for new accounts, so the advisory says public-registration instances are affected where trainer permissions are delegated.
- If you run wger, check who holds trainer permissions and which release you run. Any multi-tenant system should test its own no-tenant state.
A security check that compares two unknowns can decide they match. That is the flaw a researcher describes in wger, gym management software. An empty field was treated as a place, and two empty fields were treated as the same place.
The finding is in a GitHub Advisory Database entry, GHSA-c72h-82w6-rqfp, published October 7, 2026. The advisory text does not give a CVE ID. It rates the issue High, with a CVSS score of 7.1.
What the advisory reports
Wger lets gyms keep private records on members. These include admin notes, uploaded documents and contracts. Trainers can read them for members of their own gym.
The advisory says five views check this badly. The bypass needs a narrow starting point. The trainer must hold two permissions, gym.gym_trainer and gym.add_adminusernote. The trainer must also have no gym assigned. Even then, the reach is limited to other users who likewise have no gym.
For those users, the researcher says the trainer can see far more than notes. Exposed items include private admin notes, uploaded documents and gym contracts. Two further views show a user's configuration and permission settings.
The advisory says the notes may hold salary data, medical notes and disciplinary records. Documents may include ID scans and medical forms. Contracts carry financial terms and subscription details.
How one comparison opens the door
The guard is simple. It compares the trainer's gym with the member's gym. If they differ, the server returns a "forbidden" response.
The problem is what happens when both gyms are empty. In Python, None is the value for "nothing here." The advisory notes that None != None evaluates to False. The code reads that as "no difference," so the forbidden response is never sent.
The second step makes it worse. According to the advisory, the code then looks up records using only the member ID taken from the web address. It does not check again that the member belongs to the trainer's gym. An attacker can change that ID and read records one after another.
The researcher also ran a control. An admin in gym 1 asking for a user with no gym got a 403 refusal. So the guard works when the gyms differ. The bypass is specific to the empty case.
Why the default state is the risk
The advisory says an empty gym is the default for new users until someone assigns them manually. It concludes that any wger instance with public registration is affected, provided trainer permissions are delegated to non-admin users.
That is the lesson. The unsafe state is not rare. It is the starting state of every new account. In our view, a rule that fails only in an odd corner case is more likely to be caught in review. A rule that fails in the normal case needs an actual test.
The people who carry the risk are not the trainers. They are members whose notes sit in a system they cannot see into. Such a person, signed up but never assigned to a gym, would have had little way to know their file was readable. That is our reading; the advisory does not address it.
Limits of what is known
This is one researcher's report. The tests ran on the wger/server:latest Docker image with two test users. The advisory says the result reproduced in 2 of 2 runs after a clean database reset.
The advisory says an attacker could potentially change other users' permissions through the permissions view. It says this path was not fully explored.
The advisory links to wger release 2.6. Its text does not say whether that release fixes the issue. Check the project's release notes before relying on it.
What to ask your team
If you run wger, start with three questions. Who holds the trainer and admin-note permissions? How many accounts have no gym assigned? Has anyone confirmed which release you run and what it changes?
If you do not run wger, the question still applies. Any system that separates customers, branches or tenants has a "no tenant" state. Ask your engineers to test it directly: two users with nothing assigned, one trying to read the other.
The advisory suggests one shared helper function for the same-gym check, called from all five views. One check in one place is harder to get wrong five different ways.
A blank value is not an identity. Access rules should treat it as missing, and deny by default.
Produced by the WebPulse Newsroom with AI assistance from the original reporting credited below, and checked against that source by our editorial review. How we use AI.
Original reporting: GitHub Advisory Database.





