fix: stop throttling the realtime subscribe proxy
Centrifugo calls the proxy from 127.0.0.1 for every client, so the per-IP fallback put every subscribe into one bucket that any token holder could exhaust. Throttle only the token route, per user.
This commit is contained in:
18
routes.go
18
routes.go
@@ -30,8 +30,9 @@ const (
|
||||
// bucketManage throttles the management API per token, or per client IP
|
||||
// for a request without one.
|
||||
bucketManage = "throttle:jz.bm.manage"
|
||||
// bucketRealtime throttles the realtime token and subscribe-proxy
|
||||
// routes per user, or per client IP for a request without one.
|
||||
// bucketRealtime throttles the realtime token route per user (it runs
|
||||
// after jwt.auth), or per client IP for a request without one. The
|
||||
// subscribe proxy is not throttled: see mountRealtime.
|
||||
bucketRealtime = "throttle:jz.bm.realtime"
|
||||
)
|
||||
|
||||
@@ -154,16 +155,21 @@ func (p *Plugin) Routes(r pact.Router) error {
|
||||
// of golem15.presentations is the only realtime consumer, so nothing is
|
||||
// mounted without it, and the token route is limited to presentation owners
|
||||
// by its presentations.realtime-owner guard, named here without importing
|
||||
// the plugin. Routes built without Boot (bare tests) mount nothing; the
|
||||
// default null driver declares no routes.
|
||||
// the plugin. Only the token route is throttled, per user. The subscribe
|
||||
// proxy is called by Centrifugo from 127.0.0.1 for every client, so any
|
||||
// throttle there would be one shared bucket that a single token holder
|
||||
// could exhaust and lock the owner out; it relies on its constant-time
|
||||
// secret check and Centrifugo's own limits instead. Routes built without
|
||||
// Boot (bare tests) mount nothing; the default null driver declares no
|
||||
// routes.
|
||||
func (p *Plugin) mountRealtime(r pact.Router) error {
|
||||
if p.realtime == nil || p.app == nil || !p.app.HasPlugin("golem15.presentations") {
|
||||
return nil
|
||||
}
|
||||
return lighthouse.Mount(r, p.realtime.Driver(), lighthouse.Surfaces{
|
||||
UserAuth: surf.Use("jwt.auth", "presentations.realtime-owner"),
|
||||
UserAuth: surf.Use("jwt.auth", "presentations.realtime-owner", bucketRealtime),
|
||||
ServerToServer: surf.Use(),
|
||||
Middleware: surf.Use(bucketRealtime),
|
||||
Middleware: surf.Use(),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user