Ready Already Readers · Security

Report an exposed book, account, or checkout.

If a private book, image, link, account page, or checkout looks exposed, this is the fastest way to get it in front of a person. The control record below says what is already in place, so you can tell whether what you found is a bug.

Send to
support@readyalready.org
Read by
A person. There is no automated triage queue.
Programme
No bug bounty and no paid disclosure programme.
Record verified
30 July 2026, read back against the shipping code.

01

Send the report

Five things make a report actionable. Nothing here needs an account, and you do not have to know which part of the product is at fault.

  1. Copy the page or file URL and note the time you saw the problem.

  2. Describe what you expected to be private and what appeared instead.

  3. Include the account email address only when the report depends on it.

  4. For a book, send its title. Do not send a child's full legal name, birth date, or any other detail the report does not need.

  5. Never include passwords, full card numbers, or session cookies. They are not needed to reproduce anything, and we do not want them.

02

What happens after you send it

  • The report is written to a durable record before any notification is attempted, so a delayed or failed email cannot lose it.

    Enforced by
    app/api/contact/route.ts stores the submission first and only then makes a time-bounded notification attempt.
  • A person reads it. There is no automated triage queue and no bot deciding whether your report is interesting.

    Enforced by
    Reports arrive in the support@readyalready.org mailbox, which is monitored by hand.
  • If you would rather not use a form, the same details sent directly to the support address are equally welcome.

    Enforced by
    support@readyalready.org

03

Controls in the current product

Read this before reporting. If what you found contradicts one of these lines, that is exactly the report worth sending.

  • A parent or caregiver signs in before reaching a private family library, and the app re-checks account ownership before returning any private book record, image, or file.

    Enforced by
    Route protection in proxy.ts, plus an ownership check inside app/api/images/[...path]/route.ts that returns 401 when the signed-in account does not own the book.
  • No storage URL is ever handed to the browser. Book images and PDFs are streamed through an authenticated route; the product issues no signed and no public storage links.

    Enforced by
    app/api/images/[...path]/route.ts and app/api/download/[...path]/route.ts download server-side and stream the bytes back as private, no-store responses.
    Checked by
    scripts/privacy-export-delete-proof.mjs asserts that no signed-URL call appears in the account data helper, so reintroducing one fails the proof.
  • The book buckets are created private and are forced back to private every time the migration runs, so an accidental flip cannot survive a deploy.

    Enforced by
    supabase/migrations/20260530234217_core_rls_storage_contract.sql sets public = false on insert and again on conflict, for both the image and the PDF bucket.
  • Row-level security is enforced at the database, not only in the app. A book row is readable only by the account that owns it, and a rating additionally has to prove the rated book belongs to the caller.

    Enforced by
    The same migration revokes the anonymous and signed-in roles across these tables and then re-grants narrowly, table by table.
  • Work that needs elevated database access runs only in server-only modules with session persistence disabled, so the elevated key cannot be bundled into anything a browser downloads.

    Enforced by
    utils/supabase/server.ts
  • Payment providers and app stores handle payment details; Ready Already does not store full card numbers.

    Enforced by
    There is no card-number field anywhere in the product's own interface. A web purchase redirects to the provider's hosted checkout, changing a card opens the provider's hosted billing portal, and in the apps the purchase happens in the store's own sheet.
    Checked by
    What the product stores is opaque references: a session identifier, a payment reference, an amount, a currency, and a status.
  • Purchase notifications are authenticated before they are trusted: one endpoint verifies a signature over the raw request body, the other compares a shared secret in constant time.

    Enforced by
    The webhook routes under app/api/webhooks reject an unsigned or mismatched request outright, and processed event identifiers are recorded so a replayed event cannot be applied twice.
  • Rate limits key on the account, the IP address, and the surrounding network block, and fail closed when the limiter backend is unavailable.

    Enforced by
    utils/api-rate-limit.ts
  • The native apps ship a no-tracking privacy manifest — tracking declared false, with an empty tracking-domain list — and suppress web analytics and advertising pixels entirely in the app runtime.

    Enforced by
    ios/App/App/PrivacyInfo.xcprivacy and lib/analytics/paid-media.ts
    Checked by
    test/ios-privacy-manifest.test.js and test/native-privacy-analytics.test.js
  • Error reporting is redacted deny-by-default before it leaves the device, with default personal-data collection off and session replay disabled.

    Enforced by
    lib/observability/sentry-scrubber.ts
    Checked by
    test/sentry-scrubber.test.js

04

What this page does not claim

  • No online service can guarantee perfect security. This page describes controls, not certainty.

  • There is no bug bounty, no paid disclosure programme, and no committed response-time guarantee. Reports are still read and still acted on.

  • There is no third-party security certification and no published penetration-test report to attach.

  • Encryption in transit and at rest, host hardening, and backup handling belong to the hosting providers rather than to code in this product.

05

Reviewing rather than reporting?

If you are assessing the product for a school, library, clinic, or district rather than reporting a specific problem, start with the review record instead. It covers the account model, child-data handling, provider metadata, content safety, export, and deletion.

06

Send the security report

The report opens with security context already attached, so you only have to describe what you saw.

Patrick runs human support through support@readyalready.org. A security report reaches the same mailbox and is read by a person, not filed by a rule.