← Back to all reports

A Connection Request Endpoint That Leaks Student Names and Enables Takeover

Reported Jun 11, 2026
Severity High
Platform Web
Vulnerability Class Insecure Direct Object Reference (CWE-639)
Target Type Education / EdTech
Impact Student name disclosure escalating to account takeover

The Risk

A stranger with a free account could look up any child on the platform by their internal record number and get back the child's real name and their teacher's full name, with no proof they knew the child. The same flaw let the stranger file a "request to connect" to that child, posing as a plausible parent, and the disclosed name made that fake request far more convincing. If a teacher approved it, the stranger gained access to the child's account, including the ability to sign in as the child and obtain a reusable login link that worked from any browser. It needed only a free sign-up that anyone can complete.

The Vulnerability

In the normal product flow, a parent connects to a student only by proving they know the child: a parent code the teacher hands out, or identifying the child's real school, then teacher, then name. A connection-request endpoint bypassed that gate entirely.

Given two raw internal identifiers, a student id and a teacher id, by an authenticated parent who owned nothing and had no relationship to the class, the endpoint returned the target student's name and filed a connection request into that teacher's pending queue. It never checked that the requester knew the child or that the teacher taught the student. The endpoint was therefore both a student-id-to-name oracle and a zero-knowledge connection primitive.

Sign-up was open self-service with no email verification, so the attacker side was a free account. The identifiers were not secret either: a companion flaw in the platform's live event feed handed out real student-and-teacher identifier pairs in bulk to any account.

The Attack

From Identifier to Real Name

A single request to the connection-request endpoint with a harvested student id and the owning teacher id returned a successful response carrying the foreign child's real name and the resolved owning teacher's full name:

POST /api/connection-request
{"studentId":"<harvested>","teacherId":"<harvested>"}

-> 201  {"studentName":"...","teacher":{...}}

Because identifier pairs were harvestable in bulk, this ran at platform scale rather than against a single guessed record. Pointing the request at the attacker's own teacher account instead docked it to the attacker's own queue and emailed no one, while still returning the real foreign student's name, so the pure data leak left no trace.

Injecting the Connection Request

Each filed request landed in the real owning teacher's queue as a normal "wants to join your class" request naming a real student already in their class, indistinguishable from a legitimate parent join. The backend itself flagged the request as carrying no legitimate connection context, yet stored it and surfaced it as a normal join request. Knowing the child's name from the response, the attacker set their own display name to a plausible guardian of that exact child, so the teacher reviewing the request saw a name-consistent parent asking to connect to a real student in their class.

Escalating to Account Takeover

The takeover was gated on one teacher approval, made far more likely by the disclosed name. Once a teacher approved, the attacker parent was durably connected to a child who was not theirs and could take over the account two ways: opening the student selector to sign in as the child in a full student session, and reading the connected-student object for the child's magic-login link, a reusable, long-lived credential that worked from any browser with no login. The takeover chain was demonstrated end to end against researcher-owned accounts so no real user was touched.

The Impact

From a single free, self-registered account, an attacker could turn raw identifiers into real student names at scale (cross-tenant disclosure of school-age children's personal information) and, after one teacher approval, take over any student account on the platform. The leaked login link persisted as a standalone student credential even if the connection was later removed. This combines a children's-privacy and education-records disclosure with a path to full student account takeover against any student in any class.

Remediation

  • Enforce a relationship check on the connection-request endpoint: the requester must prove they know the child (a teacher-issued code or the school-then-teacher-then-name flow) before any request is filed.
  • Do not return the student's name in the response to an unverified requester; the response itself is the disclosure oracle.
  • Reject requests the backend already flags as having no legitimate context instead of surfacing them as normal join requests.
  • Treat the student magic-login link as a sensitive credential: scope it, expire it, and do not expose it to connected-parent objects by default.
  • Fix the companion event-feed leak that supplies the identifier pairs, and add email verification to sign-up.