Bug Bounty
Last updated September 17, 2026
Peachy pays for security findings. This page is the whole programme: what is in scope, what we pay, how fast we answer, and what we will not pay for. It sits underneath the vulnerability disclosure policy, which is where the promises about credit and disclosure live.
We run this ourselves. There is no HackerOne, no Bugcrowd and no intermediary — you email a person and a person replies. Send it to support@pchy.app with “security” in the subject line. If you would rather encrypt, say so first and we will exchange a key.
The amounts are small, on purpose. Peachy is one person, with no revenue and no funding. A four-figure top tier is what a company this size can actually pay out of pocket without the programme quietly dying the first time somebody claims it. Read the numbers as a real commitment at a real scale, not as a measure of how seriously we take the finding. The programme opened on 17 September 2026.
Tiers
Critical — $1,000
The account boundary or the cryptographic boundary is gone.
- Remote code execution on the API or the assistant worker, from an unprivileged or unauthenticated position.
- Authentication bypass reaching another account’s messages — a session minted for someone else, a sign-in code flow that signs you in as a number you do not control, a forged token.
- Forging a device credential — a credential our server accepts that our key did not sign.
- Breaking the attestation pin so unverified AI inference is accepted silently. Making the server send a person’s content to an enclave it did not verify, or to a connection whose key is not the attested one, without the call failing closed. The silence is the finding: a failure that refuses the request is the system working as designed.
- A full database read, or credential recovery that yields one.
High — $500
One person’s data reaches another person, without the whole boundary falling.
- Cross-account data read — content, media or profile fields belonging to an account you do not control.
- IDOR on messages, media, devices, sessions or group membership: an identifier you can change to address somebody else’s row.
- Push bodies leaking to a reader who asked for local notifications. If someone has set notification handling to local, the words of their messages must not reach Apple, Google or a browser push service. A path that hands them over anyway is a finding.
- An MLS delivery-service ordering or Welcome-routing violation that lets a non-member receive group traffic — a commit accepted at a stale epoch, a sequence the server reorders or reissues, a Welcome delivered to a device that was never added, key packages fetched for someone you share nothing with, or a removed member who keeps reading the stream.
- Write access to another account’s state — sending as them, deleting their content, changing their handle or their settings.
- Server-side request forgery reaching our internal network or a cloud metadata endpoint.
Medium — $150
Real impact, bounded, or needing a condition you do not control.
- Cross-site scripting in the web app, stored or reflected, running in a signed-in origin.
- CSRF with impact — a state change on behalf of a signed-in reader.
- Rate-limit bypass on the sign-in code: unbounded code requests for a number, unbounded guesses against a code, or anything that makes brute-forcing six digits practical. SMS pumping through our account counts here too.
- Log redaction failures leaking content — message bodies, sign-in codes, tokens or keys reaching our logs, our admin pages, or a third party’s console.
- Session fixation, a token that outlives a revocation, or a sign-out that leaves a usable credential behind on a shared device.
- Bypassing a privacy control the product presents as a control — blocking, profile visibility, message requests.
Low — $50, or swag
Real, reported well, and small.
- Information disclosure that exposes no content: a version banner, a stack trace, an internal hostname, a debug flag, an identifier in a place it did not need to be.
- Best-practice gaps with a plausible but undemonstrated path to impact.
- A fix we should make that nobody is exploiting.
Swag is a Peachy t-shirt and stickers, posted anywhere. You can take the $50 as well as or instead of — tell us which.
How a tier is decided
- At the operator’s discretion, and the decision is final. We will always explain it. A finding between two tiers rounds up if your report did the work of proving impact, and down if we had to.
- One payout per root cause. Five endpoints missing the same authorisation check is one bug. Report all five — it helps the fix — and expect one payment, at the highest impact among them.
- First reporter wins, timestamped by when the email arrived. A duplicate gets our thanks and the credit if they want it, but no money. If two good reports land within an hour of each other, we split rather than argue.
- A chain pays at the tier of the end result, not the sum of its steps.
- We pay in USD by bank transfer, PayPal or Wise, and in EUR or GBP at the day’s rate if you prefer. We will donate to a charity you name instead. We cannot pay anyone we are not lawfully able to pay.
Scope
In scope:
- api.pchy.app — the API: every method, the sign-in and session surface, the health endpoints, the media paths.
- pchy.app — the web app and the marketing site, including /verify, the admin pages and the service worker.
- The apps — Peachy for iPhone, Android and Mac, their extensions (the iOS notification extension included), and what they put on disk.
- The attestation and verification path — how we verify the AI enclave, what we pin, what the apps check for themselves, and what happens when verification fails.
- Device credentials — issuing, verifying and revoking them, and the key stores on each client.
- The MLS delivery service — commit ordering, Welcome routing, the key-package directory and the membership permissions around them. Nothing calls it yet (see below), but the rules are live code and a break in them counts.
- Push-body stripping — anything that puts a message’s words in front of a push service for a reader who asked us not to.
- Our use of providers — content reaching a provider the Privacy Policy does not name, or under terms it does not describe.
Out of scope:
- Tinfoil’s own enclave, its hardware, its models and its dashboard. Our side of that boundary is in scope; theirs is theirs, and they run their own process.
- Render, Cloudflare, Anthropic, Twilio, Apple and Google. Their infrastructure is theirs and each has a programme. Our configuration of them is ours, and is in scope.
- Denial of service, volumetric or algorithmic. Please do not test it. We know a one-person service can be knocked over and we do not need the demonstration.
- Social engineering, phishing or pretexting against the operator, the support inbox, or any provider’s staff.
- Physical access, including anything needing a stolen or seized device, an unlocked screen, or a jailbroken or rooted OS.
- Third-party sites, including any domain we do not own and the sites the app links out to.
- Missing headers, TLS configuration grades, cookie flags, mail hardening and similar best-practice gaps with no demonstrated impact. Report them; they land in Low at best.
- Scanner output with no working reproduction.
- Anything in the known-issues list at the foot of this page.
Safe harbour
If you follow this page, we consider your research authorised, and we will say so in writing to anyone who asks.
- We will not bring, support or join a civil or criminal action against you for research done in good faith under these rules — including under computer-misuse and anti-circumvention law, and including the parts of our Terms that would otherwise forbid it. Those terms are waived for the research, and only for the research.
- If a third party comes after you for something you did inside this scope, tell us and we will make our authorisation clear to them.
- Safe harbour is lost by reading, changing, taking or deleting another person’s content beyond the minimum needed to prove the bug; by extortion or a deadline attached to a payment demand; by testing outside the scope above; and by publishing before the window below has run.
- If a bug lets you reach real people’s data, stop. Take one record’s worth of proof, tell us what you could have taken, and do not take it. “I could have dumped the messages table, and here is the single row I read to prove it” is worth the full tier. Dumping it is not a report.
None of this is legal advice, and we can only waive our own rights.
What counts as a report
A report we can act on has all of:
- A working reproduction — steps, a request, a script or a short video. If it needs an account, make your own; sign-up is a phone number.
- What an attacker gets. “Reads any user’s messages” and “reads any user’s handle” are different findings, and this is the sentence the payout is decided from.
- Where you tested — the live service or a local build.
- The accounts and identifiers you used, so we can find your traffic in the logs and tell it apart from a real attack.
- Whether you want credit, and under what name.
What does not count: a scanner report, a dependency CVE with no path from our code to it, “your site does not set header X”, a screenshot of a theoretical risk, or an AI-written narrative with no reproduction. We read all of them. We pay for none of them.
How fast we answer
Business days, Central European Time.
- Acknowledgement within 3 business days — a human replies and says who is on it.
- Triage within 10 business days — we have reproduced it, or told you why we cannot, and told you the tier we expect to pay.
- A payout decision with triage, or within 5 business days of the fix where the tier depends on what we find.
- Disclosure after 90 days from acknowledgement, or when the fix ships, whichever is first. If we need longer we will explain why.
Fix targets, counted from triage:
- Critical: 7 days. Mitigated immediately even when the real fix is slower — we keep kill switches for the AI provider and for push bodies precisely so there is something to pull.
- High: 30 days.
- Medium: 90 days.
- Low: next time we are in that area, and we will tell you if we do not intend to fix it.
If a target is going to slip we tell you before it slips, not after. Fixes in the apps carry an extra tail: the server ships on every push, but the apps build nightly and then wait on app-store review, so a client-side Critical is “mitigated on the server in 7 days, new binary when Apple lets us”.
Duplicates and known issues
These are documented, deliberate, or known and unfixed. Reporting one of them does not pay — which is not a judgement on the report, it is what “already in the file” means. Please read this before you spend an evening.
The design, not a bug:
- Peachy is not end-to-end encrypted. Messages, group messages and AI chats are stored on our servers in a form our operators can read. It is on the Privacy Policy and on /security. “The server can read messages” is a description of the design, not a vulnerability.
- Message content goes to a model provider — Anthropic, or a Tinfoil enclave for accounts in that cohort — to run triage, search, the For-you lens and the assistant. Both are named in the Privacy Policy. Content going somewhere else is very much a finding.
- Enclave attestation does not prove which enclave served your particular request. It proves the one our server names is genuine and that the connection cannot terminate anywhere else. We say so on /verify.
- The Android app has no in-app enclave verifier. No Android verifier library exists for us to run, so the app shows the server’s evidence and links out. Web, iPhone and Mac verify independently.
- A stripped push still carries the sender’s name and photo, the thread it belongs to, and the fact that a message arrived. Only the words are withheld, deliberately. Push metadata reaching Apple or Google is the design.
- Message text is still in the notification for readers who have not asked otherwise. Stripping is on by default only for people who chose local notification handling, because a stripped push degrades badly on an older client.
- A name from someone else’s address book can be shown to its subject. We prefill a new sign-up’s name from what other people’s contacts call that number. Disclosed in the Privacy Policy.
- Phone-number discovery. Knowing a number tells you whether it is on Peachy, and handles are public by design. This is the WhatsApp model, and we chose it.
- Server logs are kept 14 days and are readable by operators.
- Session tokens are stored hashed. A dump of that table signs nobody in, so “tokens are in the database” is not a finding.
Built but not reachable — do not report it as dead code, and do report a real break in it:
- No client registers a device yet. The device-identity endpoints and key stores run for nobody. A credential-forgery bug is still Critical, because the code is live and the day it is called is the day it matters.
- Device registration refuses when the signing key is unset, rather than generating one at boot. That is deliberate: an ephemeral key would make every credential it signed unverifiable after the next deploy.
- Message bodies are still the authoritative column.The ciphertext columns beside them are written by nothing.
- The MLS tables are empty and no client calls those endpoints. Known gaps inside them, rather than findings: no rate limits or quotas on a group’s stream beyond the per-message size cap; no reconciliation between our membership table and the MLS tree; no push fan-out from a commit; no cross-ciphersuite filtering; nothing post-quantum. A permission break — a non-member reading or writing a group’s stream — is not on this list, and pays at High.
- The MLS protocol engine is a Rust workspace nothing calls. Findings in it are welcome and are tiered on what they would cost once it is wired up, which today is usually Low.
Known, and not being fixed:
- Cosmetic and platform-rendering issues of every kind.
- A jailbroken or rooted device reading the app’s own storage.
- Anything requiring the victim to install a profile, disable a platform protection, or paste something into a console.
If you think one of these is wrong — that a “known” is worse than we think, or that a design note is hiding a real bug — say so and show it. That argument, made well, has its own tier: we will pay Medium for a report that changes our mind about an item on this list.
Thanks
Nobody yet. Be the first.