Webcounter.caCanadian web analytics

Trust & security

How Webcounter.ca protects its data

This page explains the service's security controls and how to report a vulnerability. Contact details are also published at /.well-known/security.txt under RFC 9116.

Report a vulnerability

security@webcounter.ca

Email security@webcounter.ca if you find a security issue in the dashboard, tracking script, or API. Include the page or endpoint, steps to reproduce, and the result you expected. Encryption is optional.

Please report privately and allow time for investigation before public disclosure. We aim to acknowledge reports within a few business days and provide updates while we work on them.

Safe harbour

Good-faith security research is authorised

We will not pursue legal action for research that follows this policy. We will work with you to understand and resolve a reported issue.

  • Use accounts and sites you created for testing or have explicit permission to test. Do not access another customer's data.
  • Stop and report as soon as you have enough evidence to demonstrate the issue; do not continue extracting data once impact is established.
  • Do not run automated scanners, load tests, or other activity that may degrade the service. Normal rate limits also apply to research traffic.
  • Do not attempt physical access, social engineering, or phishing against Counter's operators or customers.
  • Give us a chance to fix the issue before discussing it publicly.

Webcounter.ca has no paid bounty program. We can credit you after a fix ships if you would like public recognition.

Scope

What this policy covers

In scope: webcounter.ca and its dashboard, account, and API surfaces; the /c.js collection snippet and the /api/collect//c.gif//badge.svg endpoints it calls; the public share-report and network-directory pages.

Out of scope: denial-of-service testing and services Counter does not operate, including transactional email and OpenStreetMap tile hosts.

Account security

Passwords, sessions, and multi-factor authentication

Passwords are hashed with bcrypt before storage; the plain password is never written anywhere. Login checks run a fixed comparison whether or not the email exists, so response timing cannot be used to enumerate accounts. Sign-in attempts are rate-limited per address.

Every account can enable optional multi-factor authentication with a 30-second authenticator code and one-time recovery codes. MFA secrets are encrypted, and recovery codes are stored as one-way hashes. Changing a password revokes other sessions and outstanding password-reset links.

Email links for verification, password reset, and address changes open a confirmation screen. The action occurs only after submission, so an automated mail scanner cannot trigger it by following the link.

API keys

Shown once and stored as a hash

API and secret keys are shown once when created. Counter stores only a SHA-256 hash, so a working key cannot be recovered later. Revoke and replace a lost key.

Data protection

Data protection

Visitor identifiers use a rotating keyed hash, and raw visitor IP addresses are not stored in analytics events. Web Push subscription endpoints are encrypted at rest. Nightly database backups are encrypted with a public key, and automated restore checks verify each backup.

See the data retention page for exactly how long each kind of data is kept, and the Privacy Notice for the full policy.

Transport & isolation

HTTPS, security headers, and tenant isolation

The dashboard, account, and API use HTTPS, HSTS, Content Security Policy, and framing, referrer, and permissions headers. Collection endpoints (/c.js, /api/collect, /c.gif, /badge.svg) allow cross-origin requests because customer sites must load them. They return the same empty response whether a request is accepted or rejected and expose no sensitive data.

The dashboard and API use one shared authorization path for site access. A user or key scoped to one site cannot reach another account by guessing an identifier. Production and staging also use separate database credentials, and staging is denied access to production data.