Report privately through GitHub, from the repository's Security tab: Report a vulnerability. That opens a private advisory visible only to you and the maintainer. Please do not open a public issue: PlayGuard guards a child's play time, and a way around it is useful to exactly the people it is meant to hold back from the moment it is readable.
Expect an acknowledgement within a few days. A confirmed report is fixed in a new release, and the advisory is published once that release is out.
Include, if you can: the firmware and Atmosphère versions, the PlayGuard version, what a person gains, and the smallest sequence of steps that shows it.
The latest release. Fixes are not backported.
- The PIN — the PIN reaching a log, the diagnostic report, a backup, an export or the change history; or PlayGuard's own ask for the PIN prompt being skipped from the console itself (without editing the SD card).
- Unsafe writes — the play timer written while it counts down, a setting changed while read-only mode is on, or a write on a firmware PlayGuard has not been checked against unless every feature at your own risk was chosen on the firmware screen.
- The recovery sysmodule — acting without a
RESCUErequest file, acting twice on one request, or doing more than the request asks. - The agent sysmodule — carrying out an order under a policy other than auto, a
write while
nro_state.txtsays read-only or on a firmware PlayGuard has not run on, an order PlayGuard declined being applied anyway, or thepg:agentservice letting a process other than PlayGuard change what the agent publishes or does beyond what an order on the broker could. - Optional modules — PlayGuard installing, updating, starting or removing a sysmodule without the PIN while Protect PlayGuard with the PIN is set to Before a change, or installing anything but the copy it carries (checked against its SHA-256).
- The update check and releases — anything that makes PlayGuard trust a
compat.jsonor a download that did not come from this repository's releases, or, in developer mode (Install another build), from this repository's own CI builds ofmainand of pull requests from its branches (pull requests from forks are never offered); or another build installed, or the previous one put back (at start-up too), without the PIN when one is set. - The recovery screen — reaching its actions (set a new PIN, delete everything) from a
rescue_report.txtthe console's state does not confirm, or, after an unlock, from one without the recovery sysmodule's proof for the current challenge (rescue_nonce, an HMAC keyed with the stored PIN and a secret of the console: seesysmodule/rescue/README.md), or without the recovery sysmodule installed; or the PIN found back from a copy of PlayGuard's files on the card (a report's proof included) without the console. - The forwarder gate — a forwarder protected with the PIN starting its homebrew from the HOME menu without the PIN: outside its hours without the PIN, during its hours it never opens, past a day's play time used up (Closed once today's play time is used up), or while it pauses after refused PINs; including by changing the console clock in System Settings (free hours are honoured only while the network clock vouches for the console clock, and a pause also runs on the steady clock).
- The forwarder rules — the rules of a forwarder made by this PlayGuard changed from the
SD card: they are in its RomFS on the console's storage, and the gate it starts is pinned
by its SHA-256 (
config/playguard/gate-<hash>.nro), so free hours added in a file, or another.nroput in place of the gate, must not take effect. - The homebrew menu's lock — while it is locked, the homebrew menu opened from the
console itself (the album, a game started with R held) without going through a forwarder
protected with the PIN, or the lock lifted at boot by anything but a
RESCUErequest or an Atmosphère update. - The remote link (MQTT, Home Assistant) — an order doing more than its entity allows (any order that deletes parental controls, unlinks the companion app or reads or changes the PIN, a play-timer write while Orders may change the play timer is off, a write in read-only mode, the play timer written while it counts down); an order carried out without the console's confirmation under the ask policy; the broker's password, user name or address reaching a log, the diagnostic report or an upload; a malformed message from the broker crashing PlayGuard.
- Physical access to the SD card, but for the forwarder rules above. Whoever can edit
the card can already turn off PlayGuard's own PIN prompt in
config.json, install the recovery sysmodule, or remove parental controls with any pctl tool; and, for the forwarders, delete the homebrew menu's lock (atmosphere/config/override_config.ini, by design a way back, or itsconfig/playguard/hbmenu_lock.txt), edit the pause after refusals and the log of tries (config/playguard/gate_pause.txt,gate_log.txt) or the files a forwarder made by an earlier PlayGuard reads its hours from, or replace the homebrew a forwarder starts. On a console running custom firmware, any homebrew can also read the stored PIN from the system (pctl:acommand 1208): PlayGuard keeps a child out of PlayGuard, not out of every homebrew. Seesysmodule/rescue/README.md. - Custom firmware itself. PlayGuard needs Atmosphère; a modded console can run any homebrew, including ones that change parental controls.
- Whoever can publish to the broker. With the remote link on, the broker's users are
trusted to send orders (that is what the link is for): securing the broker and the local
network, and keeping Orders may change the play timer off when it is not needed, is the
owner's part. See
docs/home-assistant.md. - Nintendo's parental controls. Behaviour of the system
pctlservice or the phone app belongs with Nintendo. PlayGuard is not affiliated with Nintendo.