Explorar o código

Merge pull request #16261 from overleaf/rd-rate-limiter

[web] Add rate limits for subscription requests

GitOrigin-RevId: 3cfdb80713c96d32f7d297f38ec306e2bf6ec9a6
Rebeka Dekany %!s(int64=2) %!d(string=hai) anos
pai
achega
8dd5b2574e

+ 28 - 1
services/web/app/src/Features/Subscription/SubscriptionRouter.js

@@ -12,17 +12,27 @@ const teamInviteRateLimiter = new RateLimiter('team-invite', {
   duration: 60,
 })
 
+const subscriptionRateLimiter = new RateLimiter('subscription', {
+  points: 30,
+  duration: 60,
+})
+
 module.exports = {
   apply(webRouter, privateApiRouter, publicApiRouter) {
     if (!Settings.enableSubscriptions) {
       return
     }
 
-    webRouter.get('/user/subscription/plans', SubscriptionController.plansPage)
+    webRouter.get(
+      '/user/subscription/plans',
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
+      SubscriptionController.plansPage
+    )
 
     webRouter.get(
       '/user/subscription',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       PermissionsController.useCapabilities(),
       SubscriptionController.userSubscriptionPage
     )
@@ -30,30 +40,35 @@ module.exports = {
     webRouter.get(
       '/user/subscription/choose-your-plan',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       SubscriptionController.interstitialPaymentPage
     )
 
     webRouter.get(
       '/user/subscription/thank-you',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       SubscriptionController.successfulSubscription
     )
 
     webRouter.get(
       '/user/subscription/canceled',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       SubscriptionController.canceledSubscription
     )
 
     webRouter.get(
       '/user/subscription/recurly/:pageType',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       SubscriptionController.redirectToHostedPage
     )
 
     webRouter.delete(
       '/subscription/group/user',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       PermissionsController.requirePermission('leave-group-subscription'),
       SubscriptionGroupController.removeSelfFromGroup
     )
@@ -61,12 +76,14 @@ module.exports = {
     // Team invites
     webRouter.get(
       '/subscription/invites/:token/',
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       PermissionsController.useCapabilities(),
       TeamInvitesController.viewInvite
     )
     webRouter.get(
       '/subscription/invites/',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       PermissionsController.useCapabilities(),
       TeamInvitesController.viewInvites
     )
@@ -81,6 +98,7 @@ module.exports = {
     // recurly callback
     publicApiRouter.post(
       '/user/subscription/callback',
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       AuthenticationController.requireBasicAuth({
         [Settings.apis.recurly.webhookUser]: Settings.apis.recurly.webhookPass,
       }),
@@ -92,21 +110,25 @@ module.exports = {
     webRouter.post(
       '/user/subscription/update',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       SubscriptionController.updateSubscription
     )
     webRouter.post(
       '/user/subscription/cancel-pending',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       SubscriptionController.cancelPendingSubscriptionChange
     )
     webRouter.post(
       '/user/subscription/cancel',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       SubscriptionController.cancelSubscription
     )
     webRouter.post(
       '/user/subscription/reactivate',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       PermissionsController.useCapabilities(),
       SubscriptionController.reactivateSubscription
     )
@@ -114,29 +136,34 @@ module.exports = {
     webRouter.post(
       '/user/subscription/v1/cancel',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       SubscriptionController.cancelV1Subscription
     )
 
     webRouter.put(
       '/user/subscription/extend',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       SubscriptionController.extendTrial
     )
 
     webRouter.get(
       '/user/subscription/upgrade-annual',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       SubscriptionController.renderUpgradeToAnnualPlanPage
     )
     webRouter.post(
       '/user/subscription/upgrade-annual',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       SubscriptionController.processUpgradeToAnnualPlan
     )
 
     webRouter.post(
       '/user/subscription/account/email',
       AuthenticationController.requireLogin(),
+      RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       SubscriptionController.updateAccountEmailAddress
     )
   },