Report privately via GitHub Security Advisories.
We read every report and fix what is real, whether or not a reward is attached. There is no fixed response time: a report is acknowledged once it has been read, and how long a fix takes depends on the finding.
Only the latest release published on the
Chrome Web Store
is supported. Releases are tagged vX.Y.Z in this repository; report against the tag of the
version you tested. Fixes ship in a new release rather than as patches to older ones.
Paused August 2026. No new submissions are eligible for a reward until it reopens.
We are receiving a high volume of automated, agent-generated submissions. Most are technically competent and most describe real code — that is not the problem. The problem is that they arrive as security advisories when what they are is patches:
- written against
mainrather than a published release, so a report can describe code that was fixed hours before it was filed; - often restating a limitation we document ourselves, sometimes quoting the very comment that documents it — reading our notes back to us with a severity label attached;
- filed under embargo, where they cannot be discussed in the open or simply merged.
A private advisory costs a maintainer far more than an issue does. It has to be triaged alone, on a clock, in a channel built for coordinated disclosure — and coordinated disclosure is not what most of these need. They need a patch.
So the rules below have not changed much. What has changed is the volume arriving through the wrong door, and the reward is what points at that door.
If your finding is any of the following, open an issue or a pull request. It will be read sooner, discussed in the open, and credited the same:
- a limitation this repository documents in a comment or a header, including the accepted risks below;
- a hardening suggestion, a missing check, or a defence-in-depth improvement;
- anything you could have fixed yourself in the time it took to write it up.
Use the advisory channel when there is a way to take a user's funds or keys, that user-visible outcome is demonstrated, and telling us privately first actually protects someone.
Three things will be true of it:
- A proof of concept against a tagged release. Already the rule; it will be enforced rather
than assumed.
mainis developed in the open and is not the product anyone is running. - A documented limitation needs a demonstrated loss. Citing the comment that describes a gap is not a finding. Show a user losing something.
- Tiered by demonstrated impact. "This guard is skipped here" and "here is BTC leaving the wallet" are not the same report and will not be paid the same.
In scope
- Browser extension code (background, content scripts, popup)
- Key derivation, encryption, and signing logic
- Provider API and dApp connection handling
- Session management and auto-lock
- Transaction construction and verification
Out of scope
- Vulnerabilities in third-party dependencies (report upstream, but let us know)
- Vulnerabilities in Trezor Connect, Trezor Suite, or Trezor firmware: report them to Trezor (trezor.io/security). How this wallet uses them (what it asks the device to sign, and how it checks the result) is in scope
- Attacks requiring physical access to an unlocked device
- Social engineering or phishing attacks
- Denial of service without security impact
- Limitations already documented in the code, in accepted risks, in what the wallet cannot see, or in this file
- Theoretical vulnerabilities without demonstrated impact
- Behaviour already fixed on
mainat the time of the report
These are known and accepted. Each links to the source comment that explains why.
- Secrets in JavaScript memory cannot be reliably cleared. String immutability, garbage collection and JIT copies may retain key material after use; clearing is best effort (sessionManager.ts).
- Keys are not rotated during an unlocked session. Session timeouts bound the exposure instead (sessionManager.ts).
- The master key is held in session storage while unlocked. It is equivalent to the password until the wallet locks, which lets the user switch wallets without re-entering it (walletManager.ts).
- Some compose values come from the ledger, not the request. A reissuance's divisibility and description, and a newly created pool's LP asset, cannot be predicted from the request and are checked only for presence (unpack/verify.ts).
- Trezor Connect brings a large dependency tree. It is accepted for hardware signing and reduced by build-time tree shaking (trezorAdapter.ts).
Critical: Direct loss of funds or private keys. An attacker can steal assets, extract seeds or keys, or get a transaction signed without the user's consent.
High: Significant impact, but requires user interaction or specific conditions — auth bypass, session theft, or transaction manipulation that leads to fund loss with additional steps.
Medium: Limited direct impact. Information disclosure, UI spoofing that could mislead a user, or a bypass of a defence-in-depth measure.
Low / Informational: Best practices, minor issues, hardening. Appreciated, credited, never rewarded — and better sent as a pull request.
- Give us reasonable time to fix before public disclosure (90 days)
- Do not access or modify other users' data
- Do not attack our infrastructure or other users
- One vulnerability per report, unless chained for impact
We recognise valid security contributions regardless of severity, and regardless of which channel they arrived through.
| Contributor | Finding | Reference |
|---|---|---|
| Niftyboss | Password memory cleanup | #178 |
| refangga1337 | Approval summary priced a PSBT without regard to what the signature committed to | GHSA-xm3c-v5fj-mxqv |
| refangga1337 | Attached-asset warning suppressible by padding a PSBT past the lookup cap | GHSA-6mmc-r2hj-qq43 |
| goat | Decode API could override byte-derived output addresses on the PSBT approval screen | #256 |