Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Four analytics endpoints bypass the dashboard password

Open Beginner friendly
#272 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
backend, security

Research direction

Read the four loaders in packages/server/app/routes/resources.country.tsx, resources.browser.tsx, resources.device.tsx, and resources.referrer.tsx, then compare them with the guarded sibling loaders named in the issue. Check how requireAuth is called there and how the loaders handle its result; done means unauthenticated requests are denied when dashboard authentication is enabled, while the existing analytics responses still work for authorized requests.

Written by the indexing model from the issue text.

Description

Affected version: confirmed on commit de70cac29ad2207c130df45ebecdabb3f65985c7 (2026-10-04), latest tagged release v3.4.1.

Summary

Counterscale's operator-configured dashboard password (CF_AUTH_ENABLED/CF_PASSWORD_HASH/CF_JWT_SECRET) is meant to gate access to all analytics data. packages/server/app/routes/resources.stats.tsx, resources.paths.tsx, resources.timeseries.tsx, and dashboard.tsx all call requireAuth(request, context.cloudflare.env) before returning data. resources.country.tsx, resources.browser.tsx, resources.device.tsx, and resources.referrer.tsx do not call it at all, so they return analytics data to any request, with or without the password, whenever a deployment has auth enabled.

Details

Each of the four unguarded loaders reads site from the query string and passes it straight into the corresponding Analytics Engine query function (getCountByCountry, getCountByBrowser, getCountByDeviceType, getCountByReferrer) with no authentication check anywhere in the function body. The sibling loaders in the same directory share the exact same loader signature and do call requireAuth(), so this reads as a per-file oversight rather than an intentional exemption.

CWE-862 (Missing Authorization). CVSS 3.1 vector AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N = 7.5 (High).

Steps To Reproduce

(available upon request)

Impact

On any deployment where the operator enabled password protection specifically to keep visitor analytics private, an unauthenticated visitor can still pull per-site country, browser, device-type, and referrer breakdowns straight from these four endpoints, bypassing the password for that subset of data.

Dominant language
TypeScript
Stars
2.2k
Forks
136
PR merge metrics
No merged PRs in 30d

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from benvinegar/counterscale

All issues in benvinegar/counterscale

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.