Legal
Security
Last updated 1 October 2026. Describes theToddle Enhancement Extension, version0.8.2. For schools, and for the privacy, legal and IT colleagues who review software on their behalf.
At a glance
- Runs on
- web.toddleapp.com only. No access to any other site.
- Permissions
- storage, and Toddle's own site. Nothing else.
- Reads
- Toddle, through an exact list of read-only queries, for the teacher at the screen, with what that teacher's account can already see.
- Writes
- Nothing. Write operations are refused outright.
- Sends
- Nothing it reads, to anyone but Toddle. Two outside connections, neither carrying Toddle data: feedback, when a person presses Send; and, while a licence is entered, a daily download of a signed list of cancelled keys.
- Stores
- Settings and a licence key, on the device. No student data.
- Tested
- Closed-loop tests, a regression test for every review finding, and an end-to-end run that records every request and attempts page-script attacks. Every release is gated on them.
- Reviewed
- Independent adversarial review, 1 October 2026. Every finding fixed in 0.8.2.
To report a vulnerability, emailsecurity@nyuchi.com with the subject "Security". We acknowledge within 3 working days.
The security model
The extension is a closed loop: it reads Toddle, for the teacher at the screen, and puts what it reads back on that same screen. Each of the following is a statement about how the software is built, and each is held in place by a test.
It runs only on Toddle
The extension is declared against https://web.toddleapp.com and nothing else. It has no access to any other website, and takes no action anywhere else.
Two permissions
It asks Chrome for storage, to keep its settings, and for Toddle's own site. Nothing more: no access to tabs, history, downloads or other sites, no pages that websites can reach or frame, no connection from outside websites, and no loosening of Chrome's own content security policy for extensions.
Its background worker opens the welcome page once, on install; opens the licence page when the extension's own toolbar asks, accepting that request only from the extension itself; and, while a licence is entered, makes the daily check for cancelled keys described below.
Read-only, by an exact list
Every query the extension may send to Toddle is written out, word for word, in one file. The channel that sends them refuses anything that is not on that list exactly, with variables of the expected shape, and sends only to Toddle's own API, checked again immediately before each request. None of the queries writes, and any write is refused, so the extension cannot change a gradebook, a record or a setting even by accident.
It reuses the session the teacher is already signed in with, so Toddle answers with what that teacher's account may already see, and no more. It never sees a password. Its message buttons open Toddle's own chat window, on real clicks only; the extension sends no message itself, and Toddle's chat applies the school's messaging rules.
Nothing it reads leaves, and two outside connections
There is no account, no analytics, no telemetry, no tracking, no advertising and no remote code. What the extension reads from Toddle goes back to Toddle's own screen and nowhere else. It makes two connections outside Toddle, and neither carries anything from Toddle:
- Feedback. The Send feedback form in the toolbar menu sends only when a person presses Send, carrying only what they typed (a topic, a message, an email address if they give one) and the extension's version number, to Nyuchi's feedback form, processed by Formspree. Nothing that runs inside a Toddle page refers to it. See theprivacy policy.
- A daily check for cancelled keys. Once a day, only while a licence is entered, the background worker makes one plain request to
https://licences.nyuchi.dev/v1/revocations. It sends no licence key, no identifiers, no cookies and no Toddle data. It downloads a list, signed by Nyuchi, of the fingerprints (SHA-256 hashes) of cancelled keys, and checks its own key against it locally. Cloudflare sees the IP address, as with any web request; Nyuchi does not log it. If the check fails, the extension keeps working.
Licence keys are checked on the device
A licence key is a signed statement that the extension verifies on the device, against a public key it carries. Licences are tied to their owner: an individual key carries the buyer's email address, and an organisation key the school's email domain. The extension compares that with the Toddle account signed in, inside the browser only. Activating a key contacts nothing, and the key is never sent anywhere. It is kept in the extension's own storage, which Toddle's page cannot reach.
No student data on the device
The extension stores the teacher's switch settings and licence key, plus a few housekeeping values in Toddle's own site storage (a copy of the switches, the academic year Toddle is showing, and a style name). No student data is stored anywhere. What it reads about students, classes and timetables is held in memory for at most a few minutes and is gone when the tab closes. Student flags are hidden by default; the sidebar fetches a student's flags only when someone chooses to show them, and forgets them when it closes. The CSV export is made in the browser and saved where the teacher's downloads go, by the teacher's choice.
Protections inside the page
Part of the extension has to run inside Toddle's page to read the gradebook, which means it shares that page with Toddle's own scripts. It is protected as far as a page allows:
- The sign-in token stays in Toddle's page. The part of the extension that draws its interface cannot read it.
- Its public objects are frozen, so a page script cannot rewrite them.
- Answers to its queries travel on a private channel, never broadcast, so no other script can read them or answer in their place.
- The query gate uses JavaScript built-ins captured before any page script runs, so a page that replaces them cannot widen it.
- Messages that change what is shown, such as licensed features or student flags, carry a secret shared only between the extension's own parts, new on every page load.
- Text read from Toddle is shown as text and never interpreted as markup, and values in the CSV export cannot start a spreadsheet formula.
How it is tested
The guarantees above are not left to good intentions. Every proposed change runs these, and a release cannot be published unless all of them pass.
- Closed-loop tests
- Fail on any new permission or page reachable from websites; anything the background worker does beyond its job; any network or storage side door; any address that is not Toddle's or Nyuchi's; any extra field on the feedback form; any message listener that does not check where a message came from; and any query whose text or variables differ from the list.
- A regression test for every finding
- Every finding from adversarial review has at least one permanent test, each of which fails on the code as it was before the fix, so a fix cannot quietly come undone.
- End to end, with a network recorder
- The built extension is loaded into Chromium and used as a teacher would use it, on stand-in Toddle pages with made-up students. Every request the browser makes is recorded, and the run fails on any that goes outside Toddle. Page-script attacks (forged queries, overheard answers, forged settings, forged flag messages) are attempted, and must fail.
- Every release is gated
- The tests run on every pull request and again in the release itself, which stops before anything is published if either fails.
Independent review, 1 October 2026
On 1 October 2026 the extension had an independent adversarial review, with proofs of concept run against the real extension. It considered a malicious script in Toddle's page, a malicious website in another tab, another extension, and crafted responses from Toddle. It found two high-severity issues, one medium and several low. All of them were fixed in version 0.8.2, and each fix carries a regression test.
HighFixed in 0.8.2
Gradebook text could run script. Rich text read from Toddle (rubric labels, single-point rubric responses, remarks) was cleaned in a way that still let a crafted image tag run script in the teacher's Toddle page.
Fix. Toddle's rich text is read into an inert document, as text, never as markup.
HighFixed in 0.8.2
The CSV export could carry spreadsheet formulas. A value beginning with a formula character was exported as it was, and a spreadsheet would have run it.
Fix. Such values are prefixed so a spreadsheet opens them as plain text.
MediumFixed in 0.8.2
A page script could redirect the extension's queries with the teacher's session. The address the extension sent its queries to could be swapped by another script in the page, so Toddle's sign-in could have reached a foreign host.
Fix. The address is fixed once as a plain string, checked to be Toddle's API, and checked again immediately before every request.
LowFixed in 0.8.2
The query gate relied on JavaScript built-ins a page script could replace, which would have let it accept anything.
Fix. The gate captures what it needs before any page script runs, and checks by hand.
LowFixed in 0.8.2
An email address could add hidden recipients to a mail link.
Fix. A strict address pattern, and every mail link built one way, with the address encoded.
LowFixed in 0.8.2
Answers to the extension's queries were broadcast in the page, where another script could read them or answer first with forged data.
Fix. Each question carries a private channel, and answers travel only on it.
LowFixed in 0.8.2
A page script could plant a class with a fake teacher in the extension's short-lived cache.
Fix. That door was removed.
LowFixed in 0.8.2
A page script could switch on licensed features.
Fix. Only the extension can, with a secret shared once per page load.
LowFixed in 0.8.2
The licence page could be framed or probed by a website.
Fix. No extension page is reachable from websites, and the licence and welcome pages refuse to run in a frame.
InfoFixed in 0.8.2
A look-alike query list defined before the extension's was kept; the gradebook's grid hooks were writable; any page script could ask for hidden flags to be shown.
Fix. A look-alike list shuts the query channel; the grid hooks are private; showing flags needs the per-load secret.
HardeningFixed in 0.8.2
Message buttons could be pressed by a script.
Fix. They act on real clicks only.
The issues were present in released versions from 0.5.0 to 0.8.1, depending on the finding. Only 0.8.2 and later are supported; Chrome updates installed copies from the Chrome Web Store on its own, and a school that pins a version should move to the current one. The review also attempted, and found held: running a query outside the list, or a write; making the extension send to any host but Toddle's; reading the licence key from the page; reaching the feedback form from Toddle's page; and opening an extension page from a website.
We publish what was found, not only that it was fixed, because a school deciding whether to trust software should know.
What no extension can promise
Any script that Toddle itself loads into its pages shares those pages, and the signed-in teacher's access, with or without this extension installed. Toddle's pages are served without a Content-Security-Policy, which would otherwise limit what scripts can run there.
That is a property of Toddle, not of the extension, and nothing an extension does can remove it. What the extension does is make sure it adds nothing such a script could use that it did not already have, and widens no access: it adds no new script sources, does not change Toddle's own security settings, answers only its own fixed list of read-only queries, and sends nothing it reads anywhere but Toddle. A school that wants that risk reduced further should raise it with Toddle.
The flag switch is a privacy aid, not a security control. It hides flags from the screen; it does not hide names, and does not stop anyone deliberately opening a student's profile.
Reporting a vulnerability
Email security@nyuchi.com with the subject "Security". Please include the extension version (in its toolbar menu), what an attacker could do and from where, and the steps or a proof of concept; describe rather than include any real student data. We acknowledge within 3 working days, confirm or rule it out within 10 working days, and fix a critical or high finding within 7 days, a medium within 30, and a low in the next release.
The extension's source repository is private, so the full policy is published here: the vulnerability disclosure policy sets out the scope (this website, the extension and the licence server), what we commit to, and safe harbour for good-faith research. It is also listed insecurity.txt.
Related
- Privacy policy — exactly what the extension reads, stores and sends.
- Data handling andstudent privacy — what Nyuchi holds, who processes it, breach notification and data processing agreements.
- Terms of use and service.
- Deploying to a school— force-install from the Google Admin console by extension ID.
If your data protection officer or IT team has questions this page does not answer, or would like to review the code before approving it, write tosupport@nyuchi.com, or for privacy questions and data processing agreements,privacy@nyuchi.com.