Privacy Policy
Last updated: October 30, 2026
Ember and Saru LLC ("we") operates SniffPup. This policy explains what we collect and why.
What we collect
- Email address: to deliver your report, sign you in, send alerts and, with your consent, product tips.
- Submitted URLs and scan results: findings are stored with secrets masked; we never store full secret values. For deep checks we store only whether a table, bucket, Firestore collection or Realtime Database path is readable and how many rows, documents or entries came back (Firestore and Realtime Database counts stop at 50+), never their contents.
- Username and password (optional): if you create an account with a password, we store your username and a one-way argon2id hash of your password, never the password itself. To stop known-leaked passwords, we check new passwords against the Have I Been Pwned database using a privacy-preserving range lookup: only the first 5 characters of a SHA-1 hash leave our servers, never your password. We record failed sign-in attempts (as a hash of the username or email entered) for up to 15 minutes to block password guessing.
- Technical data: IP address (for rate limiting and abuse prevention), and basic server logs.
- Scan audit log: to prevent misuse, each scan request records the account (if signed in), a keyed hash of the IP address and of a random device ID, the site and URL scanned, the time, the result (scanned, blocked or limited) and the version of the scan terms you agreed to. Raw IP addresses and device IDs are not stored in this log.
- Uptime monitoring: if you turn it on for a saved app, we send one light request to that app's address on a schedule and store each check's time, result, status code and response time. If you turned it on by confirming ownership, we store that confirmation's wording version, time and IP address.
- For speed and accessibility basics we use the page, headers and JavaScript files the scan already loads, plus a light HEAD request for up to 10 images on the same site. Nothing is sent to other companies.
- To show when your domain expires, we look up the domain name (only the name, never the page address or anything about you) in its public registry's RDAP service, for example Verisign for .com. Registries see that lookup the same way they see any public WHOIS or RDAP request.
- Billing data: processed by Stripe; we store your Stripe customer and subscription IDs, not card numbers.
- Supabase Security Advisor results (Pro combined report): on the website, results you paste are read in your browser and never sent to us. In our app, they're sent to our server only to build that report and are not stored or logged.
- Code you paste into the Payments Doctor: it's sent to our server only to check it for that one response, held in memory, and not stored, logged or used for training; secrets in the results are masked. We never send it to Stripe. To rate-limit the free check we count requests per hashed IP address.
- Public GitHub repos you ask the repo scan to check: we download the repo's current files from GitHub, check them in memory for that one response, then drop them; nothing is stored, logged or used for training. Secret values in the results are masked and .env values are never shown. The full check sends only the direct npm package names and versions to OSV.dev, an open vulnerability database, to look up advisories. Licences come from the repo's own lockfile. If the lockfile doesn't list them, the full check looks up the package names and versions (nothing else) in the public npm registry (registry.npmjs.org). To rate-limit the free check we count requests per hashed IP address.
- Package files you paste or that the repo scan reads (package.json, requirements.txt, pyproject.toml, Pipfile): we check them in memory for that one response and never store, log or use them for training. To check that each package exists and isn't known malware, we send only the package names (and exact versions, where the file pins them) to the public npm registry (registry.npmjs.org and api.npmjs.org), PyPI (pypi.org) and OSV.dev. Well-known packages are checked against lists we keep on our server, so their names aren't looked up on the registries. To rate-limit the free check we count requests per hashed IP address.
- Database migrations you paste into the migration safety check: we read the SQL as text, in memory, for that one response, and never store, log or use it for training. It is never run against any database and isn't sent to anyone else. To rate-limit the check we count requests per hashed IP address, or per account if you're signed in on Solo and up.
- Private GitHub repos you connect: you install the SniffPup GitHub App on only the repositories you choose. It has read-only access to their code and basic details (name, default branch). With pull request checks, it can also post a check result on your pull requests. When you ask for a scan, we download that repo's current files with a short-lived token, check them in memory for that one scan, then drop them. We never store your code, never log it and never use it to train AI. We keep your GitHub account name, the installation ID and the names of the repos you chose, so we can list them for you. Remove the app on GitHub or tap Disconnect and we delete those records and stop at once. If you turn on push checks for a repo, we check each push to its default branch the same way, in memory, and keep only a short summary of each check (the commit ID, the time, how many issues of each severity, the names of new issues, and scrambled IDs so we can tell what's new). We never keep your code, file names or commit messages. Turn push or pull request checks off or disconnect GitHub and we delete those summaries. If you turn on pull request checks, we check the files each pull request changes the same way, in memory, post the result as a check on that pull request, and keep the same short summary as push checks. We never keep your code, file names, or pull request titles or text. If you install the separate SniffPup Fix app on a repo and ask for a fix, we read that repo's current files the same way, in memory, write the change to a new branch and open a pull request for you to review. It never changes your default branch and never merges. We keep only the pull request number and which kind of fix it was, never your code or file names.
- Supabase projects you connect: SniffPup reads your project's settings to run security checks. It doesn't change anything in your project. Details in Connected Supabase projects below.
- Crash Catcher visitor reports (optional). If a site owner adds our Crash Catcher script to their site, it sends us a short report only when a page breaks for a visitor: the error message, the page path (without the query string), the file and line, and the browser name and version (for example "Safari 18 on iPhone"). It sets no cookies, stores nothing in the visitor's browser, and doesn't send IP addresses, form input, or anything that identifies the visitor. We use an IP address only for a few seconds to limit abuse and never store it. Reports are grouped, kept for 30 days, and deleted right away if the site owner turns the feature off. The site owner is responsible for mentioning it in their own privacy notice if their law requires.
- Scans without an account: scans you run while signed out are saved too, so the report link works; they follow the same 12-month retention as other scan results.
- How you found us: with each scan from the website we store the site that first linked you to SniffPup (address and path only, no query string) and any campaign tags in that link (utm_source, utm_medium, utm_campaign, utm_content), which we keep with the scan and with any purchase, including in our payment processor's checkout record. Until you scan, your browser keeps these in local storage for up to 30 days. We also keep a random device ID in local storage for per-device scan limits; it isn't tied to who you are.
- Visit statistics: we use Vercel Web Analytics to count visits in aggregate: the page viewed, the referring site, country, browser, operating system and device type. It sets no cookies and stores nothing on your device. Visitors aren't identified; a visit is grouped only by a hash of the request that Vercel discards after 24 hours, so it can't follow you across days or other sites. Before anything is sent we strip report links, checkout references and other query parameters from the address. We use these numbers only to see which pages are useful, never for advertising.
- Push notifications: if you allow notifications in a SniffPup mobile app, we store that device's push token, whether it's iOS or Android, the app version and when the app last checked in, so we can send the phone alerts you turn on. You choose which alerts you get in Account › Alerts: a new serious issue on a site you verified, a score drop, your app going down and coming back, an HTTPS certificate or domain about to expire, new page breakers found by Crash Catcher, and an exposed AI key (AI bill shield). We also store those choices and your quiet hours (the hours and your time zone) with your account. Apple Push Notification service (iOS) or Firebase Cloud Messaging by Google (Android) delivers each alert. An alert contains your site's address and a short summary, such as "is down" or the name and severity of a new issue (for example "critical: Your .env file can be downloaded by anyone"), plus a link that opens that issue in My scans. It never contains your keys, passwords, code or the full report. We delete the token when you sign out of the app or delete your account, when Apple or Google tells us it no longer works, or after 270 days without the app checking in. We delete your alert choices when you delete your account.
Aggregate statistics
We may combine scan results across many sites to publish aggregate statistics, such as the share of scanned apps missing a security header. Published figures never name or link to a site, never include a finding from an individual site, and are only published when they are based on at least 50 different sites. We only use scans run on or after October 19, 2026, when this section was added. Site owners who opted out of scanning are excluded.
Cookies
We set sp_session only when you sign in, to keep you signed in. Alongside it, sp_signed_in holds no personal data and only lets the top bar show “My scans” instead of “Sign in” (30 days), and sp_claim holds the ID of a scan you asked to save to your account while you finish signing in (30 minutes). These are strictly necessary, so we don't ask for consent. We use no advertising or tracking cookies. Your browser's local storage keeps your light/dark theme choice, a random device ID (sp_device, used only for per-device scan limits and never linked to advertising) and, after a scan, a copy of that report so the paid report can open it; neither is sent to analytics. Stripe sets its own cookies on its checkout pages to process payments and prevent fraud.
Service providers
Vercel (hosting and visit statistics), Neon (database), Stripe (payments), Resend (email delivery), ActiveCampaign (email list and marketing), and Supabase (only if you connect a Supabase project). Each processes data on our behalf.
Suggestion box
If you send a suggestion through our suggestion box, we store the text, the page you sent it from, the time, and your email if you choose to add one. We use them only to read and act on your idea and, if you gave an email, to reply about it. Adding an email doesn't sign you up for marketing. Please don't include personal or secret information in the text. You can ask us to delete a suggestion at support@sniffpup.com.
Marketing email
When you give us your email with a scan (optional), use “Email me my results” on a results page, or create an account, we use your email to deliver your report, sign-in links and account alerts. “Email me my results” sends one email with that scan's score, a short summary of the findings and a link to the report; it does not create an account, and we store the email with that scan so the report and any receipt reach you. We only send marketing email (security tips and product updates) if you tick the separate, unticked-by-default “Also send me occasional security tips and product updates” box, or sign up for the daily tip with one of our sign-up boxes; we record that choice and when you made it. Leaving the box unticked means you only get the email you asked for. Every marketing email includes an unsubscribe link, and you can unsubscribe anytime.
If you start a checkout and tick Stripe's “Keep me updated with news and personalized offers” box but don't finish paying, we may send you one reminder email with a link back to that checkout (it works for up to 30 days). We send at most one such reminder per week, none after you buy, and every reminder has a link to stop them.
Retention
Scan results: 12 months. Accounts: until you delete them. Auto-renewal consent records: at least 3 years. Rate-limit records: short-lived. Uptime checks: 7 days. Uptime daily totals and outage records: 90 days. Scan audit log: 12 months, then deleted automatically, unless we must keep a record longer to investigate abuse or respond to legal process. Abuse flags and suspensions: as long as needed to review them and enforce our Acceptable Use Policy. Connected Supabase projects and their latest results: until you disconnect, or after 90 days unused. Crash Catcher visitor reports: 30 days, or until the site owner turns the feature off.
Scans you run while signed in, or choose to save with “Save to My scans”, are kept with your account and listed in My scans on the website and, later, in the SniffPup iOS app. They follow the same 12-month retention as other scan results.
Auto-renewal consent records
When you agree to automatic renewal before checkout, we store the exact wording you agreed to, its version, the time, your IP address and browser user agent, and the checkout reference. We keep these records for at least 3 years, as consumer-protection law requires proof of consent.
Children
SniffPup is not directed to children under 13 (or under 16 in the EEA and UK), and we don't knowingly collect their data. If you believe we have, email support@sniffpup.com and we'll delete it.
Security incidents
If a breach affects your personal information, we'll notify you and the authorities as required by law, including North Carolina's Identity Theft Protection Act (N.C. Gen. Stat. § 75-65).
Our apps (iPhone, iPad and Mac)
The SniffPup apps for iPhone, iPad (including foldable iPhones) and Mac use the same account and collects the same data described here. In-app purchases are processed by Apple; we receive transaction details, not your payment card. You can delete your account from inside the app or from My scans on the website.
Android and Google Play
The SniffPup app for Android, from Google Play, uses the same account and collects the same data described here: your email address and account ID (and username, if you set one) when you sign in, which is optional, as scanning works without an account; the site addresses you scan and their results, with secrets masked; basic server logs, including your IP address and the app version; the scan audit log described above; and, only if you allow notifications, that device's push token. If you connect GitHub for repo scans, your repo data is handled as described above: checked in memory and not stored.
Everything the app sends to us goes over HTTPS, so it's encrypted in transit. We don't sell this data or share it with third parties, and the app shows no ads. The service providers listed above process it only on our behalf. Phone alerts on Android are delivered by Firebase Cloud Messaging by Google, as described under Push notifications above; the app uses Firebase only to deliver those alerts, not for analytics. The app asks before sending notifications, and you can turn them off anytime in your device's settings.
Nothing can be bought in the Android app. If you bought a plan on the website, the app shows it, and billing stays with Stripe as described above. To delete your account, open the Account tab, tap Delete account and type DELETE to confirm, or use your account page on the website. We delete your data as described in Deleting your account below.
Connected Supabase projects
If you connect a Supabase project, on our website or in the SniffPup iPhone, iPad, Mac or Android app, SniffPup reads your project's settings to run these checks. It doesn't change anything in your project. It works the same everywhere: the apps open Supabase's own page to connect, but all reading is done by SniffPup's servers. The apps never receive or store your Supabase access.
How connecting works. You approve access on Supabase's own page. SniffPup asks only for read permission to your projects' database settings, sign-in (auth) settings, storage settings and project details. We don't ask for permission to change anything, or for your API keys.
What we read: Supabase's Security Advisor results; which tables have row level security turned on and the rules in your access policies (names and policy expressions, not your data); which database functions run with elevated rights and which extensions are installed; sign-in settings such as email confirmation, leaked-password protection, one-time-code expiry and minimum password length; storage bucket names and whether each is public (not the files in them); your Postgres version, network restrictions and SSL setting; whether backups and point-in-time recovery are on and when the last backup finished (never the backup itself); and your project names, references and regions so you can pick one.
What we don't read, said plainly. Your table data: we never read the rows in your tables. To read settings, Supabase gives us a read-only database role that could technically read rows, so this promise comes from our software, not from Supabase's permissions: SniffPup only runs a short, fixed list of queries against Postgres's own system catalog. Secrets: Supabase's sign-in settings include some secrets, such as sign-in provider keys and your email (SMTP) password. We can't ask Supabase to leave them out, so we discard everything except the few settings we check as soon as the response arrives, and never store, log or show them.
What we store: your Supabase access as encrypted tokens (AES-256-GCM), the list of your project names and references, when you last used the connection, and the latest check result for each project you check (findings, the names of flagged tables, functions and buckets, and fixes; never table data). This is the same on free accounts: the check is free with a SniffPup account, and on a free account we keep the latest result to know that project's free check is used and so a paid plan can show it, even though a free account sees only the critical fixes. We don't share any of this, and we don't use it for advertising or AI training.
How long we keep it. Until you disconnect, delete your SniffPup account, or leave the connection unused for 90 days, whichever comes first. Supabase's short-lived access is renewed only when you run a check. When a connection ends, we ask Supabase to cancel our access and delete our stored tokens and results straight away. You can also remove SniffPup in Supabase under Organization settings › OAuth Apps.
Disconnecting. Any time on the website or in the app: Sniff & Fix › Supabase project check, or Account › Connections.
Mobile app scan
Your app file stays on your device. When you use the Mobile app scan on sniffpup.com, the APK, AAB, IPA or Expo export you pick is opened and read by your own web browser. The file is never uploaded to SniffPup or anyone else, and we don't store it.
What your browser sends us. To check the app is yours, your browser sends only:
- any SniffPup app token it finds in the build (a code we gave you to put in your app's config), and
- the app's Android package name and/or iOS bundle ID (for example com.yourcompany.app).
We don't receive the keys or other values found in your build. Results are worked out and shown in your browser, with key values shortened (for example "sk_liv…abcd").
Checking ownership. If no token is found, we look for your package name or bundle ID in the public /.well-known/assetlinks.json and apple-app-site-association files on websites you have already verified with SniffPup. We don't contact any other site.
What we keep. Nothing from the scan itself. Your app token is calculated from your account and isn't stored separately. Like any request to sniffpup.com, the ownership check may appear in our hosting provider's standard request logs (IP address and time), as described elsewhere in this policy.
App stores. We never download apps from Google Play, the App Store or any other store. The scan only reads builds you export yourself.
Follow-up checks. If your build points to a Supabase or Firebase project, we show the project name to you and suggest our existing checks. Those checks run only when you start them, and only under their own rules (the Supabase project check and site scan sections of this policy).
Firebase rules check
Pasting rules. You can paste your Firestore, Storage or Realtime Database rules. Your browser sends the text you paste to SniffPup, where it's checked as text and the result is sent back to you. We don't store the rules text or the result.
Connecting with Google. If you're signed in, you can instead connect your Firebase project with Google. We ask Google only for read-only access (the firebase.readonly scope) and use it to list your Firebase projects and read the live security rules for Cloud Firestore and Cloud Storage. We don't read the data in your database or files, and we can't change anything: our server only sends read requests to those rules and project-list addresses. Google gives us a short-lived access token (about one hour) and no refresh token. We keep it only in an encrypted (AES-256-GCM), httpOnly cookie in your browser, not on our servers, and we don't store your project list, rules or results. Disconnect asks Google to revoke the token and deletes the cookie right away. You can also remove SniffPup's access anytime in your Google Account under Security › Third-party apps with account access. SniffPup's use and transfer of information received from Google APIs adheres to the Google API Services User Data Policy, including the Limited Use requirements.
ZIP code scan
For the ZIP code scan, your ZIP is opened and checked inside your own browser. The ZIP and its contents are never uploaded to SniffPup or anyone else. We only see that the page was loaded and whether you're signed in, so we can show the right view. Secret values in results are masked, and .env values are never shown.
Fix Squad (done-for-you fixes)
When you order a fix we keep the order details: the site, the finding, the price, your contact email, how you want us to work and any notes you add, plus Stripe's payment record. If you join the waitlist we keep your email to tell you when a slot opens. If you invite us to a project, we use that access only for your job and remove it afterward; we don't copy your data out of the project and never keep passwords or keys (we never ask for them). We keep order records for at least the 30-day refund window and as needed for tax and accounting. Payments go through Stripe and the scope email through our email provider. Ask us anytime to delete waitlist or job notes we no longer need.
Sharing for legal reasons and abuse
We don't sell your data. We may preserve and disclose information (such as scan targets, timestamps, IP addresses, account and payment details) to law enforcement, to the owner of a site scanned without authorization, or to others when we reasonably believe it's needed to respond to valid legal process, investigate or stop unauthorized or unlawful use of SniffPup, or protect the rights, property or safety of SniffPup, our users or others.
Deleting your account
Delete your account anytime from My scans (website) or Settings in the app. We delete your saved scans, sites, sign-in links, sessions and push tokens, remove you from our email list, cancel any web subscription so it won't renew, and replace your email on the account record with a placeholder. We keep only what the law or legitimate abuse prevention requires: auto-renewal consent records (at least 3 years), payment records held by Stripe, and the scan audit log until its 12-month expiry. Subscriptions bought in the iOS app are managed by Apple; cancel them in Settings › Apple ID › Subscriptions. Deleting your account also ends any connected Supabase project: we ask Supabase to cancel our access, then delete our stored tokens and results.
Your rights
You can request access, correction or deletion of your data by emailing support@sniffpup.com. We do not sell or share your personal information for advertising. Wherever you live, you can ask us to access, correct, export or delete your data, and we will respond within 30 days.
Contact
support@sniffpup.com, Ember and Saru LLC, 10850 Providence Rd #1370, Charlotte, NC 28277, USA