mirror of
https://github.com/binwiederhier/ntfy.git
synced 2026-05-09 08:26:00 +02:00
[GH-ISSUE #1726] Authenticated free-tier users should be rate-limited by user ID, not IP address #1198
Labels
No labels
ai-generated
android-app
android-app
android-app
🪲 bug
build
build
dependencies
docs
enhancement
enhancement
🔥 HOT
in-progress 🏃
ios
prio:low
prio:low
pull-request
question
🔒 security
server
server
unified-push
web-app
website
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/ntfy#1198
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @tflpd on GitHub (May 6, 2026).
Original GitHub issue: https://github.com/binwiederhier/ntfy/issues/1726
🐞 Describe the bug
Authenticated free-tier users are rate-limited by IP address rather than by their user identity. This causes a noisy neighbor problem where unrelated users sharing the same IP address share a single rate-limit bucket.
I run a Cloudflare Worker that sends ~1 notification/day to ntfy.sh. Despite my minimal usage, I consistently hit the
This happens because:
The root cause is the
visitorID()function in server/visitor.go, which only uses user-based tracking whenu.Tier != nil.An authenticated free-tier user gets visitor ID "ip:1.2.3.4" instead of "user:u_abc123", even though the server has positively identified who they are.
Proposed fix: Change the condition to
u != nilso all authenticated users are tracked by user ID. This gives free users the same limits they have today, just tracked against their own identity rather than a shared IP. No additional resources are granted — only fair accounting.Additionally, stats persistence in server.go:980 should be extended to free authenticated users so counters survive server restarts (currently
EnqueueUserStatsis only called whenu.Tier != nil).This same problem affects any serverless platform (AWS Lambda, Vercel, Fly.io), corporate NAT, VPNs, or university networks.
💻 Components impacted
ntfy server
🔮 Additional context
Abuse considerations: Account creation is already rate-limited to 3 per IP per day (
DefaultVisitorAccountCreationLimitBurst= 3), andntfy.shrequires email verification. An attacker could at most triple their limits from a single IP, which is less impactful than the current situation where a single noisy neighbor can block thousands of legitimate users sharing an IP on platforms like Cloudflare Workers.Related issues:
The subscriber-billed topics work in #633 already established the precedent that identity-based rate limiting is preferable to IP-based rate limiting. This proposal extends that principle to all authenticated users.
@tflpd commented on GitHub (May 6, 2026):
Happy to put up the PR and tests if y'all agree with the approach! 😊
@binwiederhier commented on GitHub (May 6, 2026):
This is not a bug. It's by design. Otherwise people could trivially circumvent the rate limiting.
@tflpd commented on GitHub (May 6, 2026):
I understand the concern, but I'd argue IP-based tracking doesn't actually prevent abuse -- it just shifts the vector from "create accounts" to "rotate IPs" which requires no account, no email, and no identity at all.
Account creation is already limited to 3/IP/day and requires email verification, so the multiplication factor is capped and traceable.
Meanwhile, the current design causes real collateral damage for legitimate authenticated users on shared infrastructure (serverless platforms, corporate NAT, etc). User-based tracking would actually be harder to abuse because accounts are identifiable and bannable, unlike anonymous IP rotation.
@binwiederhier commented on GitHub (May 6, 2026):
I understand that you have a different perspective. You are free to fork the project and implement your own changes.
This has worked and is how I would like to do rate limiting for ntfy. Thanks for using ntfy.
@tflpd commented on GitHub (May 6, 2026):
Very fair, I respect that, thank you for the quick response!
Just out of curiosity, do you disagree on whether this is an issue for serverless platforms, or do you agree it's an issue but believe the current rate limiting approach is better for the overall user base?
I raised this thinking it fell in the same bucket as #144, so I was curious about the distinction.